社区导航

 

搜索
查看: 1604|回复: 15

[讨论] 这算不算是STM32的BUG

[复制链接]

213

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-1-12 16:47 | 显示全部楼层 |阅读模式
本帖最后由 lingking 于 2019-1-12 16:55 编辑

小弟编程水平和C语言都比较菜,如果犯了什么低级错误还望高手们直接指出。事情是这样的,小弟最近在学编程,这两天在STM32开发板上对XPT2046这个型号的电阻屏触摸检测芯片写驱动代码。读取触摸芯片的电压值的函数已经实现了,现在开始构思电阻屏的校准函数。初步的想法是在屏幕上面依次画4个点,点击一个点之后采集坐标的电压值然后清除这个点再画下一个,采集4个点的电压值之后开始计算电阻屏的参数。上面画4个点的过程我用了一个for循环和switch语句来组合实现。可是在这段代码里面就出现了匪夷所思的现象:点击完第一个点之后直接跳到了第三个点,然后是第四个点,第二个点直接被忽略了,然而从代码上看这四段代码除了参数以外都没有任何区别。 已经确定了是最后一个case导致出了问题,我新增了一个k变量,将i换成k,出来的结果就正常了,下面是能正常使用的代码和对应的结果:。以下是会出错的源码:
  1. u16 Xpos[3],Ypos[3];
  2. void TP_Calibration(void)
  3. {
  4.         u8 flag,j;
  5.         u16 i,k = 0;
  6.         
  7.         printf("void TP_Calibration(void) V2.1 \r\n");
  8.         
  9.         
  10.         for(j = 0;j < 5;j++)
  11.         {

  12.                 switch(j)
  13.                 {
  14.                         case 0:       /* 画第一个点 */
  15.                         {
  16.                                   i = 500;
  17.                             flag = 0;
  18.                             TP_DrawPoint(20,20,RED);
  19.                             while(i--)
  20.                                         {
  21.                                                 delay_ms(10);
  22.                                                 flag        = TP_Scan_Voltage(Xpos,Ypos);
  23.                                                 if(flag == 1)
  24.                                                 {
  25.                                                         i = 0;
  26.                                                         printf("读取到第1个点的电压\r\n");
  27.                                                         
  28.                                                 }
  29.                                         }
  30.                                         TP_DrawPoint(20,20,WHITE);        
  31.                         }                                       
  32.                         break;
  33.                                        
  34.                         case 1:     /* 画第二个点 */
  35.                         {
  36.                                   i = 500;
  37.                             flag = 0;
  38.                             TP_DrawPoint(20,lcddev.height - 20,RED);
  39.                             while(i--)
  40.                                         {
  41.                                                 delay_ms(10);
  42.                                                 flag        = TP_Scan_Voltage(Xpos + 1,Ypos + 1);
  43.                                                 if(flag == 1)
  44.                                                 {
  45.                                                         i = 0;
  46.                                                         printf("读取到第2个点的电压\r\n");
  47.                                                 }
  48.                                         }
  49.                                   TP_DrawPoint(20,lcddev.height - 20,WHITE);                        
  50.                         }               
  51.                         break;
  52.                         
  53.                   case 2:
  54.                         {        
  55.                                   i = 500;
  56.                             flag = 0;
  57.                             TP_DrawPoint(lcddev.width - 20,lcddev.height - 20,RED);
  58.                             while(i--)
  59.                                         {
  60.                                                 delay_ms(10);
  61.                                                 flag        = TP_Scan_Voltage(Xpos + 2,Ypos + 2);
  62.                                                 if(flag == 1)
  63.                                                 {
  64.                                                         i = 0;
  65.                                                         printf("读取到第3个点的电压\r\n");
  66.                                                 }
  67.                                         }
  68.                                         TP_DrawPoint(lcddev.width - 20,lcddev.height - 20,WHITE);
  69.                         }
  70.                                 break;
  71.                         
  72.                         case 3:
  73.                         {
  74.                                         i = 500;
  75.                             flag = 0;
  76.                             TP_DrawPoint(lcddev.width - 20,20,RED);
  77.                             while(i--)
  78.                                         {
  79.                                                 delay_ms(10);
  80.                                                 flag        = TP_Scan_Voltage(Xpos + 3,Ypos + 3);
  81.                                                 if(flag == 1)
  82.                                                 {
  83.                                                         i = 0;
  84.                                                         printf("读取到第4个点的电压\r\n");                                                        
  85.                                                 }
  86.                                         }
  87.                                         TP_DrawPoint(lcddev.width - 20,20,WHITE);
  88.                         }
  89.                                 break;
  90.                         
  91.                         default:
  92.                         break;
  93.                 }        
  94.                
  95.         }

  96. }
