找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1076|回复: 6
打印 上一主题 下一主题
收起左侧

单片机串口程序问题

[复制链接]
回帖奖励 10 黑币 回复本帖可获得 10 黑币奖励! 每人限 1 次
跳转到指定楼层
楼主
ID:827580 发表于 2020-12-10 09:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我想实现的功能是,当我的按键状态发生改变时,串口向上位机串口软件发送自己的MCU序列号,加一串序列号。比如按键当前是高电平,就发送一次MCU序列号➕字符串1,按键当前低电平,就发送一次MCU序列号➕字符串2,目前单片机序列号也获取到了,序列号是7个16进制数(0x01  0x02  0x03 0x04 0x05 0x06 0x07)类似这样的,目前一上电它一直在持续发送,按下按键换一个继续一直发送,哪位大佬帮我改一下,只有状态发生改变的时候发送一次。而且十六进制的怎么跟字符串连接在一起,目前接受到的是乱码,怎么能让串口接收到的是0x01 0x02 0x03 0x04 0x05 0x06 0x07 手环已连接或者0x01 0x02 0x03 0x04 0x05 0x06 0x07 手环已断开

单片机源程序如下:
  1. #include <reg52.h>
  2. #define jingzhen    11059200UL                         //使用110.592M晶体*/         
  3. #define botelv   9600UL                             //波特率定义为9600*/
  4. unsigned char zifuchuan1[]="静电腕已连接";                                                //待显示字符。
  5. unsigned char zifuchuan2[]="静电腕带未按规定佩戴,请检查连接性";                        //待显示字符。
  6. volatile unsigned char sending;
  7. sbit K2=P3^4;           //信号输入脚
  8. sbit SPK=P0^0;     //定义喇叭端口
  9. sbit LED1=P0^1;    //定义灯光接口
  10. sbit LED2=P0^2;           //状态扫描指示灯
  11. sbit LED3=P0^3;           //连接正常指示灯
  12. unsigned char frq;
  13. unsigned char key_flag = 0;            //接入状态标志位
  14. void DelayUs2x(unsigned char t);//延时函数声明
  15. void DelayMs(unsigned char t);        //延时函数声明
  16. void BEEP(unsigned char i);            //声光提示
  17. void sendc(unsigned char * pd);        //字符发送函数声明
  18. void SHANSHUO(unsigned char i);        //接入情况扫描运行状态指示
  19. unsigned char id_data[7];//存放MCU的真实序列号
  20. void sendMCUID(unsigned char idata *id_add);
  21. //***************************************************************//        延时函数
  22. void delay(unsigned char i)
  23. {
  24.         unsigned char j,k;
  25.         for(j=i;j>0;j--)
  26.                 for(k=90;k>0;k--);
  27. }
  28. /*******************************************************************/
  29. void read_save_ID()                  //读取、MCU真实序列号
  30. {
  31.    unsigned char idata *id_add; //在idata中定义指针变量id_add
  32.    unsigned char i = 0;
  33.    unsigned char j = 0;
  34.        id_add = 0xF1; //指针变量赋初值,0xF1为序列号第一个字节的指针
  35.        for(j=0;j<7;j++)           //通过7次循环将序列号7个字节转存至数组
  36.            {
  37.         i = *id_add;
  38.         id_data[j] = i;
  39.         id_add++;
  40.         }
  41. }
  42. //***************************************************************//键盘扫描函数
  43. void key_scan()
  44. {
  45.      SHANSHUO();
  46.          if(K2==1)
  47.           {
  48.                DelayMs(500);
  49.         //           sendMCUID(id_data);
  50.                    sendc(zifuchuan2);       
  51.                    BEEP();       
  52.                    DelayMs(500);
  53.                    DelayMs(500);            
  54.                 }
  55.       else if(K2!=1)
  56.           {
  57.               DelayMs(500);
  58.         //          sendMCUID(id_data);
  59.               sendc(zifuchuan1);
  60.                   LED3=0;
  61.                   DelayMs(500);
  62.                   DelayMs(500);
  63.           }
  64. }
  65. //*****************************************************************//串口初始化函数
  66. void init(void)                                //串口初始化
  67. {
  68. EA=0; //暂时关闭中断
  69. TMOD&=0x0F;  //定时器1模式控制在高4位
  70. TMOD|=0x20;    //定时器1工作在模式2,自动重装模式
  71. SCON=0x50;     //串口工作在模式1
  72. TH0 = 0x0FF;
  73. TL0 = 0x9C;
  74. TH1=256-jingzhen/(botelv*12*16);  //计算定时器重装值
  75. TL1=256-jingzhen/(botelv*12*16);
  76. PCON|=0x80;    //串口波特率加倍
  77. ES=1;         //串行中断允许
  78. TR1=1;        //启动定时器1
  79. REN=1;        //允许接收
  80. EA=1;         //允许中断
  81. TI=1;
  82. LED3=1;
  83. key_scan();
  84. }
  85. //**********************************************************************************//字节发送函数
  86. void send(unsigned char d)                  //发送一个字节的数据,形参d即为待发送数据。
  87. {

  88. SBUF=d; //将数据写入到串口缓冲
  89. sending=1;         //设置发送标志
  90. while(sending); //等待发送完毕
  91. }
  92. //*********************************************************************************//字符串发送函数
  93. void BEEP(unsigned char i)
  94. {
  95.    for(i=0;i<200;i++)
  96.           {
  97.             DelayUs2x(200);
  98.                 DelayUs2x(200);
  99.                 SPK=!SPK;
  100.                 LED1=!LED1;
  101.               }
  102.        for(i=0;i<200;i++)
  103.           {
  104.              DelayMs(1);  
  105.                  SPK=!SPK;
  106.                  LED1=!LED1;
  107.           }
  108. }
  109. /******************************************************************************************/
  110. void SHANSHUO(unsigned char i)
  111. {   
  112.     LED2=0;
  113.         DelayUs2x(2000);
  114.         LED2=1;
  115.         }
  116. /*****************************************************************************************/
  117. void sendc(unsigned char * pd)
  118. {
  119. while((*pd)!='\0') //发送字符串,直到遇到0才结束
  120. {
  121.   send(*pd); //发送一个字符
  122.   pd++;  //移动到下一个字符
  123. }
  124. }
  125. /*****************************************************************************************/
  126. void sendMCUID(unsigned char idata *id_add)
  127. {
  128. while((*id_add)!='\0') //发送字符串,直到遇到0才结束
  129. {
  130.   DelayMs(500);
  131.   DelayMs(500);
  132.   send(*id_add); //发送一个字符
  133.   DelayMs(500);
  134.   DelayMs(500);
  135.   id_add++;  //移动到下一个字符
  136. }
  137. }
  138. //************************************************************************************//主函数
  139. void main()
  140. {
  141.     while(1)
  142.         {
  143.        init();       
  144.         }         
  145.    }


  146.                      
  147. void DelayUs2x(unsigned char t)
  148. {   
  149. while(--t);
  150. }

  151. void DelayMs(unsigned char t)
  152. {
  153.      
  154. while(t--)
  155. {
  156.      //大致延时1mS
  157.      DelayUs2x(245);
  158.          DelayUs2x(245);
  159. }
  160. }

  161. void uart(void) interrupt 4                 //串口发送中断
  162. {

  163. if(RI)    //收到数据
  164. {
  165.   RI=0;   //清中断请求
  166. }
  167. else      //发送完一字节数据
  168. {
  169.   TI=0;
  170.   sending=0;  //清正在发送标志
  171. }
  172. }
