51单片机串口

51单片机串口

1.串口通信

1.1串口接线方式

  • RXD:数据输入引脚,数据接受;STC89系列对应P3.0口,上官一号有单独引出

  • TXD:数据发送引脚,数据发送;STC89系列对应P3.1口,上官一号有单独引出

  • 接线方式

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FMY5yTZI-1690308835514)(C:\Users\xie19\Pictures\Camera Roll\屏幕截图 2023-07-25 185225.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xUfBzHGK-1690308835515)(C:\Users\xie19\Pictures\Camera Roll\屏幕截图 2023-07-25 185247.png)]

2.串口编程要素

  • 输入/输出数据缓冲器都叫做SBUF, 都用99H地址码,但是是两个独立的8位寄存器

  • 代码体现为: 想要接收数据 char data = SBUF 想要发送数据 SBUF = data

  • 回忆UART是异步串行接口,通信双方使用时钟不同,因为双方硬件配置不同,但是需要约定通信速度,叫做波特率

对于电脑来说,别人做好了软件,鼠标点点点就能配置好,而苦逼单片机的波特率配置需要我们写代码点点点配置什么,我们代码也要配置对应参数

3.发送一个字符给PC

#include "reg52.h"
#include "intrins.h"

sfr AUXR=0x8e;	

/*
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR=0x01;
     SCON=0x40; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1=0xFD; //配置定时器初值
     TH1=0xFD;
     TR1=1; 
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}



void main()
{
	char data_msg='a';
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        SBUF=data_msg;
        //发送数据往寄存器SBUF写数据就ok        
    }    
}

4.发送一个字符串给PC

#include "reg52.h"
#include "intrins.h"

sfr AUXR=0x8e;	

/*
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR=0x01;
     SCON=0x40; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1=0xFD; //配置定时器初值
     TH1=0xFD;
     TR1=1; 
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char data_msg)
{
   SBUF=data_msg;
   while(!TI);
   TI=0;    
}

void sendString(char *str)
{
    while(*str)
   {
        sendByte(*str);
        str++;
   }       
}

void main()
{
	
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        sendString("nihao pc\r\n");       
    }    
}

5.PC通过串口点亮LED

#include "reg52.h"
#include "intrins.h"

sbit D5=P3^7;
sfr AUXR=0x8e;	

/*
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR =0x01;
     SCON =0x50; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1  =0xFD; //配置定时器初值
     TH1  =0xFD;
     TR1  =1; 
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char data_msg)
{
   SBUF=data_msg;
   while(!TI);
   TI=0;    
}

void sendString(char *str)
{
    while(*str)
   {
        sendByte(*str);
        str++;
   }       
}

void main()
{  
    char cmd; 
    D5=1;//一上电让D5灭    
  	
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        sendString("nihao pc\r\n");  
        //怎么知道收到了数据,打开RI中断,有硬件置1(RI=1) 
        if(RI==1)
        {
           RI=0;
           cmd=SBUF;//从寄存器接收数据
           if(cmd=='o')
           {
              D5=0;
           }
           if(cmd=='c')
           {
              D5=1;
           }               
        }            
    }    
}

6.PC通过串口中断点亮LED

#include "reg52.h"
#include "intrins.h"

sbit D5=P3^7;
sfr AUXR=0x8e;	
char cmd;

/*
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR =0x01;
     SCON =0x50; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1  =0xFD; //配置定时器初值
     TH1  =0xFD;
     TR1  =1;
     EA=1;//打开总中断
     ES=1;//打开串口中断    
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char data_msg)
{
   SBUF=data_msg;
   while(!TI);
   TI=0;    
}

void sendString(char *str)
{
    while(*str)
   {
        sendByte(*str);
        str++;
   }       
}

void main()
{  
    D5=1;//一上电让D5灭    
  	
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        sendString("nihao pc\r\n");  //心跳包;作用:有数据,说明单片机正常
    }    
}

void uart_handler()  interrupt 4
{
   if(RI)
   {
       RI=0;
       cmd=SBUF;//从串口寄存器SBUF接收数据
       if(cmd=='o')
       {
          D5=0;
       }
       if(cmd=='c')
       {
          D5=1;
       }       
   }    
   
   if(TI);
}

7.串口发送字符串点亮LED

#include "reg52.h"
#include "intrins.h"
#include<string.h>

#define SIZE 12
sbit D5=P3^7;
sfr AUXR=0x8e;	
char cmd[SIZE];

/*
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
*/

void UartInit(void)
{
     AUXR =0x01;
     SCON =0x50; //配置串口工作方式1,REN使能不接收
     TMOD&=0x0F; //配置定时器工作模式
     TMOD|=0x20;
     TL1  =0xFD; //配置定时器初值
     TH1  =0xFD;
     TR1  =1;
     EA=1;//打开总中断
     ES=1;//打开串口中断    
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void sendByte(char data_msg)
{
   SBUF=data_msg;
   while(!TI);
   TI=0;    
}

void sendString(char *str)
{
    while(*str)
   {
        sendByte(*str);
        str++;
   }       
}

void main()
{  
    D5=1;//一上电让D5灭    
  	
    UartInit();//C51串口通信初始化	
    //每隔1s发送一次
	while(1)
    {
        Delay1000ms();
        sendString("nihao pc\r\n");  //心跳包;作用:有数据,说明单片机正常
    }    
}

void uart_handler()  interrupt 4
{
   static int i=0; 
   if(RI)
   {
       RI=0;
       cmd[i]=SBUF;//从串口寄存器SBUF接收数据
       i++;
       if(i==SIZE)
       {
          i=0;
       }           
       if(strstr(cmd,"op"))
       {
          D5=0;
          i=0;
          memset(cmd,0,SIZE);           
       }
       if(strstr(cmd,"cl"))
       {
          D5=1;
          i=0;
          memset(cmd,0,SIZE);           
       }       
   }    
   
   if(TI);
}
相关推荐
嵌入式科普3 小时前
嵌入式科普(24)从SPI和CAN通信重新理解“全双工”
c语言·stm32·can·spi·全双工·ra6m5
重生之我是数学王子3 小时前
点亮核心板小灯 STM32U575
stm32·单片机·嵌入式硬件
end_SJ3 小时前
初学stm32 --- 定时器中断
stm32·单片机·嵌入式硬件
南城花随雪。3 小时前
单片机:实现数码管动态显示(0~99999999)74hc138驱动(附带源码)
单片机·嵌入式硬件
南城花随雪。6 小时前
单片机:实现信号发生器(附带源码)
单片机·嵌入式硬件
灵槐梦7 小时前
【速成51单片机】2.点亮LED
c语言·开发语言·经验分享·笔记·单片机·51单片机
三月七(爱看动漫的程序员)8 小时前
HiQA: A Hierarchical Contextual Augmentation RAG for Multi-Documents QA---附录
人工智能·单片机·嵌入式硬件·物联网·机器学习·语言模型·自然语言处理
新晨单片机设计8 小时前
【087】基于51单片机智能宠物喂食器【Proteus仿真+Keil程序+报告+原理图】
嵌入式硬件·51单片机·proteus·宠物·ad原理图
大风起兮129 小时前
STM32HAL库中RTC闹钟设置时分秒,年月日
stm32·嵌入式硬件
超能力MAX10 小时前
IIC驱动EEPROM
单片机·嵌入式硬件·fpga开发