[技术问答] 发现新唐N76E003一个伤脑的BUG!!

[复制链接]
1523|50
 楼主 | 2018-6-14 10:10 | 显示全部楼层 |阅读模式
#include "N76E003.h"

unsigned int SPEED_CNT=0;
unsigned int ct = 0;

void main(void)
{
          TMOD&=0x0F;
          TMOD|=0x10;
       
          //CKCON   |= 0x08;
       
                TH0 = (65536-16000)/256;
          TL0 = (65536-16000)%256;
       
                ET0 = 1;
          TR0=1;
          EA=1;
       
                P1M1&=~0X02;P1M2|=0X02;
               
                while(1)
                {
                        if(SPEED_CNT>1000)
                        {
                                                SPEED_CNT = 0;  //该处设置断点,然后看仿真的值
                                                                         //然后咱们会发现很神奇的现象,SPEED_CNT
                                                                         //居然一会是1001,一会又是768,而就算定时器
                        }                                               //再强大也不会超过1M的中断频率吧
                }                                                       //运行到该处会差这么大!!
}                                                                       //而且咱们可以改变SPEED_CNT >500试试,
                                                                        //呵呵,结果又是很神奇!!
void Timer0_IRQHandler(void) interrupt 1
{
                TR0=0;
    TH0 = (65536-16000)/256;
    TL0 = (65536-16000)%256;
          P11 =~P11;
                SPEED_CNT++;
                TF0 = 0;
                TR0=1;
}

评论

xch 2018-6-15 09:08 回复TA
如果没有其他中断 把这句if(SPEED_CNT>1000) 改成 if(SPEED_CNT==1000) 最简单解决 
 楼主 | 2018-6-14 10:16 | 显示全部楼层
咱们直接看结果吧

本帖子中包含更多资源

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

x
| 2018-6-14 10:20 | 显示全部楼层
仿真状态下,有可能定时器执行的快,主函数执行的慢,所以出现这样的情况了。你把判断放在定时器中看看。
 楼主 | 2018-6-14 10:24 | 显示全部楼层
xyz549040622 发表于 2018-6-14 10:20
仿真状态下,有可能定时器执行的快,主函数执行的慢,所以出现这样的情况了。你把判断放在定时器中看看。 ...

if(SPEED_CNT>1000)
                        {
                                                SPEED_CNT = 0;
                                                P11=~P11;
                    }

你实际运行下,然后看波形,如果结果是正常的波形我就服你
 楼主 | 2018-6-14 10:33 | 显示全部楼层
希望新塘的技术人员来帮我解决下,否则这款芯片会烂大街了!!!
| 2018-6-14 10:43 | 显示全部楼层
是自己的程序问题呀!
768=0X0300,1000=0X03E8。
当767时,等于0X02FF,此时主程序先取低字节FF,还没有取高字节0X02,进中断了,退出中断,高字节是0X03了,主程序把0X02FF读成0X03FF了,比0X03E8大了。
嘿嘿,如果还有不懂,自己看反汇编代码。
主程序,应该飞读这个SPEED_CNT,连续2次读出正确,才认为正确。
| 2018-6-14 10:44 | 显示全部楼层
任何在中断程序里有变化的双字节以上变量,都必须飞读(多次读比较,或者临时关闭中断)。
| 2018-6-14 10:46 | 显示全部楼层
//飞读飞写,T2中断函数会修改的双字节变量,防止读出写入误差256的数值
uint fly_read(uint *s)
{
        uint i;
        ET2=0;
        i=*s;
        ET2=1;
        return i;
}
这是我的处理方式
 楼主 | 2018-6-14 10:49 | 显示全部楼层
我觉得你们都只停留在理论层面,没有人拿示波器看看实际波形!!我这边测试了很多次,实际波形也那样

评论

gx_huang 2018-6-14 10:54 回复TA
我不仅讲理论,还有很多实践,(^-^) 
 楼主 | 2018-6-14 10:49 | 显示全部楼层
如果你们没有示波器,我可以借给你们

评论

gx_huang 2018-6-14 10:54 回复TA
我有示波器,肯定是程序问题 
| 2018-6-14 10:50 | 显示全部楼层
你的测试程序,出现该问题的概率很大的,主程序一直在判断,估计出错概率几分之一。
如果有其它任务,出错概率会下降很多,比如百分之一,更难定位故障。
这个问题,变量在中断函数改变,主程序又判断这个变量,批量产品少的工程师,很难觉察的。到了用户手里,出问题的概率也不高的,但是可能是致命的。

