在串行通信中,收发双方对发送或接收数据的速率要有约定,才能使上位机和嵌入式系统进行通信。C51单片机可设置四种工作方式,其中方式0和方式2的波特率是固定的,而方式1和方式3的波特率是可变的,由定时器T1的溢出率来决定。串行口的四种工作方式对应三种波特率。由于输入的移位时钟的来源不同,所以,各种方式的波特率计算公式也不相同。
方式0的波特率 = fosc/12
方式2的波特率 =(2SMOD/64)· fosc
方式1的波特率 =(2SMOD/32)·(T1溢出率)
方式3的波特率 =(2SMOD/32)·(T1溢出率)
方式0的波特率 = fosc/12
方式2的波特率 =(2SMOD/64)· fosc
方式1的波特率 =(2SMOD/32)·(T1溢出率)
方式3的波特率 =(2SMOD/32)·(T1溢出率)
T1溢出率是指定时器在计数达到满值后产生中断的频率,使用其作为波特率发生器则相当方便。
T1 溢出率 = fosc /{12×[256 -(TH1)]}
以方式1为例,假设晶振频率为11.0592MHz,则波特率计算如下:
Baud=(2SMOD/32)·(T1溢出率)=(2SMOD/32)·fosc /{12×[256 -(TH1)]}
SMOD波特率倍增位。在串行口方式1时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍,复位时,SMOD=0。
Baud=(2/32)·(11059200/12x(256-TH1))
若Baud为标准9600,那么T1的TH1装载初值为:
TH1=0XFDH
实验设计
电路连接图如下:
通信程序如下:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define uint unsigned int
void beeper(uchar sig);
void delay(uint z);
void init();
void delay(uint z);
void init();
sbit beep=P2^3;
uchar info;
uchar flag;
uchar info;
uchar flag;
int main() {
init();
while(1) {
if(flag==1)
beeper(info);
}
}
init();
while(1) {
if(flag==1)
beeper(info);
}
}
void init() {
TMOD=0x20; /* T1定时器方式2*/
TH1=0xFD;
TL1=0xFD;
TR1=1; /* 启动T1定期器 */
SM0=0; /* 设置串口工作方式1*/
SM1=1;
REN=1; /* 缓冲区接收使能 */
EA=1; /* 开总中断 */
ES=1; /* 串行中断 */
flag=0;
}
void ser() interrupt 4 { /* 中断程序 */
RI=0;
flag=1;
info=SBUF;
}
TMOD=0x20; /* T1定时器方式2*/
TH1=0xFD;
TL1=0xFD;
TR1=1; /* 启动T1定期器 */
SM0=0; /* 设置串口工作方式1*/
SM1=1;
REN=1; /* 缓冲区接收使能 */
EA=1; /* 开总中断 */
ES=1; /* 串行中断 */
flag=0;
}
void ser() interrupt 4 { /* 中断程序 */
RI=0;
flag=1;
info=SBUF;
}
void beeper(uchar sig) {
flag=0;
switch(sig) {
case '1':
beep=0;
delay(40);
beep=1;
delay(40);
break;
case '2':
beep=0;
elay(20);
beep=1;
delay(20);
break;
case '3':
beep=0;
delay(10);
beep=1;
delay(10);
break;
default:
beep=1;
break;
}
}
flag=0;
switch(sig) {
case '1':
beep=0;
delay(40);
beep=1;
delay(40);
break;
case '2':
beep=0;
elay(20);
beep=1;
delay(20);
break;
case '3':
beep=0;
delay(10);
beep=1;
delay(10);
break;
default:
beep=1;
break;
}
}
void delay(uint z) {
uint i,j;
for(i=1;i<500;i++)
for(j=1;j<z;j++);
}
uint i,j;
for(i=1;i<500;i++)
for(j=1;j<z;j++);
}
发表评论 评论 (6 个评论)