11528|15

367

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

这算不算是STM32的BUG [复制链接]

 
本帖最后由 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. }
复制代码




有错的实验现象:



已经确定了是最后一个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. }
复制代码






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




Task_16_Touch.rar

370.93 KB, 下载次数: 0

此帖出自单片机论坛

最新回复

那不知道了,你调试一下进去看看  详情 回复 发表于 2019-1-23 11:43
点赞 关注(1)
个人签名拿PADS和Allegro软件来吹牛的都是些土鳖
 

回复
举报

367

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
是不是我的第一段代码有逻辑问题呢?还是这原来就是STM32的BUG ?实在想不通,所以发上来和大家请教一下了
另外附件中也上传了整个工程的代码,供参考
此帖出自单片机论坛
 
个人签名拿PADS和Allegro软件来吹牛的都是些土鳖
 

回复

367

帖子

0

TA的资源

一粒金砂(高级)

板凳
 
貌似和编译器优化有关,将编译器优化改成default就不出错了
此帖出自单片机论坛
 
个人签名拿PADS和Allegro软件来吹牛的都是些土鳖
 
 

回复

1379

帖子

2

TA的资源

五彩晶圆(初级)

4
 
厄,你写这个 for 循环的用意何在?
此帖出自单片机论坛

点评

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

回复

1万

帖子

139

TA的资源

版主

5
 
凡与编译相关的,均与芯片bug无关。
此帖出自单片机论坛
 
个人签名上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
 
 

回复

1万

帖子

16

TA的资源

版主

6
 
不用问了,是编程的事不是BUG,因为四点效验我搞过。OVER
此帖出自单片机论坛

点评

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

回复

367

帖子

0

TA的资源

一粒金砂(高级)

7
 
ddllxxrr 发表于 2019-1-12 20:35
不用问了,是编程的事不是BUG,因为四点效验我搞过。OVER

我找到问题就是编译器的优化造成的,编译器默认的-O1优化会出问题,任选一个其他级别的优化就可以了
此帖出自单片机论坛
 
个人签名拿PADS和Allegro软件来吹牛的都是些土鳖
 
 

回复

367

帖子

0

TA的资源

一粒金砂(高级)

8
 
cruelfox 发表于 2019-1-12 19:29
厄,你写这个 for 循环的用意何在?

程序的东西不是一想出来就是最简洁的,但是这个完完全全是我自己想出来的,功能完成了,后面怎么改都行
此帖出自单片机论坛
 
个人签名拿PADS和Allegro软件来吹牛的都是些土鳖
 
 

回复

4008

帖子

0

TA的资源

版主

9
 
10.        for(j = 0;j < 5;j++)

11.        {

12.

13.                switch(j)

你这个逻辑语句很奇葩,j的值已经确定了还要去switch
此帖出自单片机论坛

点评

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

回复

4008

帖子

0

TA的资源

版主

10
 
你这个程序不能假定用户校准时按下电阻屏的时间,还是要以电阻屏的采样值变化作为切换校准点的依据,所以for 或者(一定是或者,用一个就行) switch的条件要重新考虑
此帖出自单片机论坛
 
 
 

回复

7219

帖子

195

TA的资源

五彩晶圆(高级)

11
 
应该是编译器优化问题  i改成volatile试试?
此帖出自单片机论坛

点评

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

回复

367

帖子

0

TA的资源

一粒金砂(高级)

12
 
常见泽1 发表于 2019-1-14 10:38
应该是编译器优化问题  i改成volatile试试?

验证过了,就是keil默认的-O1优化导致出现问题,改成其他的优化等级就不会错了
此帖出自单片机论坛
 
个人签名拿PADS和Allegro软件来吹牛的都是些土鳖
 
 

回复

367

帖子

0

TA的资源

一粒金砂(高级)

13
 
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
 
个人签名拿PADS和Allegro软件来吹牛的都是些土鳖
 
 

回复

4008

帖子

0

TA的资源

版主

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

触屏抬起切换到下一个点
此帖出自单片机论坛

点评

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

回复

367

帖子

0

TA的资源

一粒金砂(高级)

15
 
huo_hu 发表于 2019-1-21 11:38
触屏抬起切换到下一个点

没错啊,我的程序就是画点校准的时候,笔尖抬起就画下一个点然后继续采集电压值
此帖出自单片机论坛
 
个人签名拿PADS和Allegro软件来吹牛的都是些土鳖
 
 

回复

4008

帖子

0

TA的资源

版主

16
 
那不知道了,你调试一下进去看看
此帖出自单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表