评论

qiyuejikangxin 2018-6-14 10:56 回复TA
这个问题在ST单片机中完全没有这低级现象,而在这款单片机就出现了,请忽略我的仿真,请看实际波形;实际案例中这种程序是很正常的写法!!除非你有更高级的写法,或在中断中直接判断,不提出来!!变量多程序大的时候呢,都在中断中解决? 
gx_huang 2018-6-14 11:03 回复TA
@qiyuejikangxin :在16位的MCU,不会出现。8位的MCU,和C编译器也有关,和取数的顺序有关,和优化有关。有些芯片的寄存器,8位的MCU,16位以上的寄存器,都有硬件飞读功能。 
| 2018-6-14 10:53 | 显示全部楼层
实际经验告诉我们,老是怀疑芯片有问题,往往走歧路。
绝大部分是自己的问题,你能发现芯片的问题,概率那是相当的小,可以先忽略。

评论

qiyuejikangxin 2018-6-14 11:04 回复TA
同样的写法同样规格的芯片,也号称所谓的1T单片机,为何STM8S003就不会出现这种情况呢!! 
gx_huang 2018-6-14 11:07 回复TA
@qiyuejikangxin :我告诉你要飞读,你就应该理解了呀,ST的可以,和ST的指令系统、编译环境都有关呀。51就是不行,ST8也许会不行,要分析反汇编代码才可以明确是否可以。 
| 2018-6-14 10:56 | 显示全部楼层
我这辈子唯一发现的芯片问题,就是NXP的LPC900系列芯片,上电复位异常,批量产品发现的,实验也验证了,官网上查,果然有这个BUG,官网都承认了。
 楼主 | 2018-6-14 10:57 | 显示全部楼层
gx_huang 发表于 2018-6-14 10:50
你的测试程序,出现该问题的概率很大的,主程序一直在判断,估计出错概率几分之一。
如果有其它任务,出错 ...

一个产品是看不出毛病,但好几个产品摆在一起,就会明显有出现不同步现象
| 2018-6-14 10:59 | 显示全部楼层
怎么可能有这种BUG,我们都用了很多了,没遇到。
| 2018-6-14 11:00 | 显示全部楼层
qiyuejikangxin 发表于 2018-6-14 10:57
一个产品是看不出毛病,但好几个产品摆在一起,就会明显有出现不同步现象 ...

