UAV2101~2105串行通信训练

串口自学参考连接(串口通信详解、51单片机串口通信原理)

https://blog.51cto.com/u_15260779/2879124

https://blog.csdn.net/qq_41780295/article/details/124042130

训练001、使用串口调试助手,由PC机发送数据(HEX格式)到单片机通信,不开中断,运用查询法任意点亮LED。11.0592M晶振,波特率9600。

建议使用开发板测试,如果运用Proteus仿真,则需要搭建虚拟串口(运用VSPD),虚拟COM1和COM2并短接,Proteus仿真使用COM1,串口助手发送COM2

#include <reg52.h>

void main()
{
    SCON = 0x50;  //配置工作方式1,REN=1允许接收
    TMOD = 0x20;  //T1工作于方式2,定时方式
    TH1 = 0xfd;   //定时器装初值
    TL1 = 0xfd;
    TR1 = 1; //开定时器1
    while(1)
    {
        if(RI == 1)
        {
            RI=0;      //清除接收标志 
            P0 = SBUF;
        }
    }        
}

训练002、使用串口调试助手,由PC机发送数据(HEX格式)到单片机通信,开中断,运用中断法任意点亮LED。

#include <reg52.h>

void main()
{
    SCON = 0x50;  //配置工作方式1,REN=1允许接收
    TMOD = 0x20;  //T1工作于方式2,定时方式
    TH1 = 0xfd;   //定时器装初值
    TL1 = 0xfd;
    TR1 = 1; //开定时器1

    ES = 1;//开串口中断
    EA = 1;//开总中断

    while(1)
    {
        ;
    }        
}
void Uart() interrupt 4
{
    RI=0;      //清除接收标志 
    P2 = SBUF;
}

 

训练003、单片机发送数据到PC机通信,不开中断,运用for语句实现任意字符发送。11.0592M晶振,波特率9600。

#include <reg52.h>
unsigned char Tab[]="STC89C52RC\nUart Test !\r";
//unsigned char Tab[]={'1','2','3','4','5','o','k'};//定义了向PC机发送的数组
unsigned char i;

void delay(unsigned int z) //当z=1,延迟时间10ms
{
    unsigned char i,j,k;
    for(i=z;i>0;i--)
        for(j=4;j>0;j--)
            for(k=248;k>0;k--);
}
void main()
{
    SCON = 0x40;  //配置工作方式1,REN=0禁止接收
    PCON |= 0x80; //SMOD=1,波特率加倍
    TMOD = 0x20;  //T1工作于方式2,定时方式
    TH1 = 0xfa;   //定时器装初值
    TL1 = 0xfa;
    TR1 = 1; //开定时器1
    while(1)
    {
        for(i=0;i<24;i++)
        {
            SBUF = Tab[i];
            while(!TI);//等待发送完
            TI=0;      //清除发送结束标志  
        }
//        SBUF= '\r' ;   //'\r'回车'\n'换行
//      while(!TI);    //等待发送完
//        TI=0;          //清除发送结束标志 
        delay(50);
    }        
}

训练004、单片机发送数据到PC机通信,开中断,运用字符串发送子函数,实现任意字符发送。11.0592M晶振波特率9600。

#include <reg52.h>

bit busy;

void SendData(unsigned char dat)
{
    while(busy);//判断是否忙
    busy =1;
    SBUF = dat;

}
void SendString(char *s)
{
    while (*s)    //Check the end of the string
    {
        SendData(*s++); //Send current char and increment string ptr
    }
}
void main()
{
    SCON = 0x40;  //配置工作方式1,REN=0禁止接收
    PCON |= 0x80; //SMOD=1,波特率加倍
    TMOD = 0x20;  //T1工作于方式2,定时方式
    TH1 = 0xfa;   //定时器装初值
    TL1 = 0xfa;
    TR1 = 1; //开定时器1
    ES = 1;  //开串口中断
    EA = 1;  //开总中断
    SendString("STC89C52RC\r\nUart Test !\r\n");
    while(1);
}

