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

標(biāo)題: 51單片機(jī)串口通信,發(fā)送字符串回顯不全 [打印本頁]

作者: 規(guī)劃胡    時(shí)間: 2026-1-22 20:27
標(biāo)題: 51單片機(jī)串口通信,發(fā)送字符串回顯不全
  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;         // 接收索引(記錄當(dāng)前緩存位置)
  9. //bit recv_complete = 0;     // 字符串接收完成標(biāo)志
  10. bit recv_complete;
  11. // ===========================================================

  12. // 10us延時(shí)函數(shù)
  13. void delay_10us(u16 ten_us)
  14. {
  15.         while(ten_us--);       
  16. }

  17. // ms延時(shí)函數(shù)(兼容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;   // 定時(shí)器1模式2(8位自動(dòng)重裝)
  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;        // 啟動(dòng)定時(shí)器1
  43.         delay_10us(10); // 串口就緒延時(shí)
  44. }

  45. // 串口發(fā)送單個(gè)字節(jié)(帶超時(shí)容錯(cuò))

  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. // 串口發(fā)送字符串(傳入字符串首地址)
  59. void uart_send_string(u8 *str)
  60. {
  61.         while(*str != '\0') // 遍歷到字符串結(jié)束符'\0'為止
  62.         {
  63.                 uart_send_byte(*str); // 逐字節(jié)發(fā)送
  64.                 str++;                // 指針后移
  65.                 delay_10us(1);
  66.         }
  67. }
  68. // 串口中斷函數(shù):接收字符串(逐字節(jié)緩存,帶結(jié)束符判斷)
  69. void uart() interrupt 4
  70. {
  71.         u8 rec_data = 0;
  72.     if (RI) {          // 僅處理接收中斷
  73.         RI = 0;        // 清除接收標(biāo)志
  74.         rec_data = SBUF;  // 讀取當(dāng)前字節(jié)
  75.         
  76.         // 1. 結(jié)束符判斷(回車/換行視為字符串結(jié)束)
  77.         if(rec_data == '\r' || rec_data == '\n')
  78.         {
  79.                 recv_buf[recv_index] = '\0'; // 補(bǔ)充字符串結(jié)束符
  80.                 recv_complete = 1;           // 置接收完成標(biāo)志
  81.                 recv_index = 0;              // 重置索引,準(zhǔn)備下次接收
  82.         }
  83.         // 2. 未到結(jié)束符且緩存未溢出 → 緩存字節(jié)
  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; // 主動(dòng)發(fā)送的單個(gè)字符(數(shù)字0)
  99.         uart_init(0);   // 11.0592MHz傳0,12MHz傳1
  100.         delay_ms(100);  // 初始化就緒延時(shí)
  101.         memset(recv_buf, 0, RECV_BUF_LEN);
  102.        
  103.         while(1)
  104.         {
  105.                 // 1. 主動(dòng)定時(shí)發(fā)送單個(gè)字符(保留原有功能)
  106.                 //uart_send_byte(send_data);
  107.                 //delay_ms(100);
  108.                
  109.                 // 2. 檢測到字符串接收完成 → 回發(fā)該字符串
  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;          // 清除完成標(biāo)志
  122.                         recv_index = 0;               
  123.                         memset(recv_buf, 0, RECV_BUF_LEN);
  124.                        
  125.                 }
  126.         }       
  127. }
復(fù)制代碼

發(fā)送jj和發(fā)送加回車換行,uart_send_string(recv_buf);無法正常運(yùn)行,但是取消串口助手的勾選加回車換行,輸入jj\0\n,則整個(gè)代碼正常運(yùn)行,請大佬賜教!!!!
作者: ydatou    時(shí)間: 2026-1-24 16:37
  1.         if(rec_data == '\r' || rec_data == '\n')
  2.         {
  3.                 recv_buf[recv_index] = '\0'; // 補(bǔ)充字符串結(jié)束符
  4.                 recv_complete = 1;           // 置接收完成標(biāo)志
  5.                 recv_index = 0;              // 重置索引,準(zhǔn)備下次接收
  6.         }
復(fù)制代碼


問題可能在這,收到'\n'后,緩沖區(qū)為"\0j\0"
作者: ydatou    時(shí)間: 2026-1-24 17:03
感覺串口發(fā)送沒必要超時(shí)容錯(cuò)。發(fā)送失敗就只和你mcu配置不對相關(guān),和其它無關(guān)。這個(gè)錯(cuò)誤是必須處理的,容錯(cuò)反而不好。串口發(fā)送部分建議用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') // 遍歷到字符串結(jié)束符'\0'為止
  12.         {
  13.                 uart_send_byte(*str++); // 逐字節(jié)發(fā)送
  14.         }
  15. }
復(fù)制代碼

作者: ydatou    時(shí)間: 2026-1-24 17:24
ydatou 發(fā)表于 2026-1-24 16:37
問題可能在這,收到'\n'后,緩沖區(qū)為"\0j\0"

可以先判斷recv_complete再處理接受字符。
也可以收到結(jié)束符時(shí),如ecv_index為0丟棄,否則存入緩存。
  1. void uart_init(u8 baud_mode)
  2. {
  3.         TMOD |= 0X20; // 定時(shí)器1模式2(8位自動(dòng)重裝)
  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;                // 啟動(dòng)定時(shí)器1
  19.         delay_10us(10); // 串口就緒延時(shí)
  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') // 遍歷到字符串結(jié)束符'\0'為止
  33.         {
  34.                 uart_send_byte(*str++); // 逐字節(jié)發(fā)送
  35.         }
  36. }

  37. // 串口中斷函數(shù):接收字符串(逐字節(jié)緩存,帶結(jié)束符判斷)
  38. void uart() interrupt 4
  39. {
  40.         u8 rec_data = 0;
  41.         if (RI)
  42.         {                        // 僅處理接收中斷
  43.                 RI = 0; // 清除接收標(biāo)志
  44.                 if (recv_complete)
  45.                         return;
  46.                 rec_data = SBUF; // 讀取當(dāng)前字節(jié)
  47.                 // 1. 結(jié)束符判斷(回車/換行視為字符串結(jié)束)
  48.                 if (rec_data == '\r' || rec_data == '\n')
  49.                 {
  50.                         if (recv_index)
  51.                         {
  52.                                 recv_buf[recv_index] = '\0'; // 補(bǔ)充字符串結(jié)束符
  53.                                 recv_complete = 1;                         // 置接收完成標(biāo)志
  54.                                 recv_index = 0;                                 // 重置索引,準(zhǔn)備下次接收
  55.                         }
  56.                 }
  57.                 // 2. 未到結(jié)束符且緩存未溢出 → 緩存字節(jié)
  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. }
復(fù)制代碼

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




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1