test2 等于 0x55,test 等于 test2与0x0F,结果等于 0x55 ?
本帖最后由 panxiaoyi 于 2023-9-5 09:08 编辑辉芒微单片机,代码如图,真不知道,是我的问题,还是编译器或者是单片机的流程就是这样的
main()
{
MCUSYS_Init();
GPIO_Init();
GPIO_INT_Init();
TIME1_Init();
UART_Init();
// GIE=1; //全局中断使能
PEIE=1; //外设中断使能
while(1)
{
test=0;
test2=0x55;
test=test2&0x0F;
main_step=test; //然后再把中间变量赋值给用户变量,否则可能会被中断干扰
}
}
运行结果如图
是不是编译器认为变量值没有实际意义,优化了,建议变量加volatile试试 按照常规的理解,test 是不允许等于 0x55 的,这是因为我在中断里面需要判断这个 test 的值,然后才发现它的值有时候会等于 0x55。
也就是说 test=test2&0x0F; 这个语句
单片机运行的第一个步骤 test=test2;第二个步骤 test 才等于 0x05;
请问为什么会这样?为什么这个计算没有使用中间缓存来存储中间结果?这个真的好坑人。 你第一步,只是运行到那里,那一条语句实际还没运行,你应该运行到下一句再看才对,多想想自己的问题,不要认为人家做了几十年编译器会有低级的问题 ayb_ice 发表于 2023-9-5 09:05
是不是编译器认为变量值没有实际意义,优化了,建议变量加volatile试试
多谢解答
当时,我的语句是 main_step = test2 & 0x0F;其中,test2 是串口接收到的数据(按道理不该被优化啊)
然后在中断里面发现 main_step 的数据有错误,然后才加多一个步骤的
实际的代码中不是这样的,只是便于大家的理解,我就用最简单的代码来测试
在真正的代码中,main_step 和 test2 都是有硬件用到的。test 是临时测试用的
编译器是默认优化级别 我加上 volatile 试试先 试过volatile了,暂时没有效果
你这个代码,InterruptData[]好像这个数组,中断要改的吧。果断volatile。
如果中断还改了别的东西,统统volatile。 当然你要走到下一步才显示结果啊。 仿真走到main_step=test;就会有结果。 panxiaoyi 发表于 2023-9-5 09:18
多谢解答
当时,我的语句是 main_step = test2 & 0x0F;其中,test2 是串口接收到的数据(按道理不该被 ...
那几个变量都加volatile 单片机是Cortex-M的还是8位的单片机,要看汇编指令。 我一直在看汇编,但是不知道是几位的单片机,啥内核的 是辉芒微8位单片机,仿PIC的。型号是FT62F28x,访问不同的寄存器还要切换标志位的(请看第34句) 我查了汇编指令跟PIC的也不同,只能通过上下文猜测,跟ARM不同的是,ARM是会把值先放在通用寄存器中计算好再放入内存中,但是看这个猜测是直接在内存上运算。你第一张图停的地方执行的STR 38H就是把0x55放在test的内存上,所以看到的值就是0x55。这样只能通过运算赋值时关闭中断源,运算完再开启,即代码保护区,或者通过中间变量运算完再赋值给test,赋值语句是单指令。 我完全新建了一个工程,这次的芯片是辉芒微 FT62F133 ,运行也会有错,全部代码如下
#include "SYSCFG.h"
volatile unsigned char teat,teat2;
void interrupt ISR(void)
{
}
main()
{
TRISA=0x00;
PORTA=0x00;
TRISC=0x00;
PORTC=0x00;
while(1)
{
teat2++;
teat=teat2&0x03;
if(teat) PORTC^=0xFF;
}
}汇编代码如下
//Deviec:FT62F13X
//-----------------------Variable---------------------------------
_teat EQU 72H
_teat2 EQU 73H
//-----------------------Variable END---------------------------------
ORG 0000H
BCR PCLATH,3 //0000 118A
LJUMP 0BH //0001 380B
ORG 0004H
STR 7EH //0004 01FE
SWAPR STATUS,0 //0005 0703
STR 70H //0006 01F0
LDR PCLATH,0 //0007 080A
STR 71H //0008 01F1
BCR PCLATH,3 //0009 118A
LJUMP 24H //000A 3824
BCR PCLATH,3 //000B 118A
LJUMP 0DH //000C 380D
CLRR 73H //000D 0173
CLRR STATUS //000E 0103
BCR PCLATH,3 //000F 118A
LJUMP 11H //0010 3811
//;000.C: 12: TRISA=0x00;
BSR STATUS,5 //0011 1A83
CLRR 5H //0012 0105
//;000.C: 13: PORTA=0x00;
BCR STATUS,5 //0013 1283
CLRR 5H //0014 0105
//;000.C: 15: TRISC=0x00;
BSR STATUS,5 //0015 1A83
CLRR 7H //0016 0107
//;000.C: 16: PORTC=0x00;
BCR STATUS,5 //0017 1283
CLRR 7H //0018 0107
//;000.C: 19: {
//;000.C: 20: teat2++;
INCR 73H,1 //0019 09F3
//;000.C: 22: teat=teat2&0x03;
LDR 73H,0 //001A 0873
STR 72H //001B 01F2
LDWI 3H //001C 2A03
ANDWR 72H,1 //001D 02F2
//;000.C: 24: if(teat) PORTC^=0xFF;
LDR 72H,0 //001E 0872
BTSC STATUS,2 //001F 1503
LJUMP 19H //0020 3819
LDWI FFH //0021 2AFF
XORWR 7H,1 //0022 0487
LJUMP 19H //0023 3819
ORG 0024H
LDR 71H,0 //0024 0871
STR PCLATH //0025 018A
SWAPR 70H,0 //0026 0770
STR STATUS //0027 0183
SWAPR 7EH,1 //0028 07FE
SWAPR 7EH,0 //0029 077E
RETI //002A 0009
END运行结果如图
加了括号,如下,结果还是不行
teat=(teat2&0x03); panxiaoyi 发表于 2023-9-5 14:19
我完全新建了一个工程,这次的芯片是辉芒微 FT62F133 ,运行也会有错,全部代码如下汇编代码如下
运行结果 ...
按上面的汇编运行没错啊,你运行到那里已经执行了把test2的值0x87赋值给test了。
可以尝试关总中断试试 楼主的意思是,test这个变量,经过与0x0f运算,应该不会出现高位不为0的数据。 其实很多操作,都不是一步完成的,如果中断和大循环用全局变量通讯,一定要保证变量的原子操作。正确的做法应该是在更改该变量的所有语句前,都要关中断,执行后,开中断。除非能明确保证更改的操作是原子操作。
页:
[1]
2