51单片机串口接收的数据

2019-07-15 13:28发布

背景:本人做材料,通过光控制反应。要求有一个周期可调的光源,通过串口发送数据,并计算出周期
硬件:STC4052AD 12M晶振
思想:LED初始频闪周期1000 ms,通过串口接收2位数,改变频闪周期, 串口第一个是数值,第二位是数量级,例如52表示5*10^2 mstime[2]存储这两位数字。当接收2次数据后,计算2个数据代表的周期。
软件现象:串口调试助手发送数据和接收的数据对不上号。
硬件现象:起初黑暗1s,亮1s,当使用串口发送数据时,要么频率特别高(常亮),要么长不亮(等好久才切换状态)

求助高手,帮忙修改一下程序

串口调试助手截图

代码如下
  1. /*********************************************************************************************
  2. ?
  3. 硬件支持:  STC12C2052AD 外部12MHZ晶振
  4. 接口说明:  连接串口ISP下载线                                                                 
  5. 流程说明:LED初始频闪周期1000 ms,通过串口接收2位数,改变频闪周期
  6. 串口第一个是数值,第二位是数量级,例如52表示5*10^2 ms,time[2]存储这两位数字。


  7. /*********************************************************************************************/


  8. #include <STC12C2052AD.H>

  9. //定义变量
  10. unsigned char time[2]={1,3};//初始频闪周期1000 *2 ms
  11. unsigned int delaytime=1000;//初始频闪周期1000 *2 ms
  12. unsigned int wei=0;//数据接收标志位
  13. unsigned int flag=0; //重新计算标志位
  14. //当wei=1时,说明接收了2个数字,此时flag变成1,主程序中判断flag是否等于1 判断是否从串口接收了2
  15. //位数字,若是,则计算接收的数字代表的周期
  16. unsigned int number;

  17. sbit LED=P1^0;                //频闪灯

  18. /*********************************************************************************************
  19. 函数名:UART串口初始化函数
  20. 调  用:UART_init();
  21. 参  数:无
  22. 返回值:无
  23. 结  果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)
  24. 备  注:振荡晶体为12MHz,PC串口端设置 [ 4800,8,无,1,无 ]
  25. /**********************************************************************************************/
  26. void UART_init (void){
  27.         EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
  28.         ES = 1; //允许UART串口的中断

  29.         TMOD = 0x20;        //定时器T/C1工作方式2
  30.         SCON = 0x50;        //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
  31.         TH1 = 0xF3;        //定时器初值高8位设置
  32.         TL1 = 0xF3;        //定时器初值低8位设置
  33.         PCON = 0x80;        //波特率倍频(屏蔽本句波特率为2400)
  34.         TR1 = 1;        //定时器启动   
  35. }
  36. /**********************************************************************************************/

  37. /*********************************************************************************************
  38. 函数名:UART串口接收中断处理函数
  39. 调  用:[SBUF收到数据后中断处理]
  40. 参  数:无
  41. 返回值:无
  42. 结  果:
  43. 备  注:
  44. /**********************************************************************************************/
  45. void UART_R (void) interrupt 4  using 1{ //切换寄存器组到1

  46.         RI = 0;                        //令接收中断标志位为0(软件清零)
  47.         time[wei]= SBUF;        //第一次收到数据放到 time[0]中,第二次收到数据放到 time[1]中,
  48.         if(wei){                //当wei=1,则说明接收到1组数据
  49.         flag=1;                        //此时计算标志位置1,在主程序中重新计算时间
  50.                 }
  51.        
  52.         SBUF =time[wei] ;        //将接收的数据发送回去查看接收是否正确
  53.         wei=~wei;                        //改变下一次存储位置 time[0]到 time[1],或 time[1]到 time[0]
  54.         while(TI == 0);        //检查发送中断标志位
  55.         TI = 0;                //令发送中断标志位为0(软件清零)
  56. }       
  57. /**********************************************************************************************/


  58. /*********************************************************************************************/
  59. /*********************************************************************************************
  60. 函数名:毫秒级CPU延时函数
  61. 调  用:DELAY_MS (?);
  62. 参  数:1~65535(参数不可为0)
  63. 返回值:无
  64. 结  果:占用CPU方式延时与参数数值相同的毫秒时间
  65. 备  注:应用于1T单片机时i<600,应用于12T单片机时i<125
  66. /*********************************************************************************************/
  67. void DELAY_MS (unsigned int a){
  68.         unsigned int i;
  69.         while( a-- != 0){
  70.                 for(i = 0; i < 600; i++);
  71.         }
  72. }
  73. /*********************************************************************************************/
  74. /*********************************************************************************************
  75. 计算延时时间
  76. time[1]是多少,就乘以多少遍10
  77. /**********************************************************************************************/
  78. unsigned int daleycount(void){
  79. unsigned int a;
  80.                 a=1;
  81.                 while(time[1]--!=0){
  82.                 a=a*10;
  83.                 }
  84.        
  85.                 number=time[0]*a;
  86.                 return number;        //当wei=1,改变定时时间       
  87.                
  88. }
  89. /*********************************************************************************************
  90. 函数名:主函数
  91. 调  用:无
  92. 参  数:无
  93. 返回值:无
  94. 结  果:读取串口值,赋值给延时函数
  95. 备  注:
  96. /**********************************************************************************************/
  97. void main (void){

  98.         UART_init();                                //串口初始化
  99.         while(1){
  100.                 if(flag){                                //判断是否需要计算时间
  101.                 delaytime=daleycount(); //计算时间
  102.                 flag=0;                                        //等待下一次改变
  103.                 }

  104.                 LED=~LED;
  105.                 DELAY_MS(delaytime);                //延时


  106.         }
  107. }
  108. /**********************************************************************************************/
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
chenwei6991627
1楼-- · 2019-07-15 15:44
串口调试的时候用HEX方式就可以了
陈晨的电子
2楼-- · 2019-07-15 20:45
好好好好好好好好好好好好哈好好好阿红阿红
陈晨的电子
3楼-- · 2019-07-15 23:03
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
janerzhang
4楼-- · 2019-07-15 23:29
现在解决了吗,我也在看这个程序改了下,,调试你的,发的跟接受的一样,开始闪得快,后来在发的时候就敞亮了
hoddescle
5楼-- · 2019-07-16 01:15
 精彩回答 2  元偷偷看……

一周热门 更多>