基于Proteus与keil联合仿真的51单片机学习记录(六)(串口通信)
一、设计要求
不用串口中断,用工作方式1实现数据发送,用proteus中的虚拟终端来接受数据。发送大写的26个字母,每间隔100ms发送一个字母;26个字母发送完成后,每间隔3s再次循环发送。波特率设置为9 600,因为我们用的虚拟终端默认的波特率就是9 600。
二、程序设计
首先是定时器和串口的初始化(由于我们使用的是串口的工作模式1,其波特率与定时器1的溢出率有关),工作模式1的波特率计算公式为:BAUD = (2 SMOD/32)×(T1溢出率),此时,SMOD = 0,而TI的溢出率就是定时器T1每秒的溢出次数,当定时器的初值为n,则T1经过(256-n)个机器周期就会溢出一次,而一个机器周期等于12个晶振周期,也就是(256-n) ×12/fosc溢出一次,那么T1的溢出率就是fosc/[12×(256-n)],这样推出公式就是:fosc/[12×(256-n)]=32×9 600。转换一下:fosc=32× 9 600×12×(256-n),其中fosc是晶振频率,9 600是目标波特率,n是T1要设定的初始值。解得定时器T1初始值为253。
接着是串口的初始化,串口初始化中,直接让串口寄存器SCON = 0x40;即SMO=0,SM1=1,为工作模式1。
/*****************************************************************************
******************************************************************************************
***
* 文件名:main.c
* 说 明:串口通信
******************************************************************************
******************************************************************************************
**/
#include "reg51.h"
#include "main.h"
#include "delay.h"
//**数码管显示**//
// uchar code DIS_CODE[12] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF,0x0C};
// uchar g_ucNum;
/*****************************************************************************
******************************************************************************************
***
* 函数名:timer1_int(),定时器初始化
* 参 数:空
* 返回值:无
******************************************************************************
******************************************************************************************
***/
void timer1_int()
{
TMOD = 0x20;
TL1 = 0xFD;
TH1 = 0xFD;
TR1 = 1;
}
// /*****************************************************************************
//******************************************************************************************
//***
// * 函数名:serial_int(),串口初始化
// * 参 数:num
// * 返回值:无
// ******************************************************************************
//******************************************************************************************
//***/
void serial_int()
{
// PCON = 1;
SCON = 0x40;
}
/*****************************************************************************
******************************************************************************************
***
* 函数名:主函数
* 参 数:无
* 返回值:无
******************************************************************************
******************************************************************************************
***/
void main (void)
{
uchar send_data = 0; //发送数据
uchar i = 0;
timer1_int(); //初始化定时器T1
serial_int(); //串口初始化
// IE = 0x00; //关闭所有中断
while(1)
{
send_data = 'A';
for(i=0;i<26;i++)
{
SBUF = send_data;
while(TI == 0); //等待发送标志位变为1,退出此循环,恢复正常
TI = 0; //此处俩语句意为,将SBUF中的数据发送完毕后将TI置0
//如果用中断来发送的话,要在中断服务函数中将此标志位清零
send_data++;
delay_ms(100);
}
delay_ms(3000);
}
}
三、硬件设计
四、知识补充
1.网络传输的两种方式
2.与串口有关的寄存器
1.电源控制寄存器PCON(Power Control Register),地址是0x87。
IDL:空闲模式设定位。该位设置为1,单片机进入空闲(Idle)模式,除CPU不工作外,其余仍然工作,在空闲模式下可由任意一个中断或硬件复位唤醒;该位设为0,单片机处于正常工作状态。
PD:掉电模式设定位。该位设置为1,单片机进入掉电模(PowerDown),可由外部中断或硬件复位模式唤醒,进入掉电模式后,外部晶振停振,CPU、定时器、串口全部停止工作,只有外部中断继续工作;该位设为0,单片机处于正常模式。
GF0、GF1:两个通用工作状态标志,用户可以*使用。
SMOD:串口波特率控制位。该位设置为1,串口工作在方式1、2、3时,串口波特率加倍;该位设置为0,串口工作在方式1、2、3时,波特率正常。
2.串行口控制寄存器SCON
串口的工作模式
3.数据缓冲寄存器SBUF
虽然SBUF只有一个地址,但实际有两个独立的缓冲寄存器都叫SBUF,一个用做发送缓冲器,一个用做接收缓冲器。在程序中无论接收缓冲器还是发送缓冲器都用SBUF,不过不要认为这样会引起数据覆盖,因为在物理上其实是两个寄存器,所以是不会发生数据混乱的。
工作方式0的波特率:BAUD = fosc/12
工作方式1的波特率:BAUD = (2 SMOD/32)×(T1溢出率)
工作方式2的波特率:BAUD = (2 SMOD/64)×fosc
工作方式3的波特率:BAUD = (2 SMOD/32)×(T1溢出率)
串口的设置:
下一篇: 用JAVA签发数字证书