教学篇-串口通信USART
admin · 子分类2 · 2024年09月27日

串口通信使用的是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; //表示发送完毕

  }

}


标签1 ( 15 )
标签2 ( 12 )
标签3 ( 4 )
标签4 ( 2 )
标签5 ( 7 )
标签6 ( 5 )
标签 ( 2 )