复制代码




有错的实验现象: 新建位图图像.png



已经确定了是最后一个case导致出了问题,我新增了一个k变量,将i换成k,出来的结果就正常了,下面是能正常使用的代码和对应的结果:
  1. u16 Xpos[3],Ypos[3];
  2. void TP_Calibration(void)
  3. {
  4.         u8 flag,j;
  5.         u16 i,k = 0;
  6.         
  7.         printf("void TP_Calibration(void) V2.1 \r\n");
  8.         
  9.         
  10.         for(j = 0;j < 5;j++)
  11.         {

  12.                 switch(j)
  13.                 {
  14.                         case 0:       /* 画第一个点 */
  15.                         {
  16.                             i = 500;
  17.                             flag = 0;
  18.                             TP_DrawPoint(20,20,RED);
  19.                             while(i--)
  20.                                         {
  21.                                                 delay_ms(10);
  22.                                                 flag  = TP_Scan_Voltage(Xpos,Ypos);
  23.                                                 if(flag == 1)
  24.                                                 {
  25.                                                         i = 0;
  26.                                                         printf("读取到第1个点的电压\r\n");
  27.                                                         
  28.                                                 }
  29.                                         }
  30.                                         TP_DrawPoint(20,20,WHITE);        
  31.                         }                                       
  32.                         break;
  33.                                        
  34.                         case 1:     /* 画第二个点 */
  35.                         {
  36.                             i = 500;
  37.                             flag = 0;
  38.                             TP_DrawPoint(20,lcddev.height - 20,RED);
  39.                             while(i--)
  40.                                         {
  41.                                                 delay_ms(10);
  42.                                                 flag  = TP_Scan_Voltage(Xpos + 1,Ypos + 1);
  43.                                                 if(flag == 1)
  44.                                                 {
  45.                                                         i = 0;
  46.                                                         printf("读取到第2个点的电压\r\n");
  47.                                                 }
  48.                                         }
  49.                                   TP_DrawPoint(20,lcddev.height - 20,WHITE);                        
  50.                         }               
  51.                         break;
  52.                         
  53.                   case 2:
  54.                         {        
  55.                             i = 500;
  56.                             flag = 0;
  57.                             TP_DrawPoint(lcddev.width - 20,lcddev.height - 20,RED);
  58.                             while(i--)
  59.                                         {
  60.                                                 delay_ms(10);
  61.                                                 flag  = TP_Scan_Voltage(Xpos + 2,Ypos + 2);
  62.                                                 if(flag == 1)
  63.                                                 {
  64.                                                         i = 0;
  65.                                                         printf("读取到第3个点的电压\r\n");
  66.                                                 }
  67.                                         }
  68.                                         TP_DrawPoint(lcddev.width - 20,lcddev.height - 20,WHITE);
  69.                         }
  70.                                 break;
  71.                         
  72.                        [color=Red] case 3:
  73.                         {
  74.                             [b] k = 500;[/b]
  75.                             flag = 0;
  76.                             TP_DrawPoint(lcddev.width - 20,20,RED);
  77.                             while(k--)
  78.                                         {
  79.                                                 delay_ms(10);
  80.                                                 flag  = TP_Scan_Voltage(Xpos + 3,Ypos + 3);
  81.                                                 if(flag == 1)
  82.                                                 {
  83.                                                         k = 0;
  84.                                                         printf("读取到第4个点的电压\r\n");                                                        
  85.                                                 }
  86.                                         }
  87.                                         TP_DrawPoint(lcddev.width - 20,20,WHITE);
  88.                         }
  89.                                 break;[/color]
  90.                         
  91.                         default:
  92.                         break;
  93.                 }        
  94.                
  95.         }

  96. }
复制代码




新建位图图像.png

是不是我的第一段代码有逻辑问题呢?还是这原来就是STM32的BUG ?实在想不通,所以发上来和大家请教一下了
另外附件中也上传了整个工程的代码,供参考




此帖出自单片机论坛

Task_16_Touch.rar

370.93 KB, 下载次数: 0



回复

使用道具 举报

213

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-12 16:49 | 显示全部楼层
是不是我的第一段代码有逻辑问题呢?还是这原来就是STM32的BUG ?实在想不通,所以发上来和大家请教一下了
另外附件中也上传了整个工程的代码,供参考


回复

使用道具 举报

213

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-12 17:35 | 显示全部楼层
貌似和编译器优化有关,将编译器优化改成default就不出错了


回复

使用道具 举报

1072

TA的帖子

1

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

发表于 2019-1-12 19:29 | 显示全部楼层
厄,你写这个 for 循环的用意何在?

