51单片机串口通信(波特率计算、字节发送、字符串发送、串口中断接收、回环测试)

难的东西学不会是因为简单的知识没学好

基础不牢,地动山摇

1.0通信

1.0.1通信的关键:

(1)事先约定
(2)基本信息单元
(3)有效信息编码,传输和解码

1.0.2通信的几个专业性概念

(1)同步和异步
(2)双工 半双工,单工
(3)并行通信和串行通信
(4)电平信号和差分信号

1.1串行通信

(1)串口通信
(2)一种特定的通信协议,一般叫串口通信,串行通信,UART USART等都指串口通信。
(3)这种通信的特点:异步,串行,全双工

1.1.1串行通信的工作方式:

(1)3根线(GND TXD RXD )或者9根线(DB9)
(2)发送方有发送移位寄存器,接收方有接收移位寄存器
(3)数据在发送方和接收方都是以字节为单位进行整字节处理的
(4)数据在通信线上是以位为单位进行传输的。

1.1.2串行通信的主要概念:

(1)起始位、数据位、奇偶校验位、停止位(一帧数据)
(2)波特率:通信的速率,每秒钟发送的bit位的个数,比如波特率9600就代表1秒钟发送9600个bit的二进制位。
(3)流控:速率协商,完备通信需要流控,现在基本不需要流控了

1.2 51单片机的串行通信

(1)寄存器
(2)查询方式与中断方式。一般接收用中断方式,查询方式用于发送。

1.3STC51单片机串行通信相关寄存器

(1)SCON 串行口控制寄存器
(2)PCON波特率选择特殊寄存器(感觉这个稍微有点坑)
(3)TMOD定时器模式选择寄存器(为设置波特率而设置的)

51单片机串口通信(波特率计算、字节发送、字符串发送、串口中断接收、回环测试)_第1张图片
看数据手册中写的这个鬼玩意。。SMOD=1,串口通信方式123波特率加倍,后边有来一句SMOD=0,各种方式波特率加倍。复位时SMOD=0.
那是不是默认情况下就是加倍呢?不是的,复位情况下是不加倍的。或者我拿的数据手册有错误,或者,我理解错了。。

我说几点:
(1)我们一般都用8位数据位模式,基本都使用方式1.所以我目前就管的方式1的情况。也实验的是方式1的情况。
(2)实验了。波特率加倍是SMOD=1. 波特率不加倍SMOD=0;
(3)计算波特率要注意:(不要觉得加倍了,我要4800的波特率就那2400来算,这样就错了。直接带公式算)
例如:我们要4800的波特率。晶振是11.0592MHZ,工作在12T模式下
如果波特率加倍:
我要4800的波特率就把4800带进去算。不要想着加倍了,那拿2400算除了就是4800。。。。。因为我之前搞错了
51单片机串口通信(波特率计算、字节发送、字符串发送、串口中断接收、回环测试)_第2张图片
波特率不加倍:
51单片机串口通信(波特率计算、字节发送、字符串发送、串口中断接收、回环测试)_第3张图片
说白了加倍不加倍只是给TH1 与TL1中装载的计数值不同而已。

1.3代码实战

#include 

// P3^0 RXD 
// P3^1 TXD

void delay(unsigned char t);
void UartSendByte(unsigned char c);
void UartInit(void);
void SendString(unsigned char *str);


void main(void)
{
	UartInit();
	while(1)
	{
		//UartSendByte('A');
		//	SendString("专业技能要强硬\r\n"); //发送中文是没有问题的。
		//我们发送中文,单片机发送的是啥它是不管的。最终编译器都会
	    //转化成bit位依次进行发送的.只不过一个英文字符占1个字节,也就是
		//8bit,而一个汉字占2字节,16bit的区别而已。

		delay(40);
	}
}

void UartInit(void)
{
	//我们这里要用串口通信的方式1.对应的SM0 SM1分别为0 1.
	//我们要配置成1位起始位 8位数据位 无奇偶校验位 1为停止位 波特率4800
	//SCON 寄存器的8个位分别是:B7-B0依次为:SM0/FE SM1 SM2 REN TB8 RB8 TI RI
	// SM0/FE SM1 SM2 REN TB8 RB8 TI RI
	//	0	1	  0		1   0  0   0  0
	//SM0 SM1 共同控制串口的工作方式。设置为方式1,8位UART波特率可变。为 0 1
	//但是要注意。SM1要与PCON的第六位有点关系。要注意
	// SM2 是允许方式2或者方式3多级通信的控制位,这里not care 那就为0吧
	// REN 允许或禁止串行接收控制位。我们需要串口接收。REN= 1表示打开。
	//TB8 RB8 都是设置方式2与方式3的。这里统统设置为0
	//TI 发送中断请求位,我们发送一般都用查询方式,所以为0就ok.
	//						  
	//RI 串口接收完一帧数据后,由内部硬件置位,必须又软件复位。
	SCON = 0x50;		//串行口控制寄存器

	PCON = 0x80;		//波特率选择特殊功能寄存器, 我们选择波特率加倍
						//这里的意思就是我们要4800的波特率,那么按2400算就可以了。


   	TMOD = 0x20; //定时器8为自动重装载定时器
	//我们要设置波特率,工作在12T模式下, 定时器1的溢出率为 晶振频率/12/(256-TH1)
	//波特率为:2^SMOD /32 *  晶振频率/12/(256-TH1)
	TH1 = 244;
	TL1 = 244;

//	TH1 = 250;
//	TL1 = 250;

	//定时器1是不是要打开呢?

	TR1 = 1;
	//我们要串口中断接收,那么就要打开串口中断
   	ES = 1;	//串口中断开关
	EA= 1; //总中断开关
}

void UartSendByte(unsigned char c)
{
	//我们要发送,要把要发送的数据放入发送移位寄存器中,即SBUF 。
	//但是我们发送前需要检查串口这个时候有么有在忙,是不是正在发呢?要等上一次发
	//完我们才能开始下一次发送。
	SBUF = c;

	while(!TI); //一次发送结束时,硬件就自动置位了。
	

	TI = 0;	//软件复位	
}

void delay(unsigned char t)
{
	unsigned char i,j,k;
	for(i=0; i<200; i++)
		//for(j=0; j<100; j++)
			for(k=0; k

你可能感兴趣的:(51单片机,51单片机串口通信,51单片机波特率计算,51单片机字符串函数发送,51单片机回环测试)