网站导航:首页 > 论坛 > Easy Usb 51 Programer > 帖子浏览
   您正在浏览第 716 号帖子 收藏该帖

楼主 作者:saliven  发表时间:2010-8-24 10:18:00

使用STC11F48XE作为主控MCU系统不正常的问题已解决

前段时间提出来的使用STC11F48XE后,烧录程序不正常的问题。
后来自己已经解决了该问题,觉得应该和大家分享一下,现将问题处理的方法发在这里。

经过查询资料,STC11系列的处理效率比普通51系列快了3--24倍,因此,在程序中很多使用空指令、循环来进行延时的地方,就不适用了,必须全部使用精确的定时函数来处理。
经过测算,12M以下时钟,能处理的精确定时在500us左右,再小就有可能出问题了,因此我增加了这个处理500us定时的函数,和以前的处理1ms定时的同时配合使用。
将所有的用空指令、循环来进行延时的地方,全部使用延时500us函数替换,经过测试,程序已经可以在STC11F48XE上稳定运行了。
在此建议:不要使用空指令、循环等来实现短延时,这样实现的程序对MCU的依赖性太高,换一个MCU可能就不能执行了,而应该使用精确的定时功能来实现延时。

具体改动的地方:

  1. //**********************************   
  2. //   
  3. //DELAY.H   
  4. //   
  5. //*********************************   
  6.   
  7. #ifndef __DELAY_H__   
  8. #define __DELAY_H__   
  9.   
  10. #define CRYSTALCLK 11059200 //晶振频率   
  11. #define TIMER0_CLK 1000 //Timer0溢出频率(必须比CRYSTALCLK/12小),1000Hz定时1ms   
  12. #define TIMER1_CLK 2000 //Timer1溢出频率(必须比CRYSTALCLK/12小),10000Hz定时500us   
  13.   
  14. void Timer0_Init();   
  15. void delay_1ms();   
  16. void delay_xms(unsigned char ucXms);   
  17. void delay_500us();   
  18. void delay_xxus(unsigned char ucXus);   
  19.   
  20. #endif   
  21.   
  22.   
  23. //**********************************   
  24. //   
  25. //DELAY.C   
  26. //   
  27. //*********************************   
  28. #include "DELAY.H"   
  29. #include <at89x52.h>   
  30.   
  31.   
  32. unsigned char nTL0_INIT,nTL1_INIT;   
  33. unsigned char nTH0_INIT,nTH1_INIT;   
  34.   
  35. /************************************************************   
  36. ** 函数名称: void Timer0_Init()   
  37. ** 功能描述: 初始Timer0,设置工作方式,需要在主函数中调用一次   
  38. ** 输  入: 无   
  39. ** 输   出: 无   
  40. ************************************************************/   
  41. void Timer0_Init()   
  42. {   
  43.     TMOD |= 0x0F;   
  44.     TMOD &= 0xF1; //Timer0为16位定时器   
  45.        
  46.     nTL0_INIT = (65535-CRYSTALCLK/(TIMER0_CLK*12))%256;   
  47.     nTH0_INIT = (65535-CRYSTALCLK/(TIMER0_CLK*12))/256;   
  48.     nTL1_INIT = (65535-CRYSTALCLK/(TIMER1_CLK*12))%256;   
  49.     nTH1_INIT = (65535-CRYSTALCLK/(TIMER1_CLK*12))/256;   
  50. }   
  51.   
  52. /************************************************************  
  53. ** 函数名称: void delay_1ms()  
  54. ** 功能描述: 利用timer0的溢出率延时1ms  
  55. ** 输  入: 无  
  56. ** 输   出: 无  
  57. ************************************************************/  
  58. void delay_1ms()   
  59. {   
  60.     bit bEAState = EA;   
  61.     EA = 0;   
  62.        
  63.     //根据CRYSTALCLK和TIMER0_CLK(即Timer0的溢出率)初始Timer0   
  64.        
  65.     TL0 = nTL0_INIT;   
  66.     TH0 = nTH0_INIT;   
  67.        
  68.     TR0 = 1;   
  69.     while(~TF0);   
  70.     TF0 = 0;   
  71.     TR0 = 0;   
  72.        
  73.     EA = bEAState;   
  74. }   
  75.   
  76. /************************************************************  
  77. ** 函数名称: void delay_xms()  
  78. ** 功能描述: 利用timer0的溢出率延时若干ms  
  79. ** 输  入: unsigned char ucXms->多少ms  
  80. ** 输   出: 无  
  81. ************************************************************/  
  82. void delay_xms(unsigned char ucXms)   
  83. {   
  84.     while(ucXms--)   
  85.     {   
  86.         delay_1ms();   
  87.     }   
  88. }   
  89.   
  90. /************************************************************  
  91. ** 函数名称: void delay_100us()  
  92. ** 功能描述: 利用timer0的溢出率延时500us  
  93. ** 输  入: 无  
  94. ** 输   出: 无  
  95. ************************************************************/  
  96. void delay_500us()   
  97. {   
  98.     bit bEAState = EA;   
  99.     EA = 0;   
  100.        
  101.     //根据CRYSTALCLK和TIMER1_CLK(即Timer1的溢出率)初始Timer1   
  102.        
  103.     TL0 = nTL1_INIT;   
  104.     TH0 = nTH1_INIT;   
  105.        
  106.     TR0 = 1;   
  107.     while(~TF0);   
  108.     TF0 = 0;   
  109.     TR0 = 0;   
  110.        
  111.     EA = bEAState;   
  112. }   
  113.   
  114. /************************************************************  
  115. ** 函数名称: void delay_xxus()  
  116. ** 功能描述: 利用timer0的溢出率延时若干us*500  
  117. ** 输  入: unsigned char ucXus->多少us*500  
  118. ** 输   出: 无  
  119. ************************************************************/  
  120. void delay_xxus(unsigned char ucXus)   
  121. {   
  122.     while(ucXus--)   
  123.     {   
  124.         delay_500us();   
  125.     }   
  126. }   
