找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1160|回復(fù): 8
收起左側(cè)

51單片機(jī)串口通信求助

[復(fù)制鏈接]
ID:962485 發(fā)表于 2024-4-20 15:13 | 顯示全部樓層 |閱讀模式
為何手動選擇數(shù)據(jù)不能發(fā)送,串口助手接收到的全是null或者亂碼,接收中斷返回來的又正確
#include "reg52.h"

typedef unsigned int u16;        //對系統(tǒng)默認(rèn)數(shù)據(jù)類型進(jìn)行重定義
typedef unsigned char u8;




void delay_1_second(void)
{
    unsigned int i, j;
    for (i = 0; i < 12000; i++) { // 假設(shè)每個大循環(huán)約耗時1ms
        for (j = 0; j < 120; j++) { // 這里是填充的小循環(huán),具體數(shù)量需要根據(jù)實(shí)際情況調(diào)整
            // 空循環(huán),用于消耗時間
        }
    }
}

/*******************************************************************************
* 函 數(shù) 名       : uart_init
* 函數(shù)功能                 : 串口通信中斷配置函數(shù),通過設(shè)置TH和TL即可確定定時時間
* 輸    入       : baud:波特率對應(yīng)的TH、TL裝載值
* 輸    出             : 無
*******************************************************************************/
void uart_init(void)
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位數(shù)據(jù),可變波特率
        TMOD &= 0x0F;                //清除定時器1模式位
        TMOD |= 0x20;                //設(shè)定定時器1為8位自動重裝方式
        TL1 = 0xFD;                        //設(shè)定定時初值
        TH1 = 0xFD;                        //設(shè)定定時器重裝值               
        TR1 = 1;                        //啟動定時器1
        ET1 = 0;                //禁止定時器1中斷
        EA=1;                                //開放總中斷
        ES=1;                                //開放串口中斷

}


// 發(fā)送單個字符的函數(shù)
void uart_send_char(u8 da1)
{
    while(TI); // 等待上次發(fā)送完成(通過檢查TI標(biāo)志)
    SBUF = da1; // 將字符放入發(fā)送緩沖區(qū)SBUF
          while(!TI);                //等待發(fā)送數(shù)據(jù)完成
          TI=0;                        //清除發(fā)送完成標(biāo)志位       
}

void uart_send_string(const char *str)
{
    while(*str) // 遍歷字符串直到遇到結(jié)束符'\0'
    {
        uart_send_char(*str++); // 發(fā)送當(dāng)前字符,并指向下一個字符
    }
}

/*******************************************************************************
* 函 數(shù) 名       : main
* 函數(shù)功能                 : 主函數(shù)
* 輸    入       : 無
* 輸    出             : 無
*******************************************************************************/

void main()
{       
        uart_init();//波特率為9600
//char s2 = "ssss";


        while(1)
        {               
                uart_send_char('x');
                delay_1_second();
        }               
}


void uart() interrupt 4 //串口通信中斷函數(shù)
{
        u8 rec_data;
        RI = 0;                        //清除接收中斷標(biāo)志位
        rec_data=SBUF;        //存儲接收到的數(shù)據(jù)
        SBUF=rec_data;        //將接收到的數(shù)據(jù)放入到發(fā)送寄存器
        while(!TI);                //等待發(fā)送數(shù)據(jù)完成
        TI=0;                        //清除發(fā)送完成標(biāo)志位                               
}


回復(fù)

使用道具 舉報

ID:883242 發(fā)表于 2024-4-20 16:42 | 顯示全部樓層
能收說明波特率對,發(fā)送的數(shù)據(jù)接收錯誤,可能是停止位時間不夠。
回復(fù)

使用道具 舉報

ID:1116897 發(fā)表于 2024-4-20 22:11 | 顯示全部樓層
你串口助手顯示奇怪漢字還是符號啊,調(diào)一下串口助手,選文本顯示呢,別選信息位啥的,發(fā)個數(shù)字看看
回復(fù)

使用道具 舉報

