1、51单片机自带硬件串口接口,使用时只需要进行寄存器配置即可。
2、波特率有4种可选择,默认9600bps。另外还有1个字节的发送函数,n个字符发送函数。
3、有几个寄存器默认的reg52.h里面没有,我也给添加进去了,但是我也没有用到。
4、GB2312编码汉字占2个字节,UTF-8汉字占3个字节,英文均占用1个字节。使用串口工具需要注意,要不会出现中文乱码。
5、串口波特率也要一致,要不然也会出现乱码情况。
#ifndef __UART_H__
#define __UART_H__
#include <reg52.h>
sfr IPH_ =0xB7;//中断优先级高位寄存器
sfr SADEN_ =0xB9;//从机地址掩码寄存器
sfr SADDR_ =0xA9;//从机地址控制寄存器
// bps4800 1输入
// bps9600 2输入
// bps19200 3输入
// bps57600 4输入
//串口初始化装载,使用定时器1产生波特率,默认为9600bps
void UART_RES_LOAD_T1(unsigned char Mode_n_bps);//4800bps/9600bps/19200bps/57600bps
//串口发送数据
void UART_Send_1Byte_Data(unsigned char DAT);
//串口发送字符串
void UART_Send_string(unsigned char* c);
#endif // !__UART_H__
#include "uart.h"
//串口初始化装载,使用定时器1产生波特率
//串口工作方式1,8位uart且波特率可变,且允许串口接收数据
void UART_RES_LOAD_T1(unsigned char Mode_n_bps)//默认波特率9600bps
{
SCON = 0x50;//串口工作方式1,8位uart且波特率可变,且允许串口接收数据
PCON = 0x10;//0x10是PCON的默认值,最高位SMOD=1表示串口工作模式1、2、3下加倍波特率(芯片手册上有点问题)
SADEN_ = 0x00;//不使用
SADDR_ = 0x00;//不使用
EA = 1;//打开总中断
ES = 1;//打开串口中断
//串口1中断优先级0
IPH_ = 0x00;
IP = 0x00;
TMOD |= 0x20;//开启定时器T1,并使用工作方式2(8位自动重装)
switch(Mode_n_bps)
{
case 1:
TL1 = 250;//计数初值设置波特率4800bps
TH1 = 250;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
break;//bps4800
case 2:
TL1 = 253;//计数初值设置波特率9600bps
TH1 = 253;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
break;//bps9600
case 3:
PCON |= 0x80;//SM0D=1,波特率加倍
TL1 = 253;//计数初值设置波特率19200bps
TH1 = 253;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
break;//bps19200
case 4:
PCON |= 0x80;//SM0D=1,波特率加倍
TL1 = 255;//计数初值设置波特率57600bps
TH1 = 255;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
break;//bps57600
default://默认bps9600
TL1 = 253;//计数初值设置波特率9600bps
TH1 = 253;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
break;//bps9600
}
ET1 = 0;//禁止定时器1发出中断
TR1 = 1;//启动定时器1
}
//串口发送数据
void UART_Send_1Byte_Data(unsigned char DAT)
{
ES = 0;//要发送数据了,先关闭串口中断服务
TI = 0;//准备发送数据
SBUF = DAT;
while (!TI);//判断是否发送完成TI=1?
TI = 0;//软件清除发送完成的标志位
ES = 1;//发送完成了,开启串口中断服务
}
//串口发送字符串
void UART_Send_string(unsigned char *c)
{
while (*c != '\0')
{
UART_Send_1Byte_Data(*c++);//带*c表示的是值,c表示的是地址
}
}
//串口中断函数,中断号4
void UART(void) interrupt 4
{
EA = 0;//先关闭总中断,防止在处理下面的时候被别的中断打断
if (TI) //发送标志位
{
TI = 0;
}
if (RI) //接收标志位
{
RI = 0;
UART_Send_1Byte_Data(SBUF+1);//把串口接收到的值+1在重新发送回去
}
EA = 1;//打开总中断
}