找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1893|回复: 6
收起左侧

C51单片机串口调试求助

[复制链接]
ID:188773 发表于 2020-5-23 16:34 | 显示全部楼层 |阅读模式
  目前在学习串口收发数据,目的是接收命令,根据命令修改数组内的值并发送出去,主要有下面两个疑问
  1、串口调试有没有好的方法可以在线仿真,能够看到变量值的每步变化,我尝试用了proteus仿真,串口调试助手发送数据,程序进不了串口中断;
  2、我写了下面一段程序,tmp[]数组接收的是串口调试助手发来的命令ASCII码。红色这句修改数组的值出了问题,接收到的ASCII码0-b转换成16进制的0-11,作为数组的下标赋值给b,接收到的ASCII码1 、2、4、8转换成16进制(tmp[2]-0x30),赋值给数组buzzer_value ''。但是实际每次buzzer_value ''都为0X00;后面发送的b 、(tmp[2]-0x30)的值又是对的,不知道中间有什么问题。 我尝试把b改成数字下标或者把tmp[2]-0x30改成具体的十六进制数,结果都是对的。

                                        if((tmp[1]>='0')&&(tmp[1]<='9'))
                                          b=tmp[1]-0X30;
                                        else
                                          b=tmp[1]-0X51;
                                        buzzer_value  '[   b   ]'=(tmp[2]-0x30);

                                        a=0;
                                        while(a<12)
                                        {
                                                SBUF = buzzer_value[a];                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
                                                while(!TI);                                // 等特数据传送        (TI发送中断标志)
                                                TI = 0;                                        // 清除数据传送标志
                                                a++;                                            // 下一个字符         
                                        }
                                SBUF = b;                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
                                                while(!TI);                                // 等特数据传送        (TI发送中断标志)
                                                TI = 0;                                        // 清除数据传送标志        
                                SBUF = tmp[2]-0X30;                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
                                                while(!TI);                                // 等特数据传送        (TI发送中断标志)
                                                TI = 0;                                        // 清除数据传送标志        
                                int_tmp();
                                b=0;                                
回复

使用道具 举报

ID:188773 发表于 2020-5-23 16:39 | 显示全部楼层
发帖出来的buzzer_value  '[   b   ]'不加引号不能显示[]和里面的b
回复

使用道具 举报