点评

程序的东西不是一想出来就是最简洁的,但是这个完完全全是我自己想出来的,功能完成了,后面怎么改都行  详情 回复 发表于 2019-1-12 21:24


回复

使用道具 举报

1万

TA的帖子

143

TA的资源

版主

Rank: 6Rank: 6

技术导师勋章

发表于 2019-1-12 19:59 | 显示全部楼层
凡与编译相关的,均与芯片bug无关。
上传了一些书籍资料,也许有你想要的:http://download.eeworld.com.cn/user/chunyang


回复

使用道具 举报

1万

TA的帖子

15

TA的资源

版主

Rank: 6Rank: 6

发表于 2019-1-12 20:35 | 显示全部楼层
不用问了,是编程的事不是BUG,因为四点效验我搞过。OVER

点评

我找到问题就是编译器的优化造成的,编译器默认的-O1优化会出问题,任选一个其他级别的优化就可以了  详情 回复 发表于 2019-1-12 21:19
http://shop34182318.taobao.com/
http://shop562064536.taobao.com


回复

使用道具 举报

213

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-12 21:19 | 显示全部楼层
ddllxxrr 发表于 2019-1-12 20:35
不用问了,是编程的事不是BUG,因为四点效验我搞过。OVER

我找到问题就是编译器的优化造成的,编译器默认的-O1优化会出问题,任选一个其他级别的优化就可以了


回复

使用道具 举报

213

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-12 21:24 | 显示全部楼层
cruelfox 发表于 2019-1-12 19:29
厄,你写这个 for 循环的用意何在?

程序的东西不是一想出来就是最简洁的,但是这个完完全全是我自己想出来的,功能完成了,后面怎么改都行


回复

使用道具 举报

3385

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2019-1-14 10:27 | 显示全部楼层
10.        for(j = 0;j < 5;j++)

11.        {

12.

13.                switch(j)

你这个逻辑语句很奇葩,j的值已经确定了还要去switch

点评

j是用来选画点的个数的,这不是重点。我克服了上面所说的优化产生的奇怪问题之后还是按照上面的逻辑来做,没有任何问题  详情 回复 发表于 2019-1-21 11:31


回复

使用道具 举报

3385

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2019-1-14 10:31 | 显示全部楼层
你这个程序不能假定用户校准时按下电阻屏的时间,还是要以电阻屏的采样值变化作为切换校准点的依据,所以for 或者(一定是或者,用一个就行) switch的条件要重新考虑


回复

使用道具 举报

6985

TA的帖子

193

TA的资源

五彩晶圆(高级)

Rank: 9Rank: 9Rank: 9

测评达人

发表于 2019-1-14 10:38 | 显示全部楼层
应该是编译器优化问题  i改成volatile试试?

点评

验证过了,就是keil默认的-O1优化导致出现问题,改成其他的优化等级就不会错了  详情 回复 发表于 2019-1-14 20:36


回复

使用道具 举报

213

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-14 20:36 | 显示全部楼层
常见泽1 发表于 2019-1-14 10:38
应该是编译器优化问题  i改成volatile试试?

验证过了,就是keil默认的-O1优化导致出现问题,改成其他的优化等级就不会错了


回复

使用道具 举报

213

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-21 11:31 | 显示全部楼层
huo_hu 发表于 2019-1-14 10:27
10.        for(j = 0;j < 5;j++)

11.        {

12.

13.                switch(j)

你这个逻辑 ...

j是用来选画点的个数的,这不是重点。我克服了上面所说的优化产生的奇怪问题之后还是按照上面的逻辑来做,没有任何问题

点评

触屏抬起切换到下一个点  详情 回复 发表于 2019-1-21 11:38


回复

使用道具 举报

3385

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2019-1-21 11:38 | 显示全部楼层
lingking 发表于 2019-1-21 11:31
j是用来选画点的个数的,这不是重点。我克服了上面所说的优化产生的奇怪问题之后还是按照上面的逻辑来做 ...

触屏抬起切换到下一个点

点评

没错啊,我的程序就是画点校准的时候,笔尖抬起就画下一个点然后继续采集电压值  详情 回复 发表于 2019-1-21 20:45


回复

使用道具 举报

213

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-21 20:45 | 显示全部楼层
huo_hu 发表于 2019-1-21 11:38
触屏抬起切换到下一个点

没错啊,我的程序就是画点校准的时候,笔尖抬起就画下一个点然后继续采集电压值


回复

使用道具 举报

3385

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2019-1-23 11:43 | 显示全部楼层
那不知道了,你调试一下进去看看


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2019-4-21 14:08 , Processed in 0.410726 second(s), 18 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表