找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 186|回复: 8
收起左侧

51单片机串口通信求助

[复制链接]
ID:962485 发表于 2024-4-20 15:13 | 显示全部楼层 |阅读模式
为何手动选择数据不能发送,串口助手接收到的全是null或者乱码,接收中断返回来的又正确
#include "reg52.h"

typedef unsigned int u16;        //对系统默认数据类型进行重定义
typedef unsigned char u8;




void delay_1_second(void)
{
    unsigned int i, j;
    for (i = 0; i < 12000; i++) { // 假设每个大循环约耗时1ms
        for (j = 0; j < 120; j++) { // 这里是填充的小循环,具体数量需要根据实际情况调整
            // 空循环,用于消耗时间
        }
    }
}

/*******************************************************************************
* 函 数 名       : uart_init
* 函数功能                 : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
* 输    入       : baud:波特率对应的TH、TL装载值
* 输    出             : 无
*******************************************************************************/
void uart_init(void)
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位数据,可变波特率
        TMOD &= 0x0F;                //清除定时器1模式位
        TMOD |= 0x20;                //设定定时器1为8位自动重装方式
        TL1 = 0xFD;                        //设定定时初值
        TH1 = 0xFD;                        //设定定时器重装值               
        TR1 = 1;                        //启动定时器1
        ET1 = 0;                //禁止定时器1中断
        EA=1;                                //开放总中断
        ES=1;                                //开放串口中断

}


// 发送单个字符的函数
void uart_send_char(u8 da1)
{
    while(TI); // 等待上次发送完成(通过检查TI标志)
    SBUF = da1; // 将字符放入发送缓冲区SBUF
          while(!TI);                //等待发送数据完成
          TI=0;                        //清除发送完成标志位       
}

void uart_send_string(const char *str)
{
    while(*str) // 遍历字符串直到遇到结束符'\0'
    {
        uart_send_char(*str++); // 发送当前字符,并指向下一个字符
    }
}

/*******************************************************************************
* 函 数 名       : main
* 函数功能                 : 主函数
* 输    入       : 无
* 输    出             : 无
*******************************************************************************/

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


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


void uart() interrupt 4 //串口通信中断函数
{
        u8 rec_data;
        RI = 0;                        //清除接收中断标志位
        rec_data=SBUF;        //存储接收到的数据
        SBUF=rec_data;        //将接收到的数据放入到发送寄存器
        while(!TI);                //等待发送数据完成
        TI=0;                        //清除发送完成标志位                               
}


回复

使用道具 举报

ID:883242 发表于 2024-4-20 16:42 | 显示全部楼层
能收说明波特率对,发送的数据接收错误,可能是停止位时间不够。
回复

使用道具 举报

ID:1116897 发表于 2024-4-20 22:11 | 显示全部楼层
你串口助手显示奇怪汉字还是符号啊,调一下串口助手,选文本显示呢,别选信息位啥的,发个数字看看
回复

使用道具 举报

ID:1116897 发表于 2024-4-20 22:25 | 显示全部楼层
我没看出来什么错,估计是串口助手没调对,这是我之前写的
  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. }
复制代码
回复

使用道具 举报

ID:384109 发表于 2024-4-21 16:31 | 显示全部楼层
去掉串口中断函数
回复

使用道具 举报

ID:962485 发表于 2024-4-21 18:30 | 显示全部楼层
DC大魔王 发表于 2024-4-20 22:11
你串口助手显示奇怪汉字还是符号啊,调一下串口助手,选文本显示呢,别选信息位啥的,发个数字看看

先谢谢老哥,不过即使我不放循环里只跑一次他还是一直重复发送空值回来,有时候又乱码,请问老哥有解吗
回复

使用道具 举报

ID:962485 发表于 2024-4-21 18:30 | 显示全部楼层
DC大魔王 发表于 2024-4-20 22:25
我没看出来什么错,估计是串口助手没调对,这是我之前写的
#include
#define u8 unsigned char

谢谢,我学习一下你的
回复

使用道具 举报

ID:962485 发表于 2024-4-21 18:31 | 显示全部楼层
Hephaestus 发表于 2024-4-20 16:42
能收说明波特率对,发送的数据接收错误,可能是停止位时间不够。

这个停止位时间怎么弄呢,请问老哥
回复

使用道具 举报

ID:962485 发表于 2024-4-21 22:09 | 显示全部楼层
解决了,各位,是因为采用12Mhz晶振的问题,采用9600比特率通信误差太大不稳定之类的void ,采用4800比特率,同时对串口通信的操作从底层开始
void uartSendData(u8 ucData)
{
    u8 ucCnt;
    UART_TX_LOW(); //串口起始位开始
    TR1 = 1; //定时器1开始计时
    ET1 = 1; //使能定时器1中断
    bUartFlag = ON;
    while(bUartFlag == ON);
        /*
         *由地位开始,将数据通过串口输出
        */
    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;
}
记录一下
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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