[国产单片机] test2 等于 0x55,test 等于 test2与0x0F,结果等于 0x55 ?

[复制链接]
2374|31
 楼主| panxiaoyi 发表于 2023-9-5 08:59 | 显示全部楼层 |阅读模式
本帖最后由 panxiaoyi 于 2023-9-5 09:08 编辑


辉芒微单片机,代码如图,真不知道,是我的问题,还是编译器或者是单片机的流程就是这样的

  1. main()
  2. {
  3.         MCUSYS_Init();
  4.         GPIO_Init();
  5.         GPIO_INT_Init();
  6.         TIME1_Init();
  7.         UART_Init();

  8. //        GIE=1;                                    //全局中断使能
  9.         PEIE=1;                                   //外设中断使能

  10.         while(1)
  11.         {     
  12.                 test=0;   

  13.                 test2=0x55;

  14.                 test=test2&0x0F;

  15.                 main_step=test;                       //然后再把中间变量赋值给用户变量,否则可能会被中断干扰
  16.         }
  17. }

运行结果如图




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评论

xch
看样子 test 既是变量也是中间变量了。如果在中断用到test,在计算前关闭中断,计算结束打开中断。 或者定义一个volatile 中间变量作为过渡,让volatile tmp = test2 &0xf;test = tmp;倒一下脚,国足水平。  发表于 2023-9-5 17:58
ayb_ice 发表于 2023-9-5 09:05 | 显示全部楼层
是不是编译器认为变量值没有实际意义,优化了,建议变量加volatile试试
 楼主| panxiaoyi 发表于 2023-9-5 09:06 | 显示全部楼层
按照常规的理解,test 是不允许等于 0x55 的,这是因为我在中断里面需要判断这个 test 的值,然后才发现它的值有时候会等于 0x55。
也就是说 test=test2&0x0F; 这个语句
单片机运行的第一个步骤 test=test2;第二个步骤 test 才等于 0x05;
请问为什么会这样?为什么这个计算没有使用中间缓存来存储中间结果?这个真的好坑人。
ysf 发表于 2023-9-5 09:15 | 显示全部楼层
你第一步,只是运行到那里,那一条语句实际还没运行,你应该运行到下一句再看才对,多想想自己的问题,不要认为人家做了几十年编译器会有低级的问题
 楼主| panxiaoyi 发表于 2023-9-5 09:18 | 显示全部楼层
ayb_ice 发表于 2023-9-5 09:05
是不是编译器认为变量值没有实际意义,优化了,建议变量加volatile试试

多谢解答
当时,我的语句是 main_step = test2 & 0x0F;  其中,test2 是串口接收到的数据(按道理不该被优化啊)
然后在中断里面发现 main_step 的数据有错误,然后才加多一个步骤的
实际的代码中不是这样的,只是便于大家的理解,我就用最简单的代码来测试
在真正的代码中,main_step 和 test2 都是有硬件用到的。test 是临时测试用的
编译器是默认优化级别
 楼主| panxiaoyi 发表于 2023-9-5 09:19 | 显示全部楼层
我加上 volatile 试试先
 楼主| panxiaoyi 发表于 2023-9-5 09:37 | 显示全部楼层
