📄 serial.c
字号:
//**********************************************************************************
//杨屹 2002/08/20 第一版
//基于中断的串口驱动及显示程序
//联系方法:gdtyy@ri.gdt.com.cn(2003/07/31以前有效)
//**********************************************************************************
//程序特点:
// 1.基于中断,可并发执行
// 2.参数可配置(收发缓冲区大小,最大字符串长度,TAB键移动距离)
//**********************************************************************************
//使用方法:(此范例自包含,独立于其他程序。)
// 先配制收发缓冲区大小等可变参数(在serial.h中的宏定义)
// 1.开头加入#include <reg51.h>语句,一定要有。
// 2.初始化串口 InitSerial();//本例中为20MHz晶体,300波特率,模式2初始化
// 3.初始化串口缓冲区 InitSerialBuffer();
// 4.使用显示字节,字,长字,字符,字符串,清屏函数。
//自包含
//**********************************************************************************
//波特率计算公式:
// TH1=256-(2^SMOD/32*Fosc/12*1/Bound)
// 其中:SMOD=0,1;Fosc=晶体或晶振频率;Bound=波特率
// 本例中,SMOD=0;Fosc=20*10E6;Bound=300,所以TH1=0x52。
//Baud rate(20Mhz)
//300(52);1200(D5);2400(EA);4800(F5);9600(FB);19200(FD);38400(FF);
//**********************************************************************************
//书写风格:
// 1.带yy前缀标志的函数为杨屹改写的等效C库函数。
// 2.单个单词用小写,yy定义为前缀,不算一个单词。
// 3.多个单词(2个及以上),每个单词首字母大写。(有时变量名第一个单词首字母小写)
// 4.采用内缩风格,每次缩进8个空格。
//**********************************************************************************
//应用举例:(可在KEIL仿真环境下运行)
//源程序文件:serial.h/serial.c/main.c
//main.c内容:
//#include <reg51.h>//Note:It must be added.必须在serial.c之前
//#include <serial.h>
//main()
//{
// unsigned char ch;
//
// InitSerial();
// InitSerialBuffer();
// while(1){
// PrintStr("\n");
// PrintByte(90);PrintStr(" ");
// PrintWord(90);PrintStr(" ");
// PrintLong(90);PrintStr(" ");
// PrintChar('y');PrintChar(' ');//千万别写成双引号,否则打印0(乱字符)。
// PrintStr("\nHello!\nI'm YangYi.\n");
// PrintStr("Press any key to continue...");
// while(!yygetch(&ch));
// }
//}
//**********************************************************************************
//建议:
// 你完全可以把该子程序当作函数库使用,以便减少重复劳动,提高代码质量。
//**********************************************************************************
#include <serial.h>
#include <MCS51.H>
unsigned char xdata TxBuf[LenTxBuf],RxBuf[LenRxBuf];//收发缓冲区实体
unsigned char *inTxBuf,*outTxBuf,*inRxBuf,*outRxBuf;//收发缓冲区读写指针
bit TIflag=1; // 标志串口0发送缓冲区为空。
bit TIflag1=1; // 标志串口1发送缓冲区为空。
void InitSerial()//串口初始化
{
/* TMOD=TMOD&0x0F;
TMOD=TMOD|0x20;
TL1=0xFD,
TH1=0xFD;//19200 , 22.1184MHz
SCON0=0x50;
SCON1=0x50;
PCON=0x00;
TR1=1;*/
}
void InitSerialBuffer(void)//串口缓冲区初始化
{
inTxBuf=TxBuf;outTxBuf=TxBuf;
inRxBuf=RxBuf;outRxBuf=RxBuf;
}
void UART(void) interrupt 4
{ //中断在汇编中实现,去掉interrupt 4{//串口中断服务子程序
unsigned char *t;
if(TI){
TI=0;
if(outTxBuf!=inTxBuf) //TxBuf is not Empty
{
SBUF=*outTxBuf;
outTxBuf++;
if(outTxBuf==TxBuf+LenTxBuf)
outTxBuf=TxBuf;
}
else
TIflag=1;
}
if(RI){
RI=0;
t=inRxBuf;t++;
if(t==RxBuf+LenRxBuf) t=RxBuf;
if(t!=outRxBuf) //RxBuf is not Full
{
*inRxBuf=SBUF;
inRxBuf=t;
}
}
}
void UART1(void) interrupt 7
{
unsigned char *t;
if(TI_1){
TI_1=0;
if(outRxBuf!=inRxBuf) //TxBuf is not Empty
{
SBUF1=*outRxBuf;
outRxBuf++;
if(outRxBuf==RxBuf+LenRxBuf)
outRxBuf=RxBuf;
}
else
TIflag1=1;
}
if(RI_1){
RI_1=0;
t=inTxBuf;t++;
if(t==TxBuf+LenTxBuf) t=TxBuf;
if(t!=outTxBuf) //RxBuf is not Full
{
*inTxBuf=SBUF1;
inTxBuf=t;
}
}
}
void initial_cpu(void)
{
CKCON = 0x41;
TA = 0xaa;
TA = 0x55;
WDCON = 0x00; // 禁止看门狗
PMR = 0X41; //外部XDATA 4CLOCKS ONE MACHAINE CYCLE
SCON = 0x50;
SCON1 = 0x50;
TMOD = 0x21; // T1:baut,T0:Time 16bit
TCON = 0x50;
TH1 = 0xfe; // 0xfd:9600 0xfe:14400
TL1 = 0xfe;
PCON = 0x00; // Uart Baut=9600
TH0 = 0x4c;
TL0 = 0x00; // T0=50ms
IP = 0x50; //两个串口高
IE = 0xd0; //开全局中断,定时器0。串口1中断。串口2中断。
}
void putunchar(unsigned char c)
{
ES = 0;
TI = 0;
SBUF = c;
while(!TI);
TI = 0;
ES = 1;
}
void putunchar1(unsigned char c)
{
ES1 = 0;
TI_1= 0;
SBUF1 = c;
while(!TI_1);
TI_1=0;
ES1 = 1;
}
void main(void)
{
int i;
initial_cpu();
InitSerial();
InitSerialBuffer();
for(i=0;i<10;i++)
{
putunchar(0x30+i);
putunchar1(0x30+i);
}
EA = 1;
while(1)
{
if((TIflag1==1)&&(inRxBuf!=outRxBuf)) // UART0接收 到 UART1 发送.
{
TIflag1=0;
TI_1=1;
}
if((TIflag==1)&&(inTxBuf!=outTxBuf)) // UART1接收 到 UART0 发送.
{
TIflag=0;
TI=1;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -