(1)SCON
是一个特殊功能寄存器,用以设定串行口的工作方式、接收
/
发送控制以及设置状态标志:
SCON 位 7 6 5 4 3 2 1 0
位于98h SM0 SM1 SM2 REN TB8 RB8 TI RI
1.SM0与SM1是工作方式控制位
2.SM2与方式有关,一般只用方式1所以,SM2一般用不到,
3.REN
,允许串行接收位
。由软件置
REN=1
,则启动串行口接收数据;若软件置
REN=0
,则禁止接收。
4.TB8
,在方式
2
或方式
3
中,是发送数据的第九
位
,可以用软件规定其作用。可以用作数据的奇
偶校验位,或在多机通信中,作为地址帧
/
数据帧
的标志位。
在方式
0
和方式
1
中,该位未用。
5.RB8
,在方式
2
或方式
3
中,是接收到数据的第九位
,作为奇偶校验位或地址帧
/
数据帧的标志位。在方
式
1
时,若
SM2=0
,则
RB8
是接收到的停止位。
6.TI
,发送中断标志位
。在方式
0
时,当串行发送第
8
位数据结束时,或在其它方式,串行发送停止位的开
始时,由内部硬件使
TI
置
1
,向
CPU
发中断申请。在中断服务程序中,必须用软件将其清
0
,取消此中
断申请。
7.RI
,接收中断标志位
。在方式
0
时,当串行接收第
8
位数据结束时,或在其它方式,串行接收停止位的
中间时,由内部硬件使
RI
置
1
,向
CPU
发中断申请。也必须在中断服务程序中,用软件将其清
0
,取消
此中断申请。
#### 如果使用方式一的话,只要设置SM0=0,SM1=1选择方式一;REN=1启动串行口接收数据;TI跟RI,
在中断服务程序中,必须用软件将其清
0
,取消此中断申请。
(2)
PCON
中只有一位
SMOD
与串行口工作有关
:
SMOD
(
PCON.7
)
波特率倍增位。在串行口方式
1
、方式
2
、方式
3
时,波特率与
SMOD
有关,当
SMOD=1
时,波特率提高一倍。复位
时,
SMOD=0
。
SBUF可读可写
串行口工作之前,应对其进行初始化,主要是设
置产生波特率的定时器
1
、串行口控制和中断控制。
具体步骤如下:
§
确定
T1
的工作方式
(编程
TMOD
寄存器);/*TMOD寄存器 有8位,低4位是控制定时器0的,高四位是控制定时器1的,分别为GATE(初始化时候是0,不用管它)、C/t(定时计数选择位,0位定时器)、M1、M0(工作方式选择位)*/
§
计算
T1
的初值
,装载
TH1
、
TL1
; /*
T1
溢出率
= fosc /{12
×
[256
-(
TH1
)
]} 其中fosc为单片机的主频
*/
§
启动
T1
(编程
TCON
中的
TR1
位);
§
确定
串行口控制
(编程
SCON
寄存器);
串行口在中断方式工作时,要进行中断设置(编
程
IE
、
IP
寄存器)。
方式
0
的波特率
= fosc/12
方式
2
的波特率
=
(
2SMOD
/64
)
· fosc
方式
1
的波特率
=
(
2SMOD
/32
)
·
(
T1
溢出率)
方式
3
的波特率
=
(
2SMOD
/32
)
·
(
T1
溢出率)
IE寄存器:
EA:全局中断允许位,要想打开任何中断,EA都必须为1.然后再允许某个特定的中断。
ES:串行口中断允许。ES=1时,串口接收或者发送完成数据以后会引起中断(TI=1,或者RI=1)
ET1:定时计数器1中断允许。ET1=1时,当定时计数器1计数满,溢出后引起中断,可在中断函数中处理定时器。
EX1:外部中断1允许位。EX=1时,外部条边沿(或者电平)中断信号来后,会引起外部中断,可在外部中断函数中处理事件。
ET0/EX0功能跟上面一样,只是换了个定时器或者外部中断。
ES:串行口中断允许。ES=1时,串口接收或者发送完成数据以后会引起中断(TI=1,或者RI=1)
ET1:定时计数器1中断允许。ET1=1时,当定时计数器1计数满,溢出后引起中断,可在中断函数中处理定时器。
EX1:外部中断1允许位。EX=1时,外部条边沿(或者电平)中断信号来后,会引起外部中断,可在外部中断函数中处理事件。
ET0/EX0功能跟上面一样,只是换了个定时器或者外部中断。
中断优先级寄存器IP
#include<reg52.h>
unsigned char flag,a;
void main()
{
TMOD=0x20;//设置定时器1为工作方式2
TH1=0xfd;
TL1=0xfd;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
while(1)
{
/* if(RI==1)
{
RI=0;
P1=SBUF;
}*/
if(flag==1)
{
ES=0;
flag=0;
SBUF='1';//28;
while(!TI);
TI=0;
SBUF='2';//28;
while(!TI);
TI=0;
SBUF='3';//28;
while(!TI);
TI=0;
ES=1;
}
}
}
void ser() interrupt 4
{
RI=0;
// P1=SBUF;
a=SBUF;
flag=1;
}
/*
2012年3月21日21:23:36:
此程序为由串口调试工具向单片机发送数据,单片机通过led灯显示发送的数据
如发送ff,则灯全灭
发送fe,点亮第一个灯
*/
#include <reg52.h>
void init();
void main()
{
init();
while(1)
{
if(RI==1) //串行接收完毕时,由内部硬件使RI置1。检测是否接受完毕
{
P2=SBUF; //接收完毕后将接收到的SBUF赋给P2口
}
}
}
void init() //定时器及串口初始化
{
TMOD=0x20; //设置定时器1为工作方式2
TH1=0xfd; //定时器装初值
TL1=0xfd;
TR1=1; //开定时器
REN=1; //(SCON寄存器中)允许串行接收
SM0=0; //设置工作方式控制位,选择为工作方式1
SM1=1;
EA=1; //开总中断
ES=1; //开串口中断
}
void ser() interrupt 4 //中断关服务函数
{
RI=0; /*串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请,
须在中断服务程序中,用软件将其清0,取消此中断申请。*/
P2=SBUF; //将接收数据缓冲器SBUF中接受的数据传给P2口
}
/*
2012年3月21日21:23:36:
此程序为由串口调试工具向单片机发送数据,单片机通过led灯显示发送的数据
如发送ff,则灯全灭
发送fe,点亮第一个灯
并且单片机接受发来的数据以后,在发回给上位机显示!
*/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
void init();
uchar a,flag;
void main()
{
init();
while(1)
{
if(flag==1)
{
ES=0; //关串行口中断 要使其发送数据时候关中断
flag=0;
SBUF=a;
while(!TI); //检测是否发完
TI=0; //发完莫忘TI清零!!!
ES=1; //开串口中断
}
}
}
void init() //定时器及串口初始化
{
TMOD=0x20; //设置定时器1为工作方式2
TH1=0xfd; //定时器装初值
TL1=0xfd;
TR1=1; //开定时器
REN=1; //(SCON寄存器中)允许串行接收
SM0=0; //设置工作方式控制位,选择为工作方式1
SM1=1;
EA=1; //开总中断
ES=1; //开串口中断
}
void ser() interrupt 4 //中断关服务函数
{
RI=0; /*串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请,
须在中断服务程序中,用软件将其清0,取消此中断申请。*/
P2=SBUF; //将接收数据缓冲器SBUF中接受的数据传给P2口
a=SBUF;
flag=1;
}