试过volatile了,暂时没有效果

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
840A 发表于 2023-9-5 10:11 | 显示全部楼层
你这个代码,InterruptData[]好像这个数组,中断要改的吧。果断volatile。
如果中断还改了别的东西,统统volatile。
dami 发表于 2023-9-5 10:13 | 显示全部楼层
当然你要走到下一步才显示结果啊。
coody 发表于 2023-9-5 10:39 | 显示全部楼层
仿真走到main_step=test;就会有结果。
ayb_ice 发表于 2023-9-5 10:42 | 显示全部楼层
panxiaoyi 发表于 2023-9-5 09:18
多谢解答
当时,我的语句是 main_step = test2 & 0x0F;  其中,test2 是串口接收到的数据(按道理不该被 ...

那几个变量都加volatile
lelouchly 发表于 2023-9-5 11:31 | 显示全部楼层
单片机是Cortex-M的还是8位的单片机,要看汇编指令。
zlf1208 发表于 2023-9-5 12:51 | 显示全部楼层
我一直在看汇编,但是不知道是几位的单片机,啥内核的
 楼主| panxiaoyi 发表于 2023-9-5 13:39 | 显示全部楼层
是辉芒微8位单片机,仿PIC的。型号是FT62F28x,访问不同的寄存器还要切换标志位的(请看第34句)
lelouchly 发表于 2023-9-5 14:03 | 显示全部楼层
我查了汇编指令跟PIC的也不同,只能通过上下文猜测,跟ARM不同的是,ARM是会把值先放在通用寄存器中计算好再放入内存中,但是看这个猜测是直接在内存上运算。你第一张图停的地方执行的STR 38H就是把0x55放在test的内存上,所以看到的值就是0x55。这样只能通过运算赋值时关闭中断源,运算完再开启,即代码保护区,或者通过中间变量运算完再赋值给test,赋值语句是单指令。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| panxiaoyi 发表于 2023-9-5 14:19 | 显示全部楼层
我完全新建了一个工程,这次的芯片是辉芒微 FT62F133 ,运行也会有错,全部代码如下

  1. #include        "SYSCFG.h"

  2. volatile unsigned char teat,teat2;

  3. void interrupt ISR(void)
  4. {
  5. }

  6. main()
  7. {
  8.         TRISA=0x00;
  9.         PORTA=0x00;
  10.        
  11.         TRISC=0x00;
  12.         PORTC=0x00;

  13.         while(1)
  14.         {
  15.                 teat2++;
  16.                
  17.                 teat=teat2&0x03;
  18.                
  19.                 if(teat) PORTC^=0xFF;
  20.         }       
  21. }
汇编代码如下
  1. //Deviec:FT62F13X
  2. //-----------------------Variable---------------------------------
  3.                 _teat                EQU                72H
  4.                 _teat2                EQU                73H
  5. //-----------------------Variable END---------------------------------

  6.                 ORG                0000H
  7.                 BCR         PCLATH,3                 //0000         118A
  8.                 LJUMP         0BH                         //0001         380B
  9.                 ORG                0004H
  10.                 STR         7EH                         //0004         01FE
  11.                 SWAPR         STATUS,0                 //0005         0703
  12.                 STR         70H                         //0006         01F0
  13.                 LDR         PCLATH,0                 //0007         080A
  14.                 STR         71H                         //0008         01F1
  15.                 BCR         PCLATH,3                 //0009         118A
  16.                 LJUMP         24H                         //000A         3824
  17.                 BCR         PCLATH,3                 //000B         118A
  18.                 LJUMP         0DH                         //000C         380D
  19.                 CLRR         73H                         //000D         0173
  20.                 CLRR         STATUS                         //000E         0103
  21.                 BCR         PCLATH,3                 //000F         118A
  22.                 LJUMP         11H                         //0010         3811

  23.                 //;000.C: 12: TRISA=0x00;
  24.                 BSR         STATUS,5                 //0011         1A83
  25.                 CLRR         5H                         //0012         0105

  26.                 //;000.C: 13: PORTA=0x00;
  27.                 BCR         STATUS,5                 //0013         1283
  28.                 CLRR         5H                         //0014         0105

  29.                 //;000.C: 15: TRISC=0x00;
  30.                 BSR         STATUS,5                 //0015         1A83
  31.                 CLRR         7H                         //0016         0107

  32.                 //;000.C: 16: PORTC=0x00;
  33.                 BCR         STATUS,5                 //0017         1283
  34.                 CLRR         7H                         //0018         0107

  35.                 //;000.C: 19: {
  36.                 //;000.C: 20: teat2++;
  37.                 INCR        73H,1                         //0019         09F3

  38.                 //;000.C: 22: teat=teat2&0x03;
  39.                 LDR         73H,0                         //001A         0873
  40.                 STR         72H                         //001B         01F2
  41.                 LDWI         3H                         //001C         2A03
  42.                 ANDWR         72H,1                         //001D         02F2

  43.                 //;000.C: 24: if(teat) PORTC^=0xFF;
  44.                 LDR         72H,0                         //001E         0872
  45.                 BTSC         STATUS,2                 //001F         1503
  46.                 LJUMP         19H                         //0020         3819
  47.                 LDWI         FFH                         //0021         2AFF
  48.                 XORWR         7H,1                         //0022         0487
  49.                 LJUMP         19H                         //0023         3819
  50.                 ORG                0024H
  51.                 LDR         71H,0                         //0024         0871
  52.                 STR         PCLATH                         //0025         018A
  53.                 SWAPR         70H,0                         //0026         0770
  54.                 STR         STATUS                         //0027         0183
  55.                 SWAPR         7EH,1                         //0028         07FE
  56.                 SWAPR         7EH,0                         //0029         077E
  57.                 RETI                                         //002A         0009
  58.                         END
运行结果如图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| panxiaoyi 发表于 2023-9-5 14:26 | 显示全部楼层
加了括号,如下,结果还是不行
teat=(teat2&0x03);
lelouchly 发表于 2023-9-5 14:33 | 显示全部楼层
panxiaoyi 发表于 2023-9-5 14:19
我完全新建了一个工程,这次的芯片是辉芒微 FT62F133 ,运行也会有错,全部代码如下汇编代码如下
运行结果 ...

按上面的汇编运行没错啊,你运行到那里已经执行了把test2的值0x87赋值给test了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
ayb_ice 发表于 2023-9-5 14:46 | 显示全部楼层
可以尝试关总中断试试
elife 发表于 2023-9-5 15:14 | 显示全部楼层
楼主的意思是,test这个变量,经过与0x0f运算,应该不会出现高位不为0的数据。 其实很多操作,都不是一步完成的,如果中断和大循环用全局变量通讯,一定要保证变量的原子操作。正确的做法应该是在更改该变量的所有语句前,都要关中断,执行后,开中断。除非能明确保证更改的操作是原子操作。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

53

主题

417

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部