- 波特率
1波特=1字节/秒
51串行口工作的4种方式
由波特率和晶振确定TH1 & TH0
溢出率=1/每溢出一次需要的时间=1 / T
SMOD为PCON寄存器(不可位寻址)中一位,默认为0
若已知晶振为11.0592MHZ ,波特率为9600
则:设TH0填入X,则溢出需要时间T=(256-X)* (12*1/11.0592M)
1/(T*32)=9600
X=253=0xfd
注:若X不变,SMOD=1,则波特率增加一倍
若为12MHZ ,9600,0xfd,测试后无效
相关寄存器
- SCON(可位寻址)
- SM0 , SM1 串行口模式设置,通常为方式1即01
- SM2 用于多机通信
- REN 是否允许接收(1收0不收)
- TB8 方式2,3中发送数据的第9位,方式0,1 无用
- RB8 方式2,3中接受数据的第9位,方式1且SM2=0时,RB8为接收到的停止位
- TI / RI 中断标志位,硬件置1,手动清0
操作基本流程
1. 设置T1- 设置T1工作模式为8位自动重装(TH1存储值,TL1溢出)-----一般为 TMOD=0x20
- 装初值 ----- 11.0592M或12M 在9600下,皆装0xfd,即TH1=0xfd,TL1=0xfd
- 启动T1 TR1=1
2. 设置串口
- 设置串口工作模式 --------一般为方式1, SM0=0,SM1=1;
- 打开中断 EA=1,ES=1
SBUF 同地址,不同硬件
发送:SBUF=DATA
接受:DATA=SBUF
- 中断方式(!发送也会触发中断)
- data=SBUF
- 中断号4
- 查询方式
- if/while (RI==1)
- while(!TI)判断是否发送完毕
/*
#串口初始化
****重要:***********************
适用于:
晶振12M,波特率2400
********************************
****简介:**********************
定时器模式:T1八位自动重装
串口工作模式:1
中断:开串口中断,关定时器1中断
********************************
*/
void serialInit2400(){
TMOD&=0x0f;
TMOD|=0x20; //设置T1为八位自动重装 SM0=1,SM1=0!,【GATE=0(不受外部中断限制)】,【C/T=0(定时器模式)】
//TMOD=0x20;
TH1=0xf3; //晶振12M,波特率2400
TL1=0xf3;
TR1=1; //启动定时器1
SM0=0; //设置串口工作模式为模式1
SM1=1;
EA=1; //打开总总中断
ES=1; //打开串口中断
REN=1; //允许串口接收
}
/*
#串口初始化
****重要:***********************
适用于:
晶振11.0592M,波特率9600
********************************
****简介:**********************
定时器模式:T1八位自动重装
串口工作模式:1
中断:开串口中断,关定时器1中断
********************************
*/
void serialInit9600(){
TMOD&=0x0f;
TMOD|=0x20; //设置T1为八位自动重装 SM0=1,SM1=0!,【GATE=0(不受外部中断限制)】,【C/T=0(定时器模式)】
TH1=0xfd; //晶振11.0592M,波特率9600
TL1=0xfd;
TR1=1; //启动定时器1
SM0=0; //设置串口工作模式为模式1
SM1=1;
EA=1; //打开总总中断
ES=1; //打开串口中断
REN=1; //允许串口接收
}
void serialInit19200(){
TMOD&=0x0f;
TMOD|=0x20; //设置T1为八位自动重装 SM0=1,SM1=0!,【GATE=0(不受外部中断限制)】,【C/T=0(定时器模式)】
TH1=0xfd; //晶振11.0592M,波特率19200
TL1=0xfd;
TR1=1; //启动定时器1
PCON=PCON|0x80;
SM0=0; //设置串口工作模式为模式1
SM1=1;
EA=1; //打开总总中断
ES=1; //打开串口中断
REN=1; //允许串口接收
}
///********************************************************************/
sfr T2MOD = 0xC9; // 定时器2
//************************定时器2初始化*********************************** /
#define MSB_reload_value 0xff // msb reload value exemple 高位重载值
#define LSB_reload_value 0xfd // lsb reload value exemple 低位重载值
// 这里波特率为 115200
/************************************************************************************************/
void serialInit115200(void)
{
// T2OE=0;定时器2输出不允许
T2MOD = 0x01; // DCEN=1;可以设置为向上/下计数:此程序中为向上达到0xff时溢出
T2CON = 0x30; // TF2 EXF2 RCLK TCLK EXEN2 TR2 C_T2 CP_RL2
// EXF2=0; 定时器2外部标志位清除
// TCLK=0;RCLK=0; 不用于波特率发生器
// EXEN2=0; T2EX 视T2EX(P1.1)端信号无效
// C_T2=0; 定时模式
// CP_RL2=0; 重载模式
TH2 = MSB_reload_value; // Init msb_value 填入初始化值
TL2 = LSB_reload_value; // Init lsb_value
RCAP2H = MSB_reload_value; // reload msb_value重载值
RCAP2L = LSB_reload_value; // reload lsb_value
SCON |= 0x50; // 0101 0000 串口方式1,允许接收
TR2 = 1;
}
/*
#串口发送字符串
********************************
输入:
【字符串】,【长度】
*********************************
*/
void serialSendString(unsigned char x[],unsigned char len)
{
int i=0;
for(i=0;i<len;i++)
{
ES=0;
SBUF=x[i];
while(!TI);
TI=0;
ES=1;
}
}
串口输出换行
void serialNext()
{
serialSendString("\n",1);
}
//串口输出1个字节
void serialSendByte(unsigned char x)
{
ES=0;
SBUF=x;
while(!TI);
TI=0;
ES=1;
}