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);
}
相关推荐
scan13 小时前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
Qingniu013 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
Mortal_hhh4 小时前
VScode的C/C++点击转到定义,不是跳转定义而是跳转声明怎么办?(内附详细做法)
ide·vscode·stm32·编辑器
深圳市青牛科技实业有限公司5 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
Mr.谢尔比6 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理
LightningJie6 小时前
STM32中ARR(自动重装寄存器)为什么要减1
stm32·单片机·嵌入式硬件
鹿屿二向箔6 小时前
STM32外设之SPI的介绍
stm32
西瓜籽@6 小时前
STM32——毕设基于单片机的多功能节能窗控制系统
stm32·单片机·课程设计
远翔调光芯片^138287988729 小时前
远翔升压恒流芯片FP7209X与FP7209M什么区别?做以下应用市场摄影补光灯、便携灯、智能家居(调光)市场、太阳能、车灯、洗墙灯、舞台灯必看!
科技·单片机·智能家居·能源
极客小张10 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