ID:188773 发表于 2020-5-23 21:00 | 显示全部楼层
本帖最后由 guan1989 于 2020-5-23 21:02 编辑




  1. //串口通讯实验  
  2. //这里写好程序 下载到单片机里
  3. //直接 用下载软件的串口助手   以16进制 发送 8A  会接收到  我爱单片机
  4. //此程序虽然很少 但是它有着串口通讯和接收的所有功能  
  5. //需要用串口的朋友只要用它改改就可以实现自己想要的效果



  6. #include "stc8.h"

  7. unsigned char data  key_value[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //实时存储按键按下标志位:LED1,LED2,LED3...LED10,test,mute,,LED_ALARM,buzzer;用于显示和通讯
  8. unsigned char data  key_alarm[12]={1,1,1,1,1,1,1,1,1,1,1,1}; //按键按下是否生效标志位:LED1,LED2,...lLED10,test,mute               
  9. unsigned char data  buzzer_value[12]={1,1,2,4,8,1,1,1,1,1,1,1};//1表示2秒1鸣,2表示1秒1鸣、4表示1秒2鸣、8表示长鸣                         

  10. /*
  11. 命令A11,表示key_alarm[0]=1;A10,表示key_alarm[0]=0;返回key_alarm[12]
  12. 命令B11,表示buzzer_value[1]=1;B10,表示buzzer_value[1]=0;返回buzzer_value[12]
  13. 命令KEY,返回key_value[14]

  14. */
  15. unsigned char tmp[4];        //存储接收到的值;
  16. unsigned char ucreceive_num=0;


  17. void main()
  18. {
  19.   //  P3M0 |= 0x03 ;
  20.         //        P3M1 &=0xfc ;                //uart1推挽输出,需限流电阻
  21.                  SCON |= 0x50;       //REN=1允许串行接受状态,串口工作模式2               
  22.            TMOD= 0x20;      //定时器工作方式2       8位 自动重装载定时器  实现波特率               
  23.            AUXR=0X40;                 //开启1T模式   
  24.            TH1 =TL1= 0xDC;                        //  设置波特率为9600  公式 TH1=256-(11059200/32/9600)=256-36=220  0xDC
  25.                                                                                                         //  设置波特率为9600  公式 TH1=256-(22118400/32/9600)=256-72=184  0xB8
  26.                               // 如有不明白请查 STC8手册上有详细说明
  27.       
  28.        
  29.                 TR1  = 1;        //开启定时器1                                                      
  30.                 ES   = 1;        //开串口中断                  
  31.                 EA   = 1;        // 开总中断
  32.        
  33.                 while(1)
  34.                 {
  35.                        
  36.                 }

  37. }

  38. /***********************************************
  39. *函数名称:Uart1_SendChar
  40. *功    能:串口1发送单个字符函数
  41. *入口参数:Udat:欲发送的数据
  42. *返 回 值:无       
  43. *备    注:无
  44. ************************************************/
  45. void int_tmp()
  46. {
  47.         ucreceive_num=0;
  48.         tmp[0]=0x00;
  49.         tmp[1]=0x00;
  50.         tmp[2]=0x00;
  51. }

  52. /***********************************************
  53. *函数名称:Uart1_SendChar
  54. *功    能:串口1发送单个字符函数
  55. *入口参数:Udat:欲发送的数据
  56. *返 回 值:无       
  57. *备    注:无
  58. ************************************************/
  59. void ISP_Check()
  60. {
  61.                 unsigned char a;
  62.                 unsigned char c;
  63.                 switch(tmp[0])
  64.                 {
  65.                         case 'K' :
  66.                         if((tmp[1]=='E')&&(tmp[2]=='Y'))
  67.                         {
  68.                                 ES= 0;
  69.                                 a=0;
  70.                                 while(a<14)
  71.                                 {
  72.                                         SBUF = key_value[a];                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
  73.                                         while(!TI);                                // 等特数据传送        (TI发送中断标志)
  74.                                         TI = 0;                                        // 清除数据传送标志
  75.                                         a++;                                            // 下一个字符
  76.                                 }       
  77.                         int_tmp();
  78.                         }
  79.                         break;
  80.                        
  81.                         case 'A'        :
  82.                                 if(        (        ((tmp[1]>='0')&&(tmp[1]<='9'))        ||        ((tmp[1]>='a')&&(tmp[1]<='b'))        ) &&( (tmp[2]=='0') || (tmp[2]=='1')  ))
  83.                                 {
  84.                                         ES= 0;
  85.                                         if((tmp[1]>='0')&&(tmp[1]<='9'))
  86.                                                 c=tmp[1]-0X30;
  87.                                         else
  88.                                                 c=tmp[1]-0X51;
  89.                                         key_alarm[c] = (tmp[2]-0x30);
  90.                                         a=0;
  91.                                         while(a<12)
  92.                                         {
  93.                                                 SBUF = key_alarm[a];                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
  94.                                                 while(!TI);                                // 等特数据传送        (TI发送中断标志)
  95.                                                 TI = 0;                                        // 清除数据传送标志
  96.                                                 a++;                                            // 下一个字符
  97.                                         }
  98.                                 SBUF = c;                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
  99.                                                 while(!TI);                                // 等特数据传送        (TI发送中断标志)
  100.                                                 TI = 0;                                        // 清除数据传送标志       
  101.                                 SBUF = tmp[2]-0x30;                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
  102.                                                 while(!TI);                                // 等特数据传送        (TI发送中断标志)
  103.                                                 TI = 0;                                        // 清除数据传送标志
  104.                                         int_tmp();
  105.                                 }
  106.                                 break;
  107.                        
  108.                         case 'B' :
  109.                                 if(        (        ((tmp[1]>='0')&&(tmp[1]<='9'))        ||        ((tmp[1]>='a')&&(tmp[1]<='b'))        ) &&( (tmp[2]=='1') || (tmp[2]=='2') ||(tmp[2]=='4') ||(tmp[2]=='8') ))
  110.                                 {
  111.                                         ES= 0;
  112.                                         if((tmp[1]>='0')&&(tmp[1]<='9'))
  113.                                                 c=tmp[1]-0X30;
  114.                                         else
  115.                                                 c=tmp[1]-0X51;
  116.                                         buzzer_value[c] = (tmp[2]-0x30);
  117.                                         a=0;
  118.                                         while(a<12)
  119.                                         {
  120.                                                 SBUF = buzzer_value[a];                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
  121.                                                 while(!TI);                                // 等特数据传送        (TI发送中断标志)
  122.                                                 TI = 0;                                        // 清除数据传送标志
  123.                                                 a++;                                            // 下一个字符        
  124.                                         }
  125.                                 SBUF = c;                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
  126.                                                 while(!TI);                                // 等特数据传送        (TI发送中断标志)
  127.                                                 TI = 0;                                        // 清除数据传送标志       
  128.                                 SBUF = tmp[2]-0x30;                //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
  129.                                                 while(!TI);                                // 等特数据传送        (TI发送中断标志)
  130.                                                 TI = 0;                                        // 清除数据传送标志       
  131.                                 int_tmp();
  132.                                 c=0;                               
  133.                                 }
  134.                                 break;
  135.                                
  136.                         default :
  137.                                 ES=0;
  138.                                 int_tmp();
  139.                 }
  140.                 ES=1;               
  141. }               



  142. void Serial_int(void) interrupt 4 using 1
  143. {
  144.         if (RI)
  145.     {       
  146.                 tmp[ucreceive_num] = SBUF;
  147.                 ucreceive_num++;
  148.                 ISP_Check();
  149.                 if(ucreceive_num==3)
  150.                 int_tmp();
  151.                 RI = 0;       
  152.     }
  153. }  
复制代码

源代码见附件
回复

使用道具 举报

ID:213173 发表于 2020-5-24 07:51 | 显示全部楼层
楼主这不是串口通讯问题,是数据解析问题。
回复

使用道具 举报

ID:188773 发表于 2020-5-24 16:05 | 显示全部楼层
wulin 发表于 2020-5-24 07:51
楼主这不是串口通讯问题,是数据解析问题。

死活找不到原因
回复

使用道具 举报

ID:188773 发表于 2020-5-24 16:16 | 显示全部楼层
wulin 发表于 2020-5-24 07:51
楼主这不是串口通讯问题,是数据解析问题。

请问有什么方向的解决思路
回复

使用道具 举报

ID:188773 发表于 2020-5-24 16:50 | 显示全部楼层
wulin 发表于 2020-5-24 07:51
楼主这不是串口通讯问题,是数据解析问题。
  1. if((tmp[1]>='0')&&(tmp[1]<='9'))
  2.                                           b=tmp[1]-0X30;
  3.                                         else
  4.                                           b=tmp[1]-0X51;
  5.                                         buzzer_value  '[   b   ]'=(tmp[2]-0x30);
复制代码
我把上面一段修改了下,如下图。buzzer_value '[ b ]'=(tmp[2]-0x30);这一句分解成了case,结果是正确的,但是原理不是很懂,是不是编译器的编译过程有问题。
  1.                                 {
  2.                                         ES= 0;
  3.                                         if((tmp[1]>='0')&&(tmp[1]<='9'))
  4.                                         {
  5.                                                 switch(tmp[2])
  6.                                                 {
  7.                                                         case'1':buzzer_value[tmp[1]-0X30] =1;break;
  8.                                                         case'2':buzzer_value[tmp[1]-0X30] =2;break;
  9.                                                         case'4':buzzer_value[tmp[1]-0X30] =4;break;
  10.                                                         case'8':buzzer_value[tmp[1]-0X30] =8;break;
  11.                                                 }
  12.                                         }
  13.                                         else                               
  14.                                         {                                               
  15.                                                 switch(tmp[2])
  16.                                                 {
  17.                                                         case'1':buzzer_value[tmp[1]-0X57] =1;break;
  18.                                                         case'2':buzzer_value[tmp[1]-0X57] =2;break;
  19.                                                         case'4':buzzer_value[tmp[1]-0X57] =4;break;
  20.                                                         case'8':buzzer_value[tmp[1]-0X57] =8;break;
  21.                                                 }
  22.                                         }       
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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