独闷闷网

 找回密码
 立即注册
搜索
查看: 4687|回复: 2
收起左侧

[原创] 发现keil的一个秘密,编译环境Memory Mode只能选Small,否则容易出现诡异现象。

[复制链接]
发表于 2015-1-7 13:59:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

x
本帖最后由 jianhong_wu 于 2015-1-8 19:48 编辑

鸿哥-深圳:
small.jpg compact.jpg large.jpg
今天用stc15w204s单片机调试发现了一个惊天秘密,于是决定把它写出来,避免后来人犯错。就是在我们使用keil的时候,在编译环境Memory Model选项里,强烈推荐大家使用Small模式,千万不要选Compact和Large模式,否则会出现以下诡异的现象。比如,我以下两个代码都是让一个LED灯闪烁。第一个是用delay延时方式,第二个是用累加主循环次数的延时方式。结果发现,当我用Compact和Large模式的时候,第一个代码能正常闪烁,第二个代码不能正常闪烁。而当我用Small模式的时候,两个代码都能正常闪烁。


第一个是用delay延时方式:

  1. //假定测试芯片的工作频率为11.0592MHz

  2. #include "reg51.h"

  3. sfr P3M1 = 0xb1;
  4. sfr P3M0 = 0xb2;

  5. sfr P5M1 = 0xC9;
  6. sfr P5M0 = 0xCA;


  7. sbit P30 = P3^0;
  8. sbit P31 = P3^1;
  9. sbit P32 = P3^2;
  10. sbit P33 = P3^3;


  11. void delay()
  12. {
  13.     int i, j;

  14.     for (i=0; i<1000; i++)
  15.     for (j=0; j<500; j++);
  16. }


  17. void main()
  18. {

  19.     P3M0 = 0x00;  //P3为普通的准双向口
  20.     P3M1 = 0x00;

  21.     P5M0 = 0x00;  //P5为比较器IO口,必须设置为高阻输入
  22.     P5M1 = 0xff;



  23.     P33 = 1;
  24.     P32 = 1;


  25.   

  26.     while (1)
  27.     {
  28.            P33 = 0;
  29.        P32 = 1;
  30.        delay();
  31.            P33 = 1;
  32.        P32 = 0;
  33.        delay();
  34.     }
  35. }
复制代码


第二个是用累加主循环次数的延时方式:

  1. //假定测试芯片的工作频率为11.0592MHz

  2. #include "reg51.h"

  3. #define const_time_level 10000  

  4. sfr P3M1 = 0xb1;
  5. sfr P3M0 = 0xb2;

  6. sfr P5M1 = 0xC9;
  7. sfr P5M0 = 0xCA;


  8. sbit P30 = P3^0;
  9. sbit P31 = P3^1;
  10. sbit P32 = P3^2;
  11. sbit P33 = P3^3;

  12. void led_flicker(void);


  13. unsigned char ucLedStep=0; //步骤变量
  14. unsigned long  ulTimeCnt=0; //统计循环次数的延时计数器

  15. void main()
  16. {

  17.     P3M0 = 0x00;  //P3为普通的准双向口
  18.     P3M1 = 0x00;

  19.     P5M0 = 0x00;  //P5为比较器IO口,必须设置为高阻输入
  20.     P5M1 = 0xff;

  21.     P33 = 1;
  22.     P32 = 1;


  23.     while (1)
  24.     {
  25.            led_flicker();   
  26.     }
  27. }


  28. void led_flicker(void)
  29. {
  30.   
  31.   switch(ucLedStep)
  32.   {
  33.      case 0:
  34.           ulTimeCnt++;  //累加循环次数,
  35.           if(ulTimeCnt>=const_time_level) //时间到
  36.           {
  37.              ulTimeCnt=0; //时间计数器清零
  38.                  P33 = 0;
  39.              P32 = 1;
  40.              ucLedStep=1; //切换到下一个步骤
  41.           }
  42.           break;
  43.      case 1:
  44.           ulTimeCnt++;  //累加循环次数,
  45.           if(ulTimeCnt>=const_time_level) //时间到
  46.           {
  47.              ulTimeCnt=0; //时间计数器清零
  48.                  P33 = 1;
  49.              P32 = 0;
  50.              ucLedStep=0; //返回到上一个步骤
  51.           }
  52.           break;
  53.   }

  54. }
复制代码



乐于分享,勇于质疑!
发表于 2015-1-13 22:04:09 | 显示全部楼层
是仿真时有诡异现象还是实物也有?
乐于分享,勇于质疑!
 楼主| 发表于 2015-1-20 23:27:12 | 显示全部楼层
fzwwj95 发表于 2015-1-13 22:04
是仿真时有诡异现象还是实物也有?

实物。就是stc15那款单片机。
乐于分享,勇于质疑!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|独闷闷网 ( 粤ICP备12007667号-2 )

GMT+8, 2021-9-20 01:53 , Processed in 0.181643 second(s), 20 queries .

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