一看见你实际需要1001,偶尔出现768,就知道是程序问题,我的产品也遇到过的,解剖反汇编代码,很容易发现问题的原因。只是实际出问题的概率只有百分之一,研发测试没有发现,给用户发现了。延时差了256秒,产品会报废的。
| 2018-6-14 11:01 | 显示全部楼层
  1. /*---------------------------------------------------------------------------------------------------------*/
  2. /*                                                                                                         */
  3. /* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved.                                         */
  4. /*                                                                                                         */
  5. /*---------------------------------------------------------------------------------------------------------*/

  6. //***********************************************************************************************************
  7. //  Nuvoton Technoledge Corp.
  8. //  Website: http://www.nuvoton.com
  9. //  E-Mail : MicroC-8bit@nuvoton.com
  10. //  Date   : Apr/21/2017
  11. //***********************************************************************************************************

  12. //***********************************************************************************************************
  13. //  File Function: N76E003 Timer0/1 Mode0 demo code
  14. //***********************************************************************************************************
  15. #include "N76E003.h"
  16. #include "Common.h"
  17. #include "Delay.h"
  18. #include "SFR_Macro.h"
  19. #include "Function_define.h"

  20. //*****************  The Following is in define in Fucntion_define.h  ***************************
  21. //****** Always include Function_define.h call the define you want, detail see main(void) *******
  22. //***********************************************************************************************
  23. #if 0
  24. //#define                TIMER1_MODE0_ENABLE                TMOD&=0x0F
  25. //#define                TIMER1_MODE1_ENABLE                TMOD&=0x0F;TMOD|=0x10
  26. //#define                TIMER1_MODE2_ENABLE                TMOD&=0x0F;TMOD|=0x20
  27. //#define                TIMER1_MODE3_ENABLE                TMOD&=0x0F;TMOD|=0x3F

  28. //#define                TIMER0_MODE0_ENABLE                TMOD&=0xF0
  29. //#define                TIMER0_MODE1_ENABLE                TMOD&=0xF0;TMOD|=0x01
  30. //#define                TIMER0_MODE2_ENABLE                TMOD&=0xF0;TMOD|=0x02
  31. //#define                TIMER0_MODE3_ENABLE                TMOD&=0xF0;TMOD|=0xF3
  32. #endif

  33. #define TH0_INIT        0xFC //5.0ms@XTAL=12MHz, Period = (10.85/2) ms@XTAL=22.1184MHz
  34. #define TL0_INIT        0x0F
  35. #define TH1_INIT        0xE0 //2.5ms@XTAL=12MHz, Period = (5.425/2) ms@XTAL=22.1184MHz
  36. #define TL1_INIT        0x00


  37. /************************************************************************************************************
  38. *    TIMER 0 interrupt subroutine
  39. ************************************************************************************************************/
  40. void Timer0_ISR (void) interrupt 1          //interrupt address is 0x000B
  41. {
  42.     TH0 = TH0_INIT;
  43.     TL0 = TL0_INIT;   
  44.     P12 = ~P12;                                                                                                                        // GPIO toggle when interrupt
  45. }
  46. /************************************************************************************************************
  47. *    TIMER 1 interrupt subroutine
  48. ************************************************************************************************************/
  49. void Timer1_ISR (void) interrupt 3          //interrupt address is 0x001B
  50. {
  51.     TH1 = TH1_INIT;
  52.     TL1 = TL1_INIT;   
  53.     P03 = ~P03;                                                                                                                        // GPIO toggle when interrupt
  54. }
  55. /************************************************************************************************************
  56. *    Main function
  57. ************************************************************************************************************/
  58. void main (void)
  59. {
  60.         TMOD = 0XFF;
  61.         Set_All_GPIO_Quasi_Mode;
  62.         TIMER0_MODE0_ENABLE;                        //Timer 0 and Timer 1 mode configuration
  63.         TIMER1_MODE0_ENABLE;
  64.    
  65.         clr_T0M;
  66.         clr_T1M;
  67.    
  68.         TH0 = TH0_INIT;
  69.         TL0 = TL0_INIT;
  70.         TH1 = TH1_INIT;
  71.         TL1 = TL1_INIT;
  72.    
  73. //        set_ET0;                                    //enable Timer0 interrupt
  74.         set_ET1;                                    //enable Timer1 interrupt
  75.         set_EA;                                     //enable interrupts
  76.        
  77.         set_TR0;                                    //Timer0 run
  78. //        set_TR1;                                    //Timer1 run

  79.   while(1)
  80.         {
  81.                 TH0 = TH0_INIT;
  82.                 TL0 = TL0_INIT;
  83.                 set_TR0;
  84.                 while(!TF0);
  85.                 clr_TR0;
  86.                 P12 = ~P12;       
  87.                 TF0 = 0 ;
  88. }
  89. }
  90. [em:23:]
复制代码
| 2018-6-14 11:02 | 显示全部楼层
gx_huang 发表于 2018-6-14 10:53
实际经验告诉我们,老是怀疑芯片有问题,往往走歧路。
绝大部分是自己的问题,你能发现芯片的问题,概率那 ...

是的,如果真有这么严重的问题,人家厂家都**了,怎么可能,那么多出货量,大家都在用,真有问题,不会等楼主去发现了。哈哈
 楼主 | 2018-6-14 11:13 | 显示全部楼层
gx_huang 发表于 2018-6-14 11:00
一看见你实际需要1001,偶尔出现768,就知道是程序问题,我的产品也遇到过的,解剖反汇编代码,很容易发 ...

从ST转过来,同样的写法,在这芯片上就有问题,首先怀疑的是芯片,而且程序的逻辑也正常啊!!所以我现在解决办法是在中断中不超过u8类型的计数,这样就不会有问题,非常感谢你,知道它出错的原因了!!
| 2018-6-14 11:20 | 显示全部楼层
qiyuejikangxin 发表于 2018-6-14 11:13
从ST转过来,同样的写法,在这芯片上就有问题,首先怀疑的是芯片,而且程序的逻辑也正常啊!!所以我现在 ...

是的,这是通常的分析问题的逻辑思维。
我是搞硬件的,喜欢钻研底层的原理,硬件电路先计算测试各点电压波形,看看是否有偏差,最终结果不是首先关注的,中间结果对,最终结果就是对的。
软件也是一样,刚开始汇编语言,就关注这些前后顺序,关注现场保护。到了C语言,也特别喜欢反汇编,看看是否符合预期。
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

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