微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > IAR FOR 8051 使用中的一个“坑”与大家分享,请君勿入“坑!”

IAR FOR 8051 使用中的一个“坑”与大家分享,请君勿入“坑!”

时间:10-02 整理:3721RD 点击:
近日在用IAR FOR 8050  8.10版本调试CC2530单片机中发现了一个非常奇怪的问题,我用print函数向串口打印传感器数据,一切都调试正,如下图所示:



现在数据输出正常吧!

然后要增加新的功能了,这是必须的。

然后…..

加入了一个C文件,sleeptime.c,这是用来设置定时休眠的,源文件如下:

  1. *****************************************/
  2. /*引用********************************************/
  3. #include "SleepTime.h"
  4. /*宏定义*****************************************/
  5. bool SleepWakeFlag=false;
  6. //初始化睡眠定时器
  7. void init_sleep_timer(void)
  8. {
  9.   ST2=0X00;
  10.   ST1=0X0F;
  11.   ST0=0X0F;//设置计数值
  12.   EA=1;//开中断
  13.   STIE=1;//使能睡眠定时器中断
  14.   STIF=0;//清除睡眠定时器中断标志
  15. }

  16. //设置睡眠时间
  17. void set_st_period(uint16_t sec)
  18. {
  19.   uint32_t sleeptimer=0;
  20.   //把ST2:ST1:ST0赋值给sleeptimer
  21.   sleeptimer |=ST0;
  22.   sleeptimer |=(uint32_t)ST1<<8;
  23.   sleeptimer |=(uint32_t)ST2<<16;
  24.   sleeptimer +=((uint32_t)sec*(uint32_t)32768);//低速频率为32.768KHZ,故每秒定时器计数32768次
  25.   //把加N秒的计数值赋给ST2:ST1:ST0
  26.   ST2=(uint8_t)(sleeptimer>>16);
  27.   ST1=(uint8_t)(sleeptimer>>8);
  28.   ST0=(uint8_t)sleeptimer;
  29. }
  30. /*中断函数定义********************************/
  31. //休眠中断唤醒
  32. #pragma vector=ST_VECTOR
  33. __interrupt void ST_ISR(void)
  34. {
  35.   STIF=0;//标志清除
  36.   //ledblink=1;//唤醒
  37.   SleepWakeFlag=true;
  38. }

复制代码

上面这个文件只是加入进来,没有调用里面的任何函数哦,

编绎通过,没有报错,下载,运行….

奇怪的事情发生了,串口打印的数据变成了这样:


全部变成了超级大的负值,百思不得其解,清除,重新编绎,再下载,不行!

关闭工程,再打开,不行!

甚至重启了电脑,不是不行。

把上面的sleeptime.c这个文件从工程中移除,重新编绎,再下载,又正常了。


看来只能采用最笨的排除法了,最先怀疑的是这段代码:

  1. //设置睡眠时间
  2. void set_st_period(uint16_t sec)
  3. {
  4.   uint32_t sleeptimer=0;
  5.   //把ST2:ST1:ST0赋值给sleeptimer
  6.   sleeptimer |=ST0;
  7.   sleeptimer |=(uint32_t)ST1<<8;
  8.   sleeptimer |=(uint32_t)ST2<<16;
  9.   sleeptimer +=((uint32_t)sec*(uint32_t)32768);//低速频率为32.768KHZ,故每秒定时器计数32768次
  10.   //把加N秒的计数值赋给ST2:ST1:ST0
  11.   ST2=(uint8_t)(sleeptimer>>16);
  12.   ST1=(uint8_t)(sleeptimer>>8);
  13.   ST0=(uint8_t)sleeptimer;
  14. }

复制代码

把这个函数整件屏蔽了,编译,下载,正常。

我的天呐!噩梦还在继续!


只有采用逐行排除了,

  1. void set_st_period(uint16_t sec)
  2. {
  3.   uint32_t sleeptimer=0;
  4.   //把ST2:ST1:ST0赋值给sleeptimer
  5.   sleeptimer |=ST0;
  6.   sleeptimer |=(uint32_t)ST1<<8;
  7.   sleeptimer |=(uint32_t)ST2<<16;
  8.   sleeptimer +=((uint32_t)sec*(uint32_t)32768);//低速频率为32.768KHZ,故每秒定时器计数32768次
  9.   //把加N秒的计数值赋给ST2:ST1:ST0
  10. // ST2=(uint8_t)(sleeptimer>>16);
  11. // ST1=(uint8_t)(sleeptimer>>8);
  12. //  ST0=(uint8_t)sleeptimer;
  13. }
  14. 还是不行,接着屏蔽
  15. void set_st_period(uint16_t sec)
  16. {
  17.   uint32_t sleeptimer=0;
  18.   //把ST2:ST1:ST0赋值给sleeptimer
  19. //  sleeptimer |=ST0;
  20. //  sleeptimer |=(uint32_t)ST1<<8;
  21. // sleeptimer |=(uint32_t)ST2<<16;
  22. //  sleeptimer +=((uint32_t)sec*(uint32_t)32768);//低速频率为32.768KHZ,故每秒定时器计数32768次
  23.   //把加N秒的计数值赋给ST2:ST1:ST0
  24. // ST2=(uint8_t)(sleeptimer>>16);
  25. // ST1=(uint8_t)(sleeptimer>>8);
  26. //  ST0=(uint8_t)sleeptimer;
  27. }

复制代码

最后屏蔽得就剩下这行代码了

  uint32_t sleeptimer=0;

定义了一个长整型的变量,编绎下载,还是不行

看来问题就出在这行代码上了,可实在看不出有什么问题,只能采用各种怀疑了…

难道长整型赋值不对,把代码改成如下:

uint32_tsleeptimer=0L;


编绎通过,吐血,还是不行:


难道这个变量不能定义成局部变量,把这个变量定义放到函数外面试试:

  uint32_t sleeptimer=0;

voidset_st_period(uint16_t sec)

{

  //把ST2:ST1:ST0赋值给sleeptimer

sleeptimer |=ST0;

  sleeptimer |=(uint32_t)ST1<<8;

  sleeptimer |=(uint32_t)ST2<<16;

/ sleeptimer+=((uint32_t)sec*(uint32_t)32768);//低速频率为32.768KHZ,故每秒定时器计数32768次

  //把加N秒的计数值赋给ST2:ST1:ST0

ST2=(uint8_t)(sleeptimer>>16);

ST1=(uint8_t)(sleeptimer>>8);

  ST0=(uint8_t)sleeptimer;

}

编绎,下载,激动人心一刻要来临了,行不行呢?


这里插播一条广告哦,我们把平里产品开发过程中用到的一些芯片、技术顺便做成了模块,与大家一起分享:



https://shop368495242.taobao.com/shop/view_shop.htm?spm=a313o.7775905.a1zvx.d53.35627f98OZfelp&mytmenu=mdianpu&user_number_id=3326006997

欲知后事如何,请先看图:


终于,串口打印数据打印又恢复正常了。


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top