学习记录
#include "reg52.h"
#include "stdio.h"
#include "intrins.h"
/********************************
Fm = Fosc/12 ===>>> Tm = 12Tosc @11.0592MHz
********************************/
char dat = 65;
int num=0;
void delayms(int x)
{
int t;
for(;x>0;--x)
for(t=110;t>0;--t);
}
void send_byte(unsigned char str)
{
SBUF = str;
while(TI==0); //检测0到1的跳变
TI = 0;
}
void send_string(unsigned char *str)
{
while(*str!='\0')
{
send_byte(*(str++)); //str++,将地址自加1
}
}
main()
{
//T0方式0下为13位(由低8位和高5位组成)
//2^13 = 8192
//TH0 = (8192 - 4608)/32; //因为在方式0下,TH0的8位全被使用,TL0只有低5位被使用
//TL0 = (8192 - 4608)%32; //只访问低5位bit位
P2 = 0XAA;
PCON = 0X00; //SMOD = 0,不倍频
TMOD = 0X20; //T1为8位自动重载波特率发生器,T0工作方式为0(13位计数器)
//T0也可以在方式1下工作,不对T1产生影响
//TMOD = 0X23; //当T0工作在方式3下,T1不计数(此时为波特率发生器),T0被分成了两个独立的计数器TH0和TL0
SCON = 0x50; //T1工作在方式1下,10位串口,可变波特率
EA = 1; ET0 = 1; ES = 1; //T0工作在方式0下
TR0 = 1; TR1 = 1;
TH0 = (8192 - 4608)/32; //左移5位:8192/32 = 256
TL0 = (8192 - 4608)%32; //访问低5位
//SCON方式1下:波特率 = (2^SMOD/32)*T1溢出率,T1溢出率 = Fosc/(12*(256 - TL1))
TH1 = 256 - 3; //Fosc/(2^SMOD*32*12*Baud) = 3,当波特率为9600bps时 ,SMOD = 0
TL1 = 256 - 3; //TL1负责计数,当计数溢出后TH1又自动将值赋给TL1
while(1)
{
TI = 1;
printf("Hello world\n");
while(TI==0); //检测0到1的跳变
TI = 0;
delayms(1000);
send_string("Ho_Yim\n"); //换行没有效果
delayms(1000);
}
}
//定时5ms == 4608*1.085us
void T0_timer(void) interrupt 1 //当T1为工作方式2时,T0在方式1,2下均能正常工作
{
//此时TH0最高的3位不能用,故计数最大值是8192
TH0 = (8192 - 4608)/32; //左移5位:8192/32 = 256
TL0 = (8192 - 4608)%32; //只访问低5位
++num;
if(num==200) //1000ms
{
num = 0;
P2 =~P2; //LED灯
}
}
void T1_usart(void) interrupt 4 //接收中断
{
if(RI)
{
dat = SBUF;
RI = 0;
switch(dat)
{
case 1:TR0 = 1;break;
case 2:TR0 = 0;break;
}
}
}
/************************************************************************************************************************************
总结:
1.当SCON被配置为0x50(SM0:0 SM1:1 SM2:0 REN:1)时,为工作方式2,波特率=(2^SMOD/32)*T1溢出率,T1溢出率 = Fosc/(12*(256 - TL1))
进而计算出TH1(TL1会自动被配置)。
2.当T1工作在方式2下时(8位自动重装值,TH1在TL1计数完成后自动将值赋给TL1)。T0在方式1,2下均可正常工作,不对T1产生影响
此时T1工作在方式2下时,要想使用串口还要将TR1置1。波特率计算参考1
3.当T0工作在方式3下时(T0被分为两个独立的计数器),T1停止计数(此时只能作为波特率发生器),
如TMOD = 0X23(T1还是要在方式2下工作),波特率参考1
4.对比:
TMOD = 0X20; TR1 = 1; | TMOD = 0X23;
SCON = 0x50; | SCON = 0X50;
EA = 1; ES = 1; | EA = 1; ES = 1;
TH1 = 256 - 3; | TH1 = 256 - 3;
TL1 = 256 - 3; | TL1 = 256 - 3;
以上两种均能成功初始化串口!
************************************************************************************************************************************/