先来看一下有关寄存器的分配
再来了解一下编写串口通信程序的基本步骤:
1.配置串口模式。
2.配置定时器T1。
3.根据波特率计算TH1和TL1的初值,如有需要可以使用PCON进行波特率加倍。
4.打开定时器控制寄存器TR1。
下面来看1个串口通信地例程,要用HEX模式。
例程1的功能是当输入0时,流水灯停止,蜂鸣器关闭,数码管显示000000,输入非零数值时则流水灯流水,蜂鸣器打开,数码管显示相应数值。
**********例程1***********
#include<stc12c5a60s2.h>
sbit BUZZ = P1^3;//定义蜂鸣器引脚
sbit ENLED = P1^1;//使能LED
unsigned char code LedChar[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};//数码管显示缓冲区
unsigned char LedBuff[7] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
unsigned char T0RH=0;//T0重载值的高字节
unsigned char T0RL=0;//T0重载值的低字节
void ConfigUART(unsigned int baud);//串口配置函数,baud为通信波特率
void ConfigTimer0(unsigned int ms);//配置T0函数
unsigned char byte;
void main()
{
unsigned int i=0;
unsigned char cnt=0;
EA = 1;//使能总中断
ENLED = 0;//使能数码管和LED流水灯
ConfigTimer0(1);//配置T0定时1ms
ConfigUART(9600);//配置波特率9600
while(1)//将接受的字节在数码管上以16进制的形式显示出来
{
LedBuff[5] = LedChar[byte&0x0F];
LedBuff[4] = LedChar[byte>>4];
LedBuff[3] = LedChar[byte&0x0F];
LedBuff[2] = LedChar[byte>>4];
LedBuff[1] = LedChar[byte&0x0F];
LedBuff[0] = LedChar[byte>>4];
while(byte)
{
LedBuff[5] = LedChar[byte&0x0F];
LedBuff[4] = LedChar[byte>>4];
LedBuff[3] = LedChar[byte&0x0F];
LedBuff[2] = LedChar[byte>>4];
LedBuff[1] = LedChar[byte&0x0F];
LedBuff[0] = LedChar[byte>>4];
LedBuff[6] = 0xFE<<cnt;
for(i=0;i<50000;i++);
cnt++;
if(cnt>=8)cnt=0;
}
}
}
void ConfigUART(unsigned int baud)//串口配置函数
{
SCON = 0x50;//配置串口为模式1
TMOD &= 0x0F;//清零T1的控制位
TMOD |= 0x20;//配置T1为模式二
TH1 = 256-(33177600/12/32)/baud;//计算T1的重载值
TL1 = TH1;//初值等于重载值
TR1 = 1;//启动T1
ES = 1;//使能串口中断
}
void ConfigTimer0(unsigned int ms)
{
unsigned long tmp;//临时变量
tmp = 33177600/12;//定时器计数频率
tmp = (tmp*ms)/1000;//计算所需的计数值
tmp = 65536-tmp;//计算定时器重载值
TMOD &= 0xF0;
TMOD |= 0x01;
T0RH = (unsigned char)(tmp>>8);//定时器重载值拆分为高低字节
T0RL = (unsigned char)tmp;
TH0 = T0RH;//加载T0的重载值
TL0 = T0RL;
ET0 = 1;//使能T0中断
TR0 = 1;//启动T0
}
void ledscan()//LED动态扫描函数
{
static unsigned char i=0;
P0 = 0xFF;
P2 = (P2&0xF8)|i;//位索引赋值到P2的低三位
P0 = LedBuff;//赋值
if(i<7)
i++;
else
i=0;
}
void InterruptTimer0() interrupt 1//T0中断服务函数 完成LED扫描
{
TH0 = T0RH;
TL0 = T0RL;
ledscan();//LED扫描显示
if(byte)
{
BUZZ = 0;//打开蜂鸣器
}
else
{
BUZZ = 1;//关闭蜂鸣器
}
}
void InterruptUART() interrupt 4//UART中断服务函数
{
if(RI)//接到的字节
{
RI=0;//手动清零接受中断标志位
byte = SBUF;//接收到的数据保存到接受字节变量中
SBUF = byte;//接受到的数据又直接发回
}
if(TI)//字节发送完毕
{
TI=0;//手动清零接受中断标志位
}
}
|