(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;
}