1、51单片机自带硬件串口接口,使用时只需要进行寄存器配置即可。
2、定时器1波特率有4种可选择,默认9600bps。另外还有1个字节的发送函数,字符串发送函数。
3、增添:定时器2波特率有5种可选择,默认9600bps。
3、有几个寄存器默认的reg52.h里面没有,我也给添加进去了,但是我也没有用到。
4、GB2312编码汉字占2个字节,UTF-8汉字占3个字节,英文均占用1个字节。使用串口工具需要注意,要不会出现中文乱码。
5、串口波特率也要一致,要不然也会出现乱码情况。
6、备注:时钟晶振是11.0592M
#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输入
// bps115200 5输入
//串口初始化装载,使用定时器1产生波特率,默认为9600bps
void UART_RES_LOAD_T1(unsigned char Mode_n_bps);//4800bps/9600bps/19200bps/57600bps
//串口初始化装载,使用定时器2产生波特率
//串口工作方式1,8位uart且波特率可变,且允许串口接收数据//默认波特率9600bps
void UART_RES_LOAD_T2(unsigned char Mode_n_bps);//4800bps/9600bps/19200bps/57600bps//115200bps
//串口发送数据
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且波特率可变,且允许串口接收数据
//定时器1工作方式2,8位自动重装模式
void UART_RES_LOAD_T1(unsigned char Mode_n_bps)//默认波特率9600bps
{
SCON = 0x50;//串口工作方式1,8位uart且波特率可变,且允许串口接收数据
PCON = 0x10;//最高位SMOD=1表示串口工作模式1、2、3下加倍波特率(默认PCON=0x10,波特率不加倍)
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
}
//串口初始化装载,使用定时器2产生波特率
//串口工作方式1,8位uart且波特率可变,且允许串口接收数据
void UART_RES_LOAD_T2(unsigned char Mode_n_bps)//默认波特率9600bps
{
SCON = 0x50;//串口工作方式1,8位uart且波特率可变,且允许串口接收数据
T2CON |= 0x30;//定时器2用作串口波特率发生器且16位自动重装模式
SADEN_ = 0x00;//不使用,默认值
SADDR_ = 0x00;//不使用。默认值
EA = 1;//打开总中断
ES = 1;//打开串口中断
//串口1中断优先级0
IPH_ = 0x00;//默认值
IP = 0x00;//默认值
//T2MOD = 0x02;//T2OE :T2 输出允许位,当 T2OE=1 的时候,允许时钟输出到 P1.0。(仅对80C54 / 80C58 有效)
//DCEN:向下计数允许位。 DCEN = 1 是允许 T2 向下计数,否则向上计数。
switch (Mode_n_bps)
{
case 1:
TL2 = 0xb8;//计数初值设置波特率4800bps
TH2 = 0xff;//装载固定初值
RCAP2L = 0xb8;
RCAP2H = 0xff;
break;//bps4800
case 2:
TL2 = 0xdc;//计数初值设置波特率9600bps
TH2 = 0xff;//装载固定初值
RCAP2L = 0xdc;
RCAP2H = 0xff;
break;//bps9600
case 3:
TL2 = 0xee;//计数初值设置波特率19200bps
TH2 = 0xff;//装载固定初值
RCAP2L = 0xee;
RCAP2H = 0xff;
break;//bps19200
case 4:
TL2 = 0xfa;//计数初值设置波特率57600bps
TH2 = 0xff;//装载固定初值
RCAP2L = 0xfa;
RCAP2H = 0xff;
break;//bps57600
case 5:
TL2 = 0xfd;//计数初值设置波特率115200bps
TH2 = 0xff;//装载固定初值
RCAP2L = 0xfd;
RCAP2H = 0xff;
break;//bps115200
default://默认bps9600
TL2 = 0xdc;//计数初值设置波特率9600bps
TH2 = 0xff;//装载固定初值
RCAP2L = 0xdc;
RCAP2H = 0xff;
break;//bps9600
}
TR2 = 1;//启动定时器2
}
//串口发送数据
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;//此处注释掉是因为不需要在串口中断函数里发送数据。
//另外,使用printf()/puts()/putchar()(stdio.h)输入输出函数的时候,需要TI=1才能用。
}*/
if (RI) //接收标志位
{
RI = 0;
if((SBUF=='\r')|| (SBUF == '\n'))//当接收到换行或者左对齐的时候
{
UART_Send_string("\r\n");//执行左对齐并换行
}
else
UART_Send_1Byte_Data(SBUF);//把串口接收到的值在重新发送回去
}
EA = 1;//打开总中断
}