串口通信使用的是USART协议,使用两根控制线进行读写操作
需要初始化串口和打开时间计数器中断
初始化串口,需要设置如下配置,计时器是用于产生波特率的
SCON = 0x50; //串口工作方式
TMOD = 0x20; //定时器模式2
PCON = 0x80; //波特率加倍
TH1=0XF3; //计数器初始值设置,注意波特率是4800的
TL1=0XF3;
TR1 = 1; //打开计数器1中断
ES = 1; //打开串口中断
EA = 1; //打开总中断
完成之后再代码中对 SBUF 寄存器读写完成都会进入中断,在中断函数中需要执行一些操作,如复位中断标志,判断是读中断还是写中断
#include <reg52.h>
#define LCD P0
sbit RS = P2^6;
sbit RW = P2^5;
sbit LCDE = P2^7;
sbit DS1302_SCLK = P3^6;
sbit DS1302_CE = P3^5;
sbit DS1302_DISO = P3^4;
unsigned char datas[] = "Hello World";
unsigned char status = 0;//发送usart信息标记
unsigned char number = 0;//已经发送的字节
void writecom(unsigned char i);
void writedata(unsigned char i);
void Delay(unsigned int a);
unsigned char readds1302(unsigned char dat);
void writeds1302(unsigned char addr,unsigned char dat);
void main(void){
unsigned char data1,temp;
//初始化LCD1602
writecom(0x38);
writecom(0x0c);
writecom(0x06);
writecom(0x01);
writecom(0x80);
//初始化串口
SCON = 0x50; //串口工作方式
TMOD = 0x20; //定时器模式2
PCON = 0x80; //波特率加倍
TH1=0XF3; //计数器初始值设置,注意波特率是4800的
TL1=0XF3;
TR1 = 1; //打开计数器1中断
ES = 1; //打开串口中断
EA = 1; //打开总中断
//初始化DS1302
writeds1302(0x8e,0x24);//关写保护
writeds1302(0x80,0x39);
writeds1302(0x82,0x11);
writeds1302(0x84,0x17);
writeds1302(0x86,0x30);
writeds1302(0x88,0x11);
writeds1302(0x8a,0x04);
writeds1302(0x8c,0x23);
writeds1302(0x8e,0x80);//开写保护
while(1){
writecom(0x80); //重新定位
//循环显示时间
temp = readds1302(0x81);
temp &= 0x7f;
data1 = temp / 16;
writedata('0'+data1);
data1 = temp & 0xf;
writedata('0'+data1);
writedata('-');
temp = readds1302(0x83);
data1 = temp / 16;
writedata('0'+data1);
data1 = temp & 0xf;
writedata('0'+data1);
writedata('-');
temp = readds1302(0x85);
data1 = temp / 16;
writedata('0'+data1);
data1 = temp & 0xf;
writedata('0'+data1);
writedata('-');
writecom(0x80 + 0x40); //重新定位
temp = readds1302(0x8d);
data1 = temp / 16;
writedata('0'+data1);
data1 = temp & 0xf;
writedata('0'+data1);
writedata('-');
temp = readds1302(0x89);
data1 = temp / 16;
writedata('0'+data1);
data1 = temp & 0xf;
writedata('0'+data1);
writedata('-');
temp = readds1302(0x87);
data1 = temp / 16;
writedata('0'+data1);
data1 = temp & 0xf;
writedata('0'+data1);
writedata('-');
Delay(100); //这个延时会影响串口信息的接收速度
if(status == 1 && number < 11){
status = 0;
SBUF = datas[number];
number++;
}else if(number == 11){
status = 0;
number = 0;
}
}
}
unsigned char readds1302(unsigned char dat){
unsigned char i,temp,data1;
DS1302_SCLK = 0;
Delay(1);
DS1302_CE = 0;
Delay(1);
DS1302_CE = 1;
Delay(1);
for(i=0;i<8;i++){
DS1302_DISO = dat & 0x01;
dat >>= 1;
DS1302_SCLK = 1;
Delay(1);
DS1302_SCLK = 0;
}
for(i=0;i<8;i++){
temp = DS1302_DISO; //这里只是读取了一位,而且是先读的低位
data1 >>= 1;
temp <<= 7;
data1 |= temp;
DS1302_SCLK = 1;
Delay(1);
DS1302_SCLK = 0;
}
//复位需要的时间
DS1302_SCLK = 0;
Delay(1);
DS1302_CE = 0;
Delay(1);
DS1302_DISO = 0;
Delay(1);
return data1;
}
void writeds1302(unsigned char addr,unsigned char dat){
unsigned char i;
DS1302_SCLK = 0;
Delay(1);
DS1302_CE = 0;
Delay(1);
DS1302_CE = 1;
Delay(1);
for(i=0;i<8;i++){
DS1302_DISO = addr & 0x01;
addr >>= 1;
DS1302_SCLK = 1;
Delay(1);
DS1302_SCLK = 0;
}
for(i=0;i<8;i++){
DS1302_DISO = dat & 0x01;
dat >>= 1;
DS1302_SCLK = 1;
Delay(1);
DS1302_SCLK = 0;
}
DS1302_SCLK = 0;
Delay(1);
DS1302_CE = 0;
}
void writecom(unsigned char i){
RS = 0;
RW = 0;
LCD = i;
Delay(10);
LCDE = 1;
Delay(10);
LCDE = 0;
}
void writedata(unsigned char i){
RS = 1;
RW = 0;
LCD = i;
Delay(10); //这里需要延时时间长一点
LCDE = 1;
Delay(10);
LCDE = 0;
}
void Delay(unsigned int a){
unsigned char b;
for(;a>0;a--)
{
for(b=110;b>0;b--);
}
}
void usart0() interrupt 4{
unsigned char date1;
if(RI){
if(SBUF == 54){ //表示接收到最后一个字符 数字6
status = 1; //接收到数据,
}
date1 = SBUF;
RI = 0; //硬件中断后自动置1,软件值0防止多次响应 表示接收完毕
}
if(TI){
while(!TI);
status = 1;
TI = 0; //表示发送完毕
}
}