找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1|回复: 0
收起左侧

51单片机串口通信,发送字符串回显不全

[复制链接]
ID:842026 发表于 2026-1-22 20:27 | 显示全部楼层 |阅读模式
  1. #include "reg52.h"
  2. #include <string.h>
  3. typedef unsigned int u16;       
  4. typedef unsigned char u8;

  5. // ====================== 字符串接收配置 ======================
  6. #define RECV_BUF_LEN 32  // 接收缓存最大长度(可修改)
  7. u8 recv_buf[RECV_BUF_LEN]; // 字符串接收缓存
  8. u8 recv_index = 0;         // 接收索引(记录当前缓存位置)
  9. //bit recv_complete = 0;     // 字符串接收完成标志
  10. bit recv_complete;
  11. // ===========================================================

  12. // 10us延时函数
  13. void delay_10us(u16 ten_us)
  14. {
  15.         while(ten_us--);       
  16. }

  17. // ms延时函数(兼容11.0592/12MHz)
  18. void delay_ms(u16 m)
  19. {
  20.         u16 i, j;
  21.         for(i = m; i > 0; i--)      
  22.                 for(j = 115; j > 0; j--);
  23. }

  24. // 串口初始化:适配两种晶振的9600波特率
  25. void uart_init(u8 baud_mode)
  26. {                  
  27.         TMOD |= 0X20;   // 定时器1模式2(8位自动重装)
  28.         SCON = 0X50;    // 串口模式1,允许接收
  29.         PCON = 0X00;    // SMOD=0,降低波特率误差
  30.         if(baud_mode == 0)
  31.         {
  32.                 TH1 = 0XFD; // 11.0592MHz → 9600
  33.                 TL1 = 0XFD;
  34.         }
  35.         else
  36.         {
  37.                 TH1 = 0X66; // 12MHz → 9600
  38.                 TL1 = 0X66;
  39.         }
  40.         ES = 1;         // 开启串口中断
  41.         EA = 1;         // 开启总中断
  42.         TR1 = 1;        // 启动定时器1
  43.         delay_10us(10); // 串口就绪延时
  44. }

  45. // 串口发送单个字节(带超时容错)

  46. void uart_send_byte(u8 dat)
  47. {       
  48.         u16 timeout = 1000;
  49.         TI = 0;
  50.         SBUF = dat;        
  51.        
  52.         while(!TI && timeout--)
  53.         {
  54.                 delay_10us(1);
  55.         }        
  56.         TI = 0;            
  57. }

  58. // 串口发送字符串(传入字符串首地址)
  59. void uart_send_string(u8 *str)
  60. {
  61.         while(*str != '\0') // 遍历到字符串结束符'\0'为止
  62.         {
  63.                 uart_send_byte(*str); // 逐字节发送
  64.                 str++;                // 指针后移
  65.                 delay_10us(1);
  66.         }
  67. }
  68. // 串口中断函数:接收字符串(逐字节缓存,带结束符判断)
  69. void uart() interrupt 4
  70. {
  71.         u8 rec_data = 0;
  72.     if (RI) {          // 仅处理接收中断
  73.         RI = 0;        // 清除接收标志
  74.         rec_data = SBUF;  // 读取当前字节
  75.         
  76.         // 1. 结束符判断(回车/换行视为字符串结束)
  77.         if(rec_data == '\r' || rec_data == '\n')
  78.         {
  79.                 recv_buf[recv_index] = '\0'; // 补充字符串结束符
  80.                 recv_complete = 1;           // 置接收完成标志
  81.                 recv_index = 0;              // 重置索引,准备下次接收
  82.         }
  83.         // 2. 未到结束符且缓存未溢出 → 缓存字节
  84.         else if(recv_index < RECV_BUF_LEN - 1) // 留1位存'\0'
  85.         {
  86.                 recv_buf[recv_index] = rec_data;
  87.                 recv_index++; // 索引自增
  88.         }
  89.         // 3. 缓存溢出 → 重置(防程序异常)
  90.         else
  91.         {
  92.                 recv_index = 0;
  93.         }
  94.     }
  95. }

  96. void main()
  97. {
  98.         //u8 send_data = 0X30; // 主动发送的单个字符(数字0)
  99.         uart_init(0);   // 11.0592MHz传0,12MHz传1
  100.         delay_ms(100);  // 初始化就绪延时
  101.         memset(recv_buf, 0, RECV_BUF_LEN);
  102.        
  103.         while(1)
  104.         {
  105.                 // 1. 主动定时发送单个字符(保留原有功能)
  106.                 //uart_send_byte(send_data);
  107.                 //delay_ms(100);
  108.                
  109.                 // 2. 检测到字符串接收完成 → 回发该字符串
  110.                 if(recv_complete)
  111.                 {
  112.                         uart_send_string("收到字符串:"); // 提示语
  113.                        
  114.                         if(strcmp((char*)recv_buf, "jj") == 0)
  115.                         {       
  116.                                 uart_send_string(recv_buf);
  117.                                
  118.                         }
  119.                         uart_send_string("\r\n");
  120.                         delay_10us(1);
  121.                         recv_complete = 0;          // 清除完成标志
  122.                         recv_index = 0;               
  123.                         memset(recv_buf, 0, RECV_BUF_LEN);
  124.                        
  125.                 }
  126.         }       
  127. }
复制代码

发送jj和发送加回车换行,uart_send_string(recv_buf);无法正常运行,但是取消串口助手的勾选加回车换行,输入jj\0\n,则整个代码正常运行,请大佬赐教!!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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