复制代码

1.zip

26.96 KB, 下载次数: 7

源码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:827580 发表于 2020-12-10 10:00 | 只看该作者
帮解决此问题,30元MONEY,此话算数
回复

使用道具 举报

板凳
ID:276663 发表于 2020-12-10 12:39 | 只看该作者
做个标志位,发送过后就不再发了。
回复

使用道具 举报

地板
ID:858078 发表于 2020-12-10 14:05 | 只看该作者
"怎么能让串口接收到的是0x01 0x02 0x03 0x04 0x05 0x06 0x07",
将16进制数转成hex string格式输出
回复

使用道具 举报

5#
ID:216962 发表于 2020-12-10 14:25 | 只看该作者
一楼正解。。
回复

使用道具 举报

6#
ID:358620 发表于 2020-12-10 17:17 | 只看该作者
你好,你板子一上电按键就两个状态,要么是高电平要么是低电平,每次按键扫描就发送一次,所以是一直发送,增加两个标志位,High_Flag,Low_Flag,检测按键是高电平的时候High_Flag=1,Low_Flag=0检测到低电平的时候反过来,在发送哪里只需判断一下就OK了,这个就可以实现状态改变一次发送一次
回复

使用道具 举报

7#
ID:827580 发表于 2020-12-11 08:58 | 只看该作者
lihaifeng_avr@1 发表于 2020-12-10 17:17
你好,你板子一上电按键就两个状态,要么是高电平要么是低电平,每次按键扫描就发送一次,所以是一直发送, ...

收到!谢谢!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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