AT89C5X.C
只列出一个函数的修改,其他地方参考修改就可以了

  1. void AT89C5X_Write(unsigned char ucStartingAddressBuffer[2],unsigned char ucDataBuffer[],unsigned char ucDataLengthBuffer[])   
  2. {   
  3.     unsigned char i,j;   
  4.     unsigned int nStartingAddress = ucStartingAddressBuffer[1]*256+ucStartingAddressBuffer[0];   
  5.        
  6.     AT89C5X_InitOpt();   
  7.        
  8.     P27 = 0;   
  9.     delay_xms(1);   
  10.     P27 = 1;   
  11.     delay_xms(1);   
  12.        
  13.     for(i = 0; i < ucDataLengthBuffer[0]; i++)   
  14.     {    
  15.         //1. Input the desired memory location on the address lines.   
  16.         SetAddress(nStartingAddress);   
  17.         //2. Input the appropriate data byte on the data lines.   
  18.         PortData = ucDataBuffer[i];   
  19.         //3. Activate the correct combination of control signals.    
  20.         P26 = 0;   
  21.         P27 = 1;    
  22.         P36 = 1;   
  23.         P37 = 1;   
  24.         P33 = 1; //为兼容S系列(P3.3=1),对C系列无影响   
  25.         PROG = 1;   
  26.            
  27.         //4. Raise EA/VPP to 12V for the high-voltage programming mode.   
  28.         if(bHighProgrameVoltage)   
  29.             SetVpp(12);   
  30.         else  
  31.             SetVpp(5);   
  32.         delay_xxus(1);   
  33.            
  34.         //5. Pulse ALE/PROG once to program a byte in the Flash array or the lock bits.   
  35.         PROG = 0;   
  36.         delay_xxus(1);   
  37.            
  38.         //The byte-write cycle is   
  39.         //self-timed and typically takes no more than 1.5 ms.   
  40.         //Repeat steps 1 through 5, changing the address   
  41.         //and data for the entire array or until the end of the   
  42.         //object file is reached.    
  43.         PROG = 1;   
  44.         delay_xxus(1);   
  45.            
  46.         SetVpp(5);   
  47.         delay_xxus(1);   
  48.            
  49.         P27 = 0;   
  50.         // delay_xms(2); //C系列写一个地址不超过1.5ms,而S系列不超过50us   
  51.         //两类芯片差别如此之大,还是不要定死延时了,让事实说话吧   
  52.         j = 255;   
  53.         PortData = 0xFF;   
  54.         while(j--)   
  55.         {   
  56.             if(PortData == ucDataBuffer[i])   
  57.                 break;   
  58.         }   
  59.         nStartingAddress++;    
  60.     }    
  61.     AT89C5X_EndOpt();   
  62. }   


回复楼主
第1楼 作者:强强  发表时间:2010-8-24 20:41:06

太帅了,谢谢分享


回复楼主    回复第1楼

 
 
本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4