ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【蓝桥杯】串口通信详解附双串口代码

2022-02-01 22:58:18  阅读:521  来源: 互联网

标签:附双 定时器 TI 串行口 蓝桥 串口 波特率 接收


目录


IAP15F2K61S2单片机拥有两个全双工串口通信接口(串口1和串口2)

1、串口相关寄存器

在这里插入图片描述
每个串口都有2个数据缓冲器、一个移位寄存器、一个串行控制器和一个波特率发生器

1.1数据缓冲器SBUF

这是两个物理上独立的接收、发送缓冲器,可同时发送、接收数据。
发送缓冲器只写不能读,接收缓冲器只读不能写。因此两个缓冲器共用一个地址码
从STC15F2K60S2这个头文件的190行和192行可以看出串行口1SBUF地址是99H,串行口2S2UBF地址是9BH。

1.2串行口(工作方式)控制寄存器SCON

在这里插入图片描述
IAP15F2K61S2 单片机的串行口有 4 种工作方式。
(1)SM0、SM1控制工作方式
在这里插入图片描述
方式0:同步串行通信
方式1:异步串行通信8位,串行口1波特率取决于定时器T1,串行口1波特率取决于定时器T2,波特率都可变
方式2:异步串行通信9位(多一个奇偶检验位、或地址帧/数据帧标识位),波特率取决于内部晶振,波特率不可变
方式3:异步串行通信9位(多一个奇偶检验位、或地址帧/数据帧标识位),串行口1波特率取决于定时器T1,串行口1波特率取决于定时器T2,波特率可变
(2)SM2多机通信控制位,用来控制是否激活RI
①当串口以方式2或方式3接收时:
如果SM2 = 1,则只有当接收到的第9位数据(RB8)为“1”时,才使RI置“1”,产生中断请求,并将接收到的前8位数据送入SBUF。当接收到的第9位数据(RB8)为“0”时,不使RI置“1”,并将接收到的前8位数据丢弃。
当SM2 = 0时,则不论第9位数据是“1”还是“0”,都将前8位数据送入SBUF中,并使RI置“1”,产生中断请求。
②方式0、方式1时,SM2 = 0。
(3)TB8—发送的第9位数据
在多机通信中用来表示主机发送的是地址帧还是数据帧,TB8=1为地址帧,TB8=0为数据帧。
双机串行通信时,为奇偶校验位。
(4)RB8—接收的第9位数据
方式0,不使用RB8。
方式1中,RB8是接收到的停止位。
方式2和方式3,RB8存放接收到的第9位数据。作为地址帧/数据帧标识位、或奇偶校验位。
(5)REN—允许串行接收位。
由软件置“1”或清“0”。
REN=1,允许串行口接收数据。
REN=0,禁止串行口接收数据。
(6)TI—发送中断标志位
TI =1,表示一帧数据发送结束。TI状态可供软件查询,也可申请中断。CPU响应中断后,在中断服务程序中向SBUF写入要发送的下一帧数据。
方式0,串行发送的第8位数据结束时TI由硬件置“1”,
在其他方式中,串行口发送停止位的开始时置TI 为“1”。
TI必须由软件清“0”
(7)RI—接收中断标志位
RI=1,表示一帧数据接收完毕,并申请中断,要求CPU从接收SBUF取走数据。该位的状态也可供软件查询。
方式0时,接收完第8位数据时,RI由硬件置“1”。
在其他工作方式中,串行接收到停止位时,该位置“1”。

RI必须由软件清“0”。

1.3特殊功能寄存器PCON

在这里插入图片描述
PCON中仅最高位SMOD与串口有关:SMOD:波特率倍增位。
方式0时(同步),此位未采用,即波特率的速度不受SMOD影响。
方式1、2、3时,SMOD=1时的波特率比SMOD=0时的波特率速度提高一倍。所以称SMOD位为波特率倍增位。

2、波特率

异步通信没有时钟线的约束,通信双方都有自己的通信频率(波特率),且双方的波特率要相同。
波特率的设置 (fosc:frequency oscillate晶振频率)

方式0的波特率 = fosc/12

方式2的波特率 =(2SMOD/64*fosc

方式1的波特率 =(2SMOD/32)*(T溢出率)

方式3的波特率 =(2SMOD/32)*(T溢出率)
一般我们使用定时器作为波特率的发生器,进行串口通信,如果两个串口同时使用,那么我们需要准备两个波特率发生器
串行口1使用定时器1作为波特率发生器
串行口2使用定时器2作为波特率发生器
下面进行串口通信波特率可变的函数编写(两个串口全部使用)
串口2的S2CON 的8个位没有在头文件定义,要自己定义

#include <STC15F2K60S2.H>
#include <stdio.h>
#define S2RI  0x01              
#define S2TI  0x02              
#define S2RB8 0x04             
#define S2TB8 0x08             
#define S2_S0 0x01
//定义接收数组
unsigned char Buffer1[5]={0};//串口1接收数组
unsigned char Buffer2[5]={0};//串口2接收数组
unsigned char buf[12]={0}; //发送数组
unsigned char i=0,j=0;
void Uart1Init(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器1时钟为Fosc,即1T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xC7;		//设定定时初值
	TH1 = 0xFE;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	EA=1;
    ES=1;
}
void Uart2Init(void)		//9600bps@12.000MHz
{
	S2CON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x04;		//定时器2时钟为Fosc,即1T
	T2L = 0xC7;		//设定定时初值
	T2H = 0xFE;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
}
//串口1字符串发送
void Uart_Sendstring(unsigned char *pucStr) 
{ 
 while(*pucStr != '\0') 
 { 
	 SBUF = *pucStr; 
	 while(TI == 0); 
	 TI = 0; 
	 pucStr++; 
 } 
}
//主函数
void  main()
{
	Uart1Init();
	Uart2Init();
	sprintf  (buf,"%u","lianglujun");
	while(1)
	{
	  
	}
}

//中断接收函数
void UART1receive() interrupt 4
{
	 if(RI)
	 { 
		  Buffer1[i]=SBUF;
		  RI=0;
	 }
	
	 SBUF=Buffer1[i]; 	//TI =1,表示一帧数据发送结束。TI状态可供软件查询,也可申请中断
	 while(!TI)	;
	 TI=0;
	 i++;
	 if(i>=5){
	 	i=0;
	 }
}
//中断函数
void UART2receive() interrupt 8	using 2
{
    //接收标记,S2RI=1,表示一帧数据接收完毕,并申请中断
	//因为头文件对串口2缺少定义,这里采用一些位操作
	 if(S2CON &S2RI)
	 { 
		  Buffer2[j]=S2BUF;
		  S2CON &= ~S2RI;
	 }
	
	 S2BUF=Buffer2[j];//发送数据
	 while(!S2CON & S2TI);
	 S2CON &= ~S2TI;
	 j++;
	 if(j>=5){
	 	j=0;
	 }
}		 

标签:附双,定时器,TI,串行口,蓝桥,串口,波特率,接收
来源: https://blog.csdn.net/C_white_llj/article/details/122765426

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有