void uart() interrupt 4
{
    if(TI)
    {
        TI = 0;
        busy = 0;        
    }
}

训练005、简单的串口回环程序,PC机发送数据到单片机通信,并且单片机返回数据给PC机

简单的串口回环程序,它能够将从串口接收到的数据原样发送回去。在这段代码中,使用了 UART_Init() 函数来初始化串口,UART_SendByte() 函数用于发送一个字符,UART_ReceiveByte() 函数用于接收一个字符。main() 函数是程序的主入口,通过循环不断从串口接收数据并发送回去。

 

#include <reg52.h>

// 定义串口波特率
#define BAUDRATE 9600

// 计算波特率产生器的值
#define BRL_VALUE (256 - (11059200 / 12) / 32 /  BAUDRATE)

// 初始化串口函数
void UART_Init()
{
    TMOD = 0x20;       // 设置定时器1为模式2
    TH1 = BRL_VALUE;  // 设置波特率
    
    SCON = 0x50;      // 串口工作在模式1,允许接收
    TR1 = 1;          // 启动定时器1
}

// 串口发送函数
void UART_SendByte(unsigned char dat)
{
    SBUF = dat;        // 将数据写入SBUF寄存器
    while (!TI);       // 等待发送完成
    TI = 0;            // 清除发送完成标志
}

// 串口接收函数
unsigned char UART_ReceiveByte()
{
    while (!RI);       // 等待接收完成
    RI = 0;            // 清除接收标志
    return SBUF;       // 返回接收到的数据
}

// 主程序
void main()
{
    unsigned char dat;
    
    UART_Init();       // 初始化串口
    while (1)
    {
        dat = UART_ReceiveByte();   // 从串口接收数据
        UART_SendByte(dat);         // 将接收到的数据发送回去
    }
}

训练006、PC机发送数据到单片机通信,并且单片机返回数据给PC机,通过串行调试助手接收端返回显示(SCON=0x50允许接收),LED显示出来

#include <reg52.h>

bit busy;
unsigned char uart_data;
void SendData(unsigned char dat)
{
    while(busy);
    busy =1;
    SBUF = dat;

}
void SendString(char *s)
{
    while (*s)    //Check the end of the string
    {
        SendData(*s++); //Send current char and increment string ptr
    }
}
void main()
{
    SCON = 0x50;  //配置工作方式1,REN=1允许接收
    TMOD = 0x20;  //T1工作于方式2,定时方式
    TH1 = 0xfd;   //定时器装初值
    TL1 = 0xfd;
    TR1 = 1; //开定时器1
    ES = 1;  //开串口中断
    EA = 1;  //开总中断
    SendString("STC89C52RC\r\nUart Test !\r\n");
    while(1);
}

void uart() interrupt 4
{
    if(RI)
    {
        RI = 0;          //清除接收中断标志
        uart_data = SBUF;//接收数据
        P2 = SBUF;       //P2显示接收的UART数据
        SBUF = uart_data;//返回到PC上位机观察
    }
    if(TI)
    {
        TI = 0;     //清除发送中断标志
        busy = 0;    //忙标志位清零
    }
}

训练007、PC机发送数据到单片机通信,并且单片机返回数据给PC机,通过串行调试助手接收端返回显示(SCON=0x50允许接收),数码管显示出来对应数字

#include <reg52.h>

unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,
0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段

//#define FOSC 11059200L      //System frequency
//#define BAUD 9600           //UART baudrate
//TH1 = TL1 = -(FOSC/12/32/BAUD); //Set auto-reload vaule
char uart_data;

void main (void)
{
    SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */
    TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */
    TH1 = 0xFD; /* 9600 Bds at 11.059MHz */
    TL1 = 0xFD; /* 9600 Bds at 11.059MHz */
    ES = 1; /* Enable serial interrupt*/
    EA = 1; /* Enable global interrupt */
    TR1 = 1; /* Timer 1 run */
    while(1); /* endless */
}

