第六章 RS232串口通信
目录
前言
本章主要学习如何通过串口方式在单片机与单片机、单片机与PC机、多个单片机之间进行通信。
计算机通信的基础
- 波特率
1)定义:每秒传输的二进制位
2)通信双方必须有相同的波特率
上述基本概念是我们进行计算机通信的基础,下面我们介绍单片机硬件电路中有关串口通信的情况。
串口通信
- 单片机内可编程全双工通信电路
1)发送管脚:TXD(P3.1)
2)接收管脚:RXD(P3.0)
3)管脚为TTL电平之间通信(0~5V)
- RS232接口
1)用于与PC机或外部通信的接口
2)通信电平为(-15V~+15V)
3)需要用MAX232进行电平转换
4)通信距离15M左右,若需要更长距离通信,可采用RS385接口
串口通信主要寄存器
- 数据缓冲寄存器SBUF
数据缓存寄存器SBUF在物理上分为两个独立的发送缓冲器和接收缓冲器。这两个缓冲器占用相同的物理地址99H,它究竟是用于发送缓冲器还是接收缓冲器,取决于软件编程指令。
- 通信方式控制寄存器SCON
串行口控制寄存器SCON(地址为98H)包含有串行口的工作方式选择位、接收发送控 制位及串行口的状态标志,格式为
SM0和SM1为串行口的工作方式选择位
关于串口通信主要寄存器的工作方式与控制,将在下一个章节详细介绍。
二、单片机与单片机串口通信电路程序设计与仿真
实现功能:A单片机向B单片机发送数字1~7,并在B单片机显示传送过来的数字1~7。
proteus仿真
序号 | 元件名称 | 名称说明 | 备注 |
1 | 89C52 | 单片机 | 51系列 |
2 | 7SEG-COM-AN-BLUE | 数码管 | 共阳,蓝色 |
3 | RES | 标准电阻 | 500Ω |
4 | MAX232 | 串口电平转换芯片 |
MAX232芯片的作用就是将TTL(0~5V)方式转换位RS232(-15V~+15V)方式,以便能在较长的距离传输,最长15m.
程序
主机程序
#include <reg52.h>//单片机头文件
void main()
{
char Buf[]={1,2,3,4,5,6,7};//定义一个存放传送内容的数组
char len=7;//传送数组的长度
char i=0;//定义循环变量
SM1=1;//定义串口工作方式1
SM0=0;//定义定时器1工作方式2,自动重载
TMOD=0x20;//8位计数,用于设置波特率
TH1=0xf3;//定时器初值,波特率2400
TL1=0xf3;
TI=0;
RI=0;//发送、接收中断标志清零
TR1=1;//启动定时器
SBUF=len;//先发送数组长度
while(TI==0);//等待发送完毕,若发送完毕,则TI=1
TI=0;//发送标志清零
for(i=0;i<len;i++)//循环7次
{
SBUF=Buf[i];//将发送数据放入缓冲区
while(TI==0);//等待发送完毕
TI=0;//发送完毕,发送标志清零
}
while(1);/循环等待
}
从机程序
#include <reg52.h>//单片机头文件
unsigned char LED_CODES[]={0xC0,0xF9,0xA4,0XB0,0X99,0x92,0x82,0xF8,0x80,0x90};//共阳数码管码段表
void main()
{
char Buf[20];//存放接收数据数组
char len;//接收数据长度
char i=0;//循环变量
unsigned int k;//循环变量
SM1=1;定义串口工作方式1
SM0=0;//定义定时器1工作方式2,自动重载
TMOD=0x20;//8位计数,用于设置波特率
TH1=0xf3;//定时器初值,波特率2400
TL1=0xf3;
TI=0;
RI=0;//发送、接收中断标志清零
REN=1;//允许串行接受位 1允许 0禁止
TR1=1;//启动定时器
while(RI==0);//等待接收完毕
RI=0;//接收完毕,接收标志清零
len=SBUF;//从缓冲区接收数据长度
for(i=0;i<len;i++)//循环len次
{
while(RI==0);
RI=0;
Buf[i]=SBUF;//接收数据放入数组
}
i=0;//循环变量清零
while(1)//无限循环
{
P2=LED_CODES[Buf[i]];//在数码管显示第i个接收数据
for(k=50000;k!=0;k--);//延时
i++;//循环变量加1
if(i==len)
i=0;//循环变量等于数据长度时清零
}
}
PC(虚拟终端)与单片机通信程序设计与仿真
proteus仿真
虚拟终端在“虚拟仪器模式”中的“VIRTUAL TERMINAL"。虚拟终端的RXD与TXD和单片机的RXD和TXD交叉相连。
程序
#include <reg51.h>
unsigned char table1[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//共阳数码管码段表
unsigned char table2[]={0,0,0,0};//4位显示数字存放数组
unsigned char i;//循环变量
unsigned char temp;//片选变量
unsigned char dat,dat1;//接收变量
sbit K=P3^2;//定义按键
char code str[]="123";/定义发送数据
void delay(void)//延时子程序
{
int k;
for(k=0;k<600;k++);
}
void display(int k)显示子程序
{
table2[0]=k%1000/100;//百位数
table2[1]=k%100/10;//十位数
table2[2]=k%10;//个位数
temp=0x01;//片选初值
for(i=0;i<4;i++)//循环4次
{
P2=~temp;//送片选值
P0=table1[table2[i]];//送显示数据位
temp=temp<<1;//片选值左移一位
delay();//延时
}
}
void Init_Com(void)//串口定义初始化子程序
{
TMOD=0x20;//定时器工作方式2,初值自动装入
PCON=0x00;//波特率不倍增
SCON=0x50;//串行工作方式1
TH1=0xFd;//定时器初值高位,波特率9600
TL1=0xFd;//定时器初值低位
TR1=1;//启动定时器
}
void send_str()//发送字符串子程序
{
unsigned char i=0;
while(str[i]!='\0')//直到字符串尾部
{
SBUF=str[i];//将字符送缓冲区
while(!TI);//等特数据传送
TI=0;//清除数据传送标志
i++;//下一个字符
}
}
void main()
{
EA=1;//开总允许中断
IT0=1;EX0=1;//开外部中断0和外部中断允许
P0=0xff;//P0口清空
P2=0xff;//P2口清空
Init_Com();//调用串口通信初始化子程序
while(1)
{
if(RI)//如果接收到数据
{
dat=SBUF;将数据从缓冲区读到dat中
RI=0;//接收标志清零
dat1=dat-112;
}
display(dat1);//数值显示
}
}
void intersvr0(void) interrupt 0 using 1
{
send_str();//调用发送字符串子程序
}
在串口通信初始化中,我们将波特率设置成9600,因此,在仿真运行前,需要将虚拟终端的属性也进行相应的设置。双击虚拟终端,如图所示的方法设置属性
编译程序生成可执行程序,并将程序加入单片机中,运行仿真。要使虚拟终端弹出运行,还必须保证在仿真运行时,“Virtual Terminal”弹出,如图所示
右键单击虚拟终端弹出菜单,选择“Echo Typed Characters" 回显键盘字符,这样,当我们敲键盘字符时,就会在虚拟终端上显示出来,并发送给单片机,否则就不会显示所敲字符,但仍然会发送。当我们运行时会发现在键盘上输入的字符与显示的字符是一致的,但单片机上接收的数据却不一样,这是因为键盘上的所有字符都属于ASCII编码,传输后还有一个转换的变化。但接收的数据与输入的字符是一一对应的。找规律可以看出输入数字与接收数字差112。于是定义新变量dat1,dat1=dat-112
单片机发送数据给PC的操作,通过按钮操作,发送一个字符串。这个字符串是程序中预先定义好的,当按钮按下时,就触发了一个外部中断,中断处理程序就发送了我们定义的字符串“123”,需要选中“Hex Display Mode”16进制显示,如图所示
总结
在单片机中内置了串口通信方式,通过规定的引脚RXD(P3.0)和TXD(P3.1)进行通信。本章主要如何通过RS232串口方式在单片机与单片机、单片机与PC机、多个单片机之间进行通信。