5.3串行口编程
80C51 系列单片机片上有UART 用于串行通信,80C51 中有两个SBUF,一个用作发送
缓冲器,一个用作接收缓冲器,在完成串口的初始化后,只要将数据送入发送SBUF,即可
按设定好的波特率将数据发送出去,而在接收到数据后,可以从接收BUF 中读到接收到的
数据。下面我们通过一个例子来了解串行口编程的方法。
例 3 单片机P1 口接8 只发光二极管,P3.2~P3.5 接有K1~K4 共四个按键,使用串行
口编程,1)由PC 机控制单片机的P1 口,将PC 机送出的数以二进制形式显示在发光二极
管上;2)按下K1 向主机发送数字0x55,按下K2 向主机发送数字0xAA,使显示转下一行。
#define uchar unsigned char
#include "string.h"
#include "reg51.h"
void SendData(uchar Dat)
{ uchar i=0;
SBUF=Dat;
while(1){ if(TI)
{ TI=0;
break;}}
}
void mDelay(unsigned int DelayTime)
{ unsigned char j=0;
for(;DelayTime>0;DelayTime--)
{ for(j=0;j<125;j++)
{;}
}
}
uchar Key()
{ uchar KValue;
P3|=0x3e; //中间4 位置高电平
if((KValue=P3|0xe3)!=0xff)
{ mDelay(10);
if((KValue=P3|0xe3)!=0xff)
{ for(;;)
if((P3|0xe3)==0xff)
return(KValue);
}
}
return(0);
}
void main()
{ uchar KeyValue;
P1=0xff; //关闭P1 口接的所有灯
TMOD=0x20; //确定定时器工作模式
TH1=0xFD;
TL0=0xFD; //定时初值
PCON&=0x80; //SMOD=1
TR1=1; //开启定时器1
SCON=0x40; //串口工作方式1
REN=1; //允许接收
for(;;)
{ if(KeyValue=Key())
{ if((KeyValue|0xfb)!=0xff) //K1 按下
SendData(0x55);
if((KeyValue|0xf7)!=0xff)
SendData(0xaa);
}
if(RI)
{ P1=SBUF;
RI=0;
}
}
}
实现过程:输入程序,命名为exam53.c,建立名为exam53 的工程,将文件加入,设置
工程,使用实验仿真板进行调试。正确编译连接后进入调试,
打开实验仿真板,然后再点击viewserial #1 打开串行窗口,在
窗口空白处点右键,在弹出式菜单中选择“Hex Mode”如图3
所示。
单击实验仿真板的 K1 键和K2 键,即可看到在串行窗口中
分别出现55 和AA;单击串行窗口的空白处,使其变为活动窗
口,即可接收键盘输入,按下键盘上不同的字符键,可见实验仿真板上的LED 产生相应的
变化。图5-4 是按下K1 一次、K2 连续两次、再按一次K1 后看到的串行窗口现象,而实验
仿真板则是在键盘上按下字符1 之后看到的现象,灯亮为“0”,灯灭为“1”,因此灯的组合
为00110001,即0x31,这正是字符1 的ASCII 码值。
程序分析:本程序使用T1 作为波特率发生器,工作于方式2(8 位自动重装入方式),
波特率为19200,串行口工作于方式1,根据以上条件不难算出T1 的定时初值为0xfd,TMOD
应初始化为0x20,SMOD 应初始化为0x30,而PCON 中的SMOD 位必须置1,主程序main
的开头对这些初值进行了设置。设置好初值后,使用“TR1=1;”开启定时器1,使用“REN
=1;”允许接收数据,然后即进入无限循环中开始正常工作。在这个无限循环中首先调用键
盘程序,检测是否有键按下,如果有键按下,那么检测是否
K1 被按下,如果K1 被按下,则调用发送数据程序,将数据
0x55 送出,如果K2 被按下,则将数据0xAA 送出。然后检测
RI 是否等于1,如果RI 等于1,说明接收到字符,清RI,准
备下一次接收,并将接收到的数据送往P1 口显示。这样,一
次循环结束,继续开始下一次循环。
发送函数 SendData 中有只有一个参数Dat,即待发送的
字符,函数将待发送的字符送入SBUF 后,使用一个无限循
环等待发送的结束,在循环中通过检测TI 来判断数据是否发
送完毕,发送完毕使用break 语句退出循环。
如果使用 DSB-1A 型实验板做实验,需要用到一个PC
端的串口调试程序,并正确设置该调试程序的有关参数,这
里以“串口调试助手”软件为例,其参数设置如图5-5 所示。
由于该板占用了串口,因此做串口通讯类实验只能用下载全速运行的方法,具体步骤如下:
1.设置工程,在Debug 页将波特率设置为19200 上;
2.进入调试后全速运行程序,然后按Debug->Stop Runing 停止运行,实际上这不会中
断硬件电路的工作;
3.打开PC 端串口调试软件,正确设置串口参数,即可正常工作。
缓冲器,一个用作接收缓冲器,在完成串口的初始化后,只要将数据送入发送SBUF,即可
按设定好的波特率将数据发送出去,而在接收到数据后,可以从接收BUF 中读到接收到的
数据。下面我们通过一个例子来了解串行口编程的方法。
例 3 单片机P1 口接8 只发光二极管,P3.2~P3.5 接有K1~K4 共四个按键,使用串行
口编程,1)由PC 机控制单片机的P1 口,将PC 机送出的数以二进制形式显示在发光二极
管上;2)按下K1 向主机发送数字0x55,按下K2 向主机发送数字0xAA,使显示转下一行。
#define uchar unsigned char
#include "string.h"
#include "reg51.h"
void SendData(uchar Dat)
{ uchar i=0;
SBUF=Dat;
while(1){ if(TI)
{ TI=0;
break;}}
}
void mDelay(unsigned int DelayTime)
{ unsigned char j=0;
for(;DelayTime>0;DelayTime--)
{ for(j=0;j<125;j++)
{;}
}
}
uchar Key()
{ uchar KValue;
P3|=0x3e; //中间4 位置高电平
if((KValue=P3|0xe3)!=0xff)
{ mDelay(10);
if((KValue=P3|0xe3)!=0xff)
{ for(;;)
if((P3|0xe3)==0xff)
return(KValue);
}
}
return(0);
}
void main()
{ uchar KeyValue;
P1=0xff; //关闭P1 口接的所有灯
TMOD=0x20; //确定定时器工作模式
TH1=0xFD;
TL0=0xFD; //定时初值
PCON&=0x80; //SMOD=1
TR1=1; //开启定时器1
SCON=0x40; //串口工作方式1
REN=1; //允许接收
for(;;)
{ if(KeyValue=Key())
{ if((KeyValue|0xfb)!=0xff) //K1 按下
SendData(0x55);
if((KeyValue|0xf7)!=0xff)
SendData(0xaa);
}
if(RI)
{ P1=SBUF;
RI=0;
}
}
}
实现过程:输入程序,命名为exam53.c,建立名为exam53 的工程,将文件加入,设置
工程,使用实验仿真板进行调试。正确编译连接后进入调试,
打开实验仿真板,然后再点击viewserial #1 打开串行窗口,在
窗口空白处点右键,在弹出式菜单中选择“Hex Mode”如图3
所示。
单击实验仿真板的 K1 键和K2 键,即可看到在串行窗口中
分别出现55 和AA;单击串行窗口的空白处,使其变为活动窗
口,即可接收键盘输入,按下键盘上不同的字符键,可见实验仿真板上的LED 产生相应的
变化。图5-4 是按下K1 一次、K2 连续两次、再按一次K1 后看到的串行窗口现象,而实验
仿真板则是在键盘上按下字符1 之后看到的现象,灯亮为“0”,灯灭为“1”,因此灯的组合
为00110001,即0x31,这正是字符1 的ASCII 码值。
程序分析:本程序使用T1 作为波特率发生器,工作于方式2(8 位自动重装入方式),
波特率为19200,串行口工作于方式1,根据以上条件不难算出T1 的定时初值为0xfd,TMOD
应初始化为0x20,SMOD 应初始化为0x30,而PCON 中的SMOD 位必须置1,主程序main
的开头对这些初值进行了设置。设置好初值后,使用“TR1=1;”开启定时器1,使用“REN
=1;”允许接收数据,然后即进入无限循环中开始正常工作。在这个无限循环中首先调用键
盘程序,检测是否有键按下,如果有键按下,那么检测是否
K1 被按下,如果K1 被按下,则调用发送数据程序,将数据
0x55 送出,如果K2 被按下,则将数据0xAA 送出。然后检测
RI 是否等于1,如果RI 等于1,说明接收到字符,清RI,准
备下一次接收,并将接收到的数据送往P1 口显示。这样,一
次循环结束,继续开始下一次循环。
发送函数 SendData 中有只有一个参数Dat,即待发送的
字符,函数将待发送的字符送入SBUF 后,使用一个无限循
环等待发送的结束,在循环中通过检测TI 来判断数据是否发
送完毕,发送完毕使用break 语句退出循环。
如果使用 DSB-1A 型实验板做实验,需要用到一个PC
端的串口调试程序,并正确设置该调试程序的有关参数,这
里以“串口调试助手”软件为例,其参数设置如图5-5 所示。
由于该板占用了串口,因此做串口通讯类实验只能用下载全速运行的方法,具体步骤如下:
1.设置工程,在Debug 页将波特率设置为19200 上;
2.进入调试后全速运行程序,然后按Debug->Stop Runing 停止运行,实际上这不会中
断硬件电路的工作;
3.打开PC 端串口调试软件,正确设置串口参数,即可正常工作。