欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 625|回復: 3
打印 上一主題 下一主題
收起左側

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,則整個代碼正常運行,請大佬賜教!。!
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1073939 發表于 2026-1-24 16:37 | 只看該作者
  1.         if(rec_data == '\r' || rec_data == '\n')
  2.         {
  3.                 recv_buf[recv_index] = '\0'; // 補充字符串結束符
  4.                 recv_complete = 1;           // 置接收完成標志
  5.                 recv_index = 0;              // 重置索引,準備下次接收
  6.         }
復制代碼


問題可能在這,收到'\n'后,緩沖區為"\0j\0"
回復

使用道具 舉報

板凳
ID:1073939 發表于 2026-1-24 17:03 | 只看該作者
感覺串口發送沒必要超時容錯。發送失敗就只和你mcu配置不對相關,和其它無關。這個錯誤是必須處理的,容錯反而不好。串口發送部分建議用keil官方代碼。
  1. char putchar (char c)
  2. {
  3.         while (!TI);
  4.         TI = 0;
  5.         SBUF = c;
  6.         return (c);
  7. }
  8. #define uart_send_byte putchar
  9. void uart_send_string(char *str)
  10. {
  11.         while (*str != '\0') // 遍歷到字符串結束符'\0'為止
  12.         {
  13.                 uart_send_byte(*str++); // 逐字節發送
  14.         }
  15. }
復制代碼
回復

使用道具 舉報

地板
ID:1073939 發表于 2026-1-24 17:24 | 只看該作者
ydatou 發表于 2026-1-24 16:37
問題可能在這,收到'\n'后,緩沖區為"\0j\0"

可以先判斷recv_complete再處理接受字符。
也可以收到結束符時,如ecv_index為0丟棄,否則存入緩存。
  1. void uart_init(u8 baud_mode)
  2. {
  3.         TMOD |= 0X20; // 定時器1模式2(8位自動重裝)
  4.         SCON = 0X50;  // 串口模式1,允許接收
  5.         PCON = 0X00;  // SMOD=0,降低波特率誤差
  6.         if (baud_mode == 0)
  7.         {
  8.                 TH1 = 0XFD; // 11.0592MHz → 9600
  9.                 TL1 = 0XFD;
  10.         }
  11.         else
  12.         {
  13.                 TH1 = 0X66; // 12MHz → 9600
  14.                 TL1 = 0X66;
  15.         }
  16.         ES = 1;                        // 開啟串口中斷
  17.         EA = 1;                        // 開啟總中斷
  18.         TR1 = 1;                // 啟動定時器1
  19.         delay_10us(10); // 串口就緒延時
  20. }

  21. char putchar(char c)
  22. {
  23.         while (!TI)
  24.                 ;
  25.         TI = 0;
  26.         SBUF = c;
  27.         return (c);
  28. }
  29. #define uart_send_byte putchar
  30. void uart_send_string(char *str)
  31. {
  32.         while (*str != '\0') // 遍歷到字符串結束符'\0'為止
  33.         {
  34.                 uart_send_byte(*str++); // 逐字節發送
  35.         }
  36. }

  37. // 串口中斷函數:接收字符串(逐字節緩存,帶結束符判斷)
  38. void uart() interrupt 4
  39. {
  40.         u8 rec_data = 0;
  41.         if (RI)
  42.         {                        // 僅處理接收中斷
  43.                 RI = 0; // 清除接收標志
  44.                 if (recv_complete)
  45.                         return;
  46.                 rec_data = SBUF; // 讀取當前字節
  47.                 // 1. 結束符判斷(回車/換行視為字符串結束)
  48.                 if (rec_data == '\r' || rec_data == '\n')
  49.                 {
  50.                         if (recv_index)
  51.                         {
  52.                                 recv_buf[recv_index] = '\0'; // 補充字符串結束符
  53.                                 recv_complete = 1;                         // 置接收完成標志
  54.                                 recv_index = 0;                                 // 重置索引,準備下次接收
  55.                         }
  56.                 }
  57.                 // 2. 未到結束符且緩存未溢出 → 緩存字節
  58.                 else if (recv_index < RECV_BUF_LEN - 1) // 留1位存'\0'
  59.                 {
  60.                         recv_buf[recv_index] = rec_data;
  61.                         recv_index++; // 索引自增
  62.                 }
  63.                 // 3. 緩存溢出 → 重置(防程序異常)
  64.                 else
  65.                 {
  66.                         recv_index = 0;
  67.                 }
  68.         }
  69. }
復制代碼

你這代碼比較大的問題是收到的字符串處理期間,不能正常接收字符串。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表