新手用51内核单片机写了个串口通信,结果打印出来各种乱序

[复制链接]
306|2
手机看帖
扫描二维码
随时随地手机跟帖
fangding1997|  楼主 | 2022-7-31 22:02 | 显示全部楼层 |阅读模式
# include "SC92F725X_C.h"

bit UartSendFlag = 0; //发送中断标志位
bit UartReceiveFlag = 0; //接收中断标志位
char p[]="linx\r\n";
int i;
int j;
int k;

void Uart_Init(){
        P1CON |=0xF3; //给两个引脚1来允许输出
        P1PH &=0x0C;  //设置两个引脚0来允许上拉的输出
        SCON =0x50; //串口控制寄存器,方式1通信高两位表示模式00 01 10 11,第四位表示允许接受
        PCON |=0x80; //电源管理寄存器,最高位波特率设置,0在1/12时钟运行,1在1/4时钟运行
        //以上是串口设置
       
       
        T2CON =0x00; //TCON控制timer0和timer1,T2con中不但有timer2控制还有uart选择,这里选择了定时器1收发波特率
        TMOD=0X20; //定时器工作模式寄存器,可以选择作为计数器还是定时器,定时模式,8位自动重载模式
        TMCON=0X02;//选择计时器1的时钟 是1倍系统时钟
        //注意使用timer2的话代码略有不同
       
        TL1 = 217;               
        TH1 = 217;                 //UART 波特率24M情况下=38400,计算公式见手册15.2;
        TR1 = 1;                 //启动Timer0
        EUART = 1;             //允许UART中断
        EA = 1;                     //开总中断
        //以上是定时器控制中断设置
}

void UartInt(void) interrupt 4//4表示串口中断
{
        if(TI)//SCON中的读写控制,TI发送中断标志
        {
                TI = 0;       
                UartSendFlag = 1;               
        }
        if(RI)//SCON中的读写控制,RI接受中断标志
        {
                RI = 0;       
                UartReceiveFlag = 1;
        }       
}
unsigned char tx_data;
void SendByte(tx_data)
{
        SBUF=tx_data;//似乎这里会自动把字符指针转换成byte
        while(!UartSendFlag)
                UartSendFlag=0;
}

       
void SendString(char *s)
{
        while(*s)
        {
                SendByte(*(s++));
//                                for (i=200;i<1;i--){
//                        for (j=200;j<1;j--);}
        }
}
void delay(k)
{                for (i=200;i<1;i--){
                        for (j=200;j<1;j--){
                                while(k>1,k--);}
                        }
                }

void main()
{
        Uart_Init();
        while(1){
                SendString(p);
                delay(1000);
               

        }
}               
       

微信图片_20220731213526.png

使用特权

评论回复
sjnh| | 2022-8-1 07:59 | 显示全部楼层
试试,UartSendFlag  UartReceiveFlag 这两个用volatile修饰一下,在中断和主程序操作一个变量,必须用这个修饰下,不然容易出问题;
还有,主程序程序发送用了查询,串口又用了中断,UartSendFlag  UartReceiveFlag做中间变量,这是多此一举,不如不开串口中断,直接判断TI/RI,或者全部用中断发送,不用查询方式;

使用特权

评论回复
发送打架了,前面的还没有发出完毕,后面的又怼上去了,也就错乱了神经,原则上是发送后等待发送完成标志,或者发送第一个数据后中断里面续发,但是要控制好时间间隔,避免互撕

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则