微控制器与外部设备的数据通信,根据连线结构和传送方式的不同,可以分为两种:并行通信和串行通信。
并行通信:指数据的各位同时发送和接收,每个数据位使用一条导线。
串行通信:指数据一位接一位的顺序发送或接收。
串行通信有SPI、IIC、UART等多种,最常见最通用的是指UART,大多数情况下,串口通信指的就是UART。
串行通信的制式有:单工,半双工,全双工三种。
RS458总线是半双工的通信制式。
串行通信的主要方式有两种:同步 和 异步 。
同步串行通信:需要使用同一个时钟,以数据快位单位传送数据。
异步串行通信:每个设备都有自己的时钟信号,通信中双方的波特率要保持一致,以字符位单位进行数据帧传送,一次传送一个帧。
波特率:串口每秒传输的位数。
通常使用定时器1的工作模式2(8位自动重装)来产生波特率,TL1作为脉冲计数寄存器,TH1作为自动重装寄存器,当计数到最大值溢出的时候,TH1的值会自动重装到TL1中。
波特率的计算公式:
UART口的数据发送与接收:
串行口中有两个缓冲寄存器SBUF,一个是发送寄存器,一个是接收寄存器,都是字节寻址的寄存器,字节地址均为99H。
数据发送: 发送数据程序:SBUF = 数据/变量; 如: SBUF = 0x58;
数据扔入SBUF后,发送后,会将TI标志位置1
数据接收: 接收数据程序: 变量 = SBUF; 如: date = SBUF;
从SBUF读取后,会将RI标志位置1
IAP芯片 在前面要写一个 sfr AUXR = 0x8e;
UART函数:
void InitUART()
{
TMOD = 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
SCON = 0x50;
AUXR = 0x00;
ES = 1;
EA = 1;
}
TMOD = 0x20; 设置定时器自动重装(依次: 0010 0000 转化为16进制为2 0 即0x20)
TH1 = 0xfd ;
TL1 = 0xfd ; 使用波特率为9600收发
TR1 = 1; 开启定时器
SCON = 0x50; 表示异步8位UART并允许接收 (为 0101 0000,即50,16进制 即0x50)
AUXR = 0x00 重置AUXR
ES = 1; 打开
EA = 1; 打开总开关
UART服务函数:
unsigned char command;
void UART() interrupt 4
{
if(RI == 1)
{
command = SBUF;
RI = 0;
}
}
RI == 1 表示接收完成;
TI == 1 表示发送完成;
数据接收:
void SendByte(unsigned char byt)
{
SBUF = byt;
while(TI == 0);
TI = 0;
}
SBFU = byt 给byt赋值为SBUF的值,直到TI == 0(直到数据发送结束)
数据发送至上位机:
void Sendstring(unsigned char *str)
{
while(*str != '\0')
{
SendByte(*str++);
}
}
新建一个字符变量unsigned char *str (指针) 一位一位传输,直到到达不是 “\0” 即字符结束的标志 。
如:Sendstring(“Welcome to ARM! ”);
即串口显示Welcome to ARM!
以下代码可以实现串口显示开机欢迎语 和 使串口输入的数字加1后通过串口输出:
#include"reg52.h"
sfr AUXR = 0x8e;
void HC573(unsigned char channel)
{
switch(channel)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
break;
case 0:
P2 = (P2 & 0x1f) | 0x00;
break;
}
}
void InitSym()
{
HC573(5);
P0 = 0x00;
HC573(4);
P0 = 0xff;
}
void InitUART()
{
TMOD = 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
SCON = 0x50;
AUXR = 0x00;
ES = 1;
EA = 1;
}
unsigned char command;
void UART() interrupt 4
{
if(RI == 1)
{
command = SBUF;
RI = 0;
}
}
void SendByte(unsigned char byt)
{
SBUF = byt;
while(TI == 0);
TI = 0;
}
void Sendstring(unsigned char *str)
{
while(*str != '\0')
{
SendByte(*str++);
}
}
void Working()
{
if(command != 0x00)
{
switch(command & 0xf0)
{
case 0xa0:
break;
case 0xb0:
break;
case 0xc0:
Sendstring("The System is Running\r\n");
command = 0x00;
break;
}
}
}
void main()
{
InitSym();
InitUART();
Sendstring("Welcome to ARM !\r\n");
while(1)
{
Working();
}
}