串行通信基础 计算机通信大多是指计算机与外部设备或者是计算机之间进行相关信息或者数据进行互换、交换。 串行通信主要有并行通信和串行通信两种方式。在两个或者多个微系统交换信息中多采用串行通信方式。
并行通信:通常是将数据字节的各位用多条数据线同时进行数据的传输。控制比较简单,传输速度较快;长距离传输成本较高。
串行通信:是将数据字节分成一位一位的方式在一根传输线上逐个传输;传输速度没有并行通信速度快,长距离传输成本较低。
串行通信方式 AT89C52单片机的串口一共有4种工作方式,其中工作方式0为同步通信方式外,其余的3种均为异步通信方式。本文章主要讲的是异步通信方式中的一种,方式一。
串行通信数据传输的方向 数据传输方向可分为三种:单工、半双工、全双工。 单工指的是数据在传输的时候只能一个方向进行传输,不可以实现反向传输。简单的说就是只能 A的数据传输到B,而B的数据不能传输到A。 半双工指的是数据在传输的时候两个方向都可以进行传输,不过要分时进行。也就是说只有 A的数据传输到B完成以后 B的数据才可以进行传到A。 全双工指的是数据可以同时进行双向传输。也就是在A发送数据给B时,B也可以传送数据个A。
本文主要介绍的是单工通信的使用示例,程序编写与相关的仿真电路设计。
仿真电路设计以及单工传输工作原理 仿真电路通过proteus仿真软件进行设计,矩阵键盘输入1~16数字到单片机A,然后单片机A将数据发送到单片机B,通过单片机B连接的数码管显示出相应的数字。具体电路设计如下图所示:
电路工作原理 如图所示,单片机A、B双机进行串行通信,双机的RXD和TXD相互交叉相连,单片机A的P1 IO口连接矩阵按键,单片机B的P0 IO口连接一个2*8的数码管,数码管段选与位选通过74HC573八路输出锁存器进行控制。单片机A只设置为只能发送数据数据但不能接收数据的单工方式。当单片机A读入到P1口有状态变化后(也就是有数距输入),读取到后通过单片机A串行口发送到单片机B;当单片机B接收到数据后将数据送到P0进行输出显示。其中要注意的一点是双方的晶振频率均为11.0592MHz。
程序编写 在编写相关程序之前我们要先弄清楚单片机A、B两者各要做什么事情。单片机A需要做的是发送数据和按键处理,单片机B需要做的是接收数据和显示相关数据。所以我们编写程序可以分开进行编写。先写单片机A后写单片机B。
单片机A程序编写 单片机A程序编写可以分为两个部分来处理,一是数据发送程序。二是按键处理程序。
主程序
#include <reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
#define DPIO_Key P1
sbit Key1=P2^2;
u8 num=0;
u8 dat;
void scen(u8 dat);
void UARTint();
void dis_Key();
void dis();
void delay(u16 i)
{
while(i--);
}
void main()
{
UARTint();
while(1)
{
dis();
dis_Key();
scen(num);
}
}
按处理程序
void dis()
{
u8 a;
DPIO_Key=0x0f;
if(DPIO_Key!=0x0f)
{
delay(1000);
if(DPIO_Key!=0x0f)
{
DPIO_Key=0x0f;
switch(DPIO_Key)
{
case(0x0e) : num=4;break;
case(0x0d) : num=3;break;
case(0x0b) : num=2;break;
case(0x07) : num=1;break;
}
DPIO_Key=0xf0;
switch(DPIO_Key)
{
case(0xe0) : num=12+num;break;
case(0xd0) : num=8+num;break;
case(0xb0) : num=4+num;break;
case(0x70) : num=num;break;
}
while((a<50)&&(DPIO_Key!=0xf0))
{
delay(1000);
a++;
}
}
}
}
void dis_Key()
{
if(Key1==0)
{
delay(1000);
if(Key1==0)
{
num=0;
}
while(!Key1);
}
}
串行通信发送数据程序
void UARTint()
{
TMOD=0x20;
TH1=253;
TL1=253;
TR1=1;
PCON=0x00;
SCON=0x40;
}
void scen(u8 dat)
{
SBUF=dat;
while(TI==0);
TI=0;
}
单片机B程序编写 单片机B程序编写也可以分为两个部分来编写,一是数码管显示程序,二是串行口数据接收程序。
主程序
#include <reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
#define LED P0
sbit duan=P2^0;
sbit wei=P2^1;
u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
u8 code smgwei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
u8 shi,ge;
u8 dat;
u8 receive();
void UARTint();
void dispaly();
void delay(u16 i)
{
while(i--);
}
void main()
{
UARTint();
while(1)
{
dispaly();
receive();
}
}
数码管显示程序
void dispaly()
{
if(dat==0)
{
LED=0xff;
wei=1;
LED=smgwei[0];
wei=0;
duan=1;
LED=0x00;
duan=0;
delay(50);
LED=0xff;
wei=1;
LED=smgwei[1];
wei=0;
duan=1;
LED=0x00;
duan=0;
delay(50);
}
else
{
LED=0xff;
wei=1;
LED=smgwei[0];
wei=0;
duan=1;
LED=smgduan[shi];
duan=0;
delay(50);
LED=0xff;
wei=1;
LED=smgwei[1];
wei=0;
duan=1;
LED=smgduan[ge];
duan=0;
delay(50);
}
}
数据接收程序
void UARTint()
{
wei=0;
duan=0;
TMOD=0x20;
TH1=253;
TL1=253;
TR1=1;
PCON=0x00;
SCON=0x50;
}
u8 receive()
{
while(RI==0);
{
RI=0;
}
dat=SBUF;
shi=dat/10;
ge=dat%10;
return dat;
}
以上就是单工串行通信的资料,写的不好,有不懂的和意见都可以留言哦。大家也可以根据这个实力进行修改成半双工的串行通信。
|