ID:1116897 發(fā)表于 2024-4-20 22:25 | 顯示全部樓層
我沒看出來什么錯,估計是串口助手沒調(diào)對,這是我之前寫的
  1. #include <reg52.h>
  2. #define u8 unsigned char
  3. #define u16 unsigned int   
  4. u8  table[]="2";
  5. u8 a,flag;
  6. void Tim1_Init();
  7. void Serial_Init();
  8. void Serial_Interrupt_Init();
  9. void delay(u16 time_out)
  10. {
  11.     while(time_out--);
  12. }
  13. void main()
  14. {

  15.     u8 i;
  16.     Tim1_Init();
  17.     Serial_Init();
  18.     Serial_Interrupt_Init();   
  19.     while(1)
  20.     {
  21.         if(flag==1)
  22.         {
  23.         
  24.             for(i=0;i<1;i++)
  25.             {
  26.                 SBUF=table[i];
  27.                
  28.                 while(!TI);
  29.             
  30.                 TI=0;
  31.             }
  32.         
  33.             TI=0;
  34.             flag=0;
  35.         }
  36.      delay(1000);
  37.     }
  38. }

  39. void Tim1_Init()
  40. {
  41.     TMOD=0x20;
  42.     PCON=0X80;            
  43.     //波特率為9600 STC89C51 11.052MHZ
  44.     TH1=0xfA;
  45.     TL1=TH1;
  46.     TR1=1;
  47. }
  48. void Serial_Init()
  49. {
  50.     SM0=0;
  51.     SM1=1;
  52.     REN=1;
  53. }

  54. void Serial_Interrupt_Init()
  55. {
  56.     ES=1;
  57.     EA=1;
  58. }
  59. void Serial_Interrupt() interrupt 4
  60. {
  61.     RI=0;
  62.     a=SBUF;
  63.     flag=1;
  64. }
復(fù)制代碼
回復(fù)

使用道具 舉報

ID:384109 發(fā)表于 2024-4-21 16:31 | 顯示全部樓層
去掉串口中斷函數(shù)
回復(fù)

使用道具 舉報

ID:962485 發(fā)表于 2024-4-21 18:30 | 顯示全部樓層
DC大魔王 發(fā)表于 2024-4-20 22:11
你串口助手顯示奇怪漢字還是符號啊,調(diào)一下串口助手,選文本顯示呢,別選信息位啥的,發(fā)個數(shù)字看看

先謝謝老哥,不過即使我不放循環(huán)里只跑一次他還是一直重復(fù)發(fā)送空值回來,有時候又亂碼,請問老哥有解嗎
回復(fù)

使用道具 舉報

ID:962485 發(fā)表于 2024-4-21 18:30 | 顯示全部樓層
DC大魔王 發(fā)表于 2024-4-20 22:25
我沒看出來什么錯,估計是串口助手沒調(diào)對,這是我之前寫的
#include
#define u8 unsigned char

謝謝,我學(xué)習(xí)一下你的
回復(fù)

使用道具 舉報

ID:962485 發(fā)表于 2024-4-21 18:31 | 顯示全部樓層
Hephaestus 發(fā)表于 2024-4-20 16:42
能收說明波特率對,發(fā)送的數(shù)據(jù)接收錯誤,可能是停止位時間不夠。

這個停止位時間怎么弄呢,請問老哥
回復(fù)

使用道具 舉報

ID:962485 發(fā)表于 2024-4-21 22:09 | 顯示全部樓層
解決了,各位,是因?yàn)椴捎?2Mhz晶振的問題,采用9600比特率通信誤差太大不穩(wěn)定之類的void ,采用4800比特率,同時對串口通信的操作從底層開始
void uartSendData(u8 ucData)
{
    u8 ucCnt;
    UART_TX_LOW(); //串口起始位開始
    TR1 = 1; //定時器1開始計時
    ET1 = 1; //使能定時器1中斷
    bUartFlag = ON;
    while(bUartFlag == ON);
        /*
         *由地位開始,將數(shù)據(jù)通過串口輸出
        */
    for (ucCnt = 0; ucCnt < 8; ucCnt++)
        {
        UART_TX_SET(ucData & 0x01);
        ucData >>= 1;
        bUartFlag = ON;
        while(bUartFlag == ON);
    }
    UART_TX_HIGH();
    bUartFlag = ON;
    while(bUartFlag == ON);
    TR1 = 0;
    ET1 = 0;
}
記錄一下
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表