void serial_IT(void) interrupt 4
{
    if (RI == 1)
    {    /* if reception occur */
         RI = 0; /* clear reception flag for next reception */
         uart_data = SBUF; /* Read receive data */
         P2 = Tab[uart_data];
         SBUF = uart_data; /* Send back same data on uart*/
    }
    else TI = 0; /* if emission occur */
} /* clear emission flag for next emission*/

 

训练008、实现单片机与单片机通信,需搭建虚拟串口(运用VSPD),虚拟COM1和COM2并短接,分别配置COM1、COM2

/*串口发送与接受一体的控制代码*/

1、在发送端proteus图纸中, 按下按键K1和K2,可以改变要发送的数据num(数值范围0~9),按下K3通过串口发送num数据到接收端。

接收端能够接受数据,并在数码管上显示接受的数字。

2、接收端也可以进行数据的发送,也可以发送数据到发送端,同时发送端也能显示接收到的数据。

#include <REG52.H>
#include <intrins.h>

//共阳0-F dp-a 
unsigned char code tab[16]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

#define uchar unsigned char
sbit K1=P1^0;//ADD  递增
sbit K2=P1^1;//DEC  递减
sbit K3=P1^2;//DEC  递减

void UartInit(void)        //9600bps@11.0592MHz
{
    PCON &= 0x7F;        //波特率不倍速SMOD=0
    SCON = 0x50;        //8位数据,可变波特率,模式1,允许接收
    TMOD = 0x20;        //设定定时器1,模式2为8位自动重装方式
    TL1 = 0xFD;        //设定定时初值253
    TH1 = 0xFD;        //设定定时器重装值
    ET1 = 0;        //禁止定时器1中断
    TR1 = 1;        //启动定时器1
    ES=1;           //开串口中断
    EA=1;           //开总中断
}

char putchar (uchar ch)//向串口发送数据
{
     SBUF=ch;
     while(!TI);//查询发生是否完毕
     TI=0;//发送完毕,TI由软件清零
    return ch;
}

/********************************************************
函数功能: 延时c  ms
参    数:  c
返回  值: 无
*********************************************************/
void delayms( unsigned int ms)        //@11.0592MHz
{
    unsigned char i, j;
    for(;ms>0;ms--)
    {
        _nop_();
        i = 2;
        j = 199;
        do
        {
            while (--j);
        } while (--i);
    }
}

uchar Receive_nums=0;//接收到的字符
void Uart1() interrupt 4
{    
   if (RI)
   {
        RI=0;        //清除RI位
        Receive_nums=SBUF;    
   }
}

void main(void)
{
    uchar Transmit_nums=0;//发送给乙机的数字
    UartInit();
    
    while(1)
    {
        P0=~tab[Receive_nums];//在数码管上显示数字
        if(K1==0)//递增按键
        {
             delayms(10);//消抖
             if(K1==0)
             {
                 Transmit_nums++;
                 if(Transmit_nums>9)
                     Transmit_nums=9; 
             }
             while(K1==0);//等待按键K1松开
        }
        
        if(K2==0)//递减按键
        {
             delayms(10);//消抖
             if(K2==0)
             {
                 Transmit_nums--;
                 if(Transmit_nums<1)
                     Transmit_nums=0;     
             }
             while(K2==0);//等待按键K2松开
        }
        
        if(K3==0)//发送按键
        {
             delayms(10);//消抖
             if(K3==0)
             {
                putchar(Transmit_nums);
             }
             while(K3==0);//等待按键K3松开
        }
    }
}

训练009、实现单片机与PC机通信,11.0592M晶振,波特率9600。实现;两个功能。

1、单片机按键按下,向PC机发送4组1–5五个数

2、PC机控制单片机LED灯的亮灭。

 

posted on 2023-12-23 22:55  一郎哥哥  阅读(100)  评论(0编辑  收藏  举报

导航