当前位置:网站首页>学习记录:USART—串口通讯

学习记录:USART—串口通讯

2022-07-06 09:25:00 Bitter tea seeds

目录

1.串口通讯协议简介

1.1物理层

1.2 电平标准

2.协议层

 3.printf函数的支持代码

 4.usart.h程序

 5.main.c主函数

6.实验现象 


1.串口通讯协议简介

对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。 

1.1物理层

主要是了解:RS-232 标准,RS-232 标准主要规定了信号的用途、通讯接口以及信号的电平标准。 

使用RS-232标准的串口设备间常见的通讯结构,如下图所示

在上面的通讯方式中,两个通讯设备的“DB9 接口”之间通过串口信号线建立起连接,串口信号线中使用“RS-232 标准”传输数据信号。由于 RS-232 电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个“电平转换芯片”转换成控制器能识别的“TTL 标准”的电平信号,才能实现通讯。 

1.2 电平标准

根据通讯使用的电平标准不同,串口通讯可分为 TTL 标准及 RS-232 标准;

常见的电子电路中常使用 TTL 的电平标准,理想状态下,使用 5V 表示二进制逻辑 1,使用 0V 表示逻辑 0;而为了增加串口通讯的远距离传输及抗干扰能力,RS-232使用-15V 表示逻辑 1, +15V 表示逻辑 0。使用 RS232 与 TTL 电平校准表示同一个信号时的对比,如下图所示。

因为控制器一般使用 TTL 电平标准,所以常常会使用 MA3232 芯片对 TTL 及 RS-232 电平的信号进行互相转换。

2.协议层

串口通讯的数据包由发送设备通过自身的 TXD 接口传输到接收设备的 RXD 接口。在串口通讯的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据,

 3.printf函数的支持代码

//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 

 4.usart.h程序

定义最大接收字节数 200;

#define USART_REC_LEN  			200  

接收缓冲,最大USART_REC_LEN个字节.末字节为换行符;

extern u8  USART_RX_BUF[USART_REC_LEN]; 

接收状态标记  ;

extern u16 USART_RX_STA;

使能(1)/禁止(0)串口1接收 ;

#define EN_USART1_RX 			1		

usart.c和usart.h函数程序在专栏Stm32学习笔记中的博客学习记录:串口通信和遇到的错误解决方法 有写。

 5.main.c主函数

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"

 int main(void)
 {		
		u16 t;  
		u16 len;	
		u16 times=0;
		delay_init();	    	 //延时函数初始化	  
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
		uart_init(115200);	 //串口初始化为115200
		LED_Init();			     //LED端口初始化
		KEY_Init();          //初始化与按键连接的硬件接口
		while(1)
		{
			if(USART_RX_STA&0x8000)
			{					   
				len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
				printf("\r\n您发送的短信为:\r\n\r\n");
				for(t=0;t<len;t++)
				{
						USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
						while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
				}
				printf("\r\n\r\n");//插入换行
				USART_RX_STA=0;
			}
			else
			{
				times++;
				if(times%5000==0)
				{
					printf("\r\n关注Bitter tea seeds\r\n");
					printf("USART—串口通讯\r\n\r\n");
				}
				if(times%200==0)printf("请输入数据,以回车键结束\n");  
				if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
				delay_ms(10);   
			}
		}	 
}

首先判断全局变量 USART_RX_STA 的最高位是否为 1,如果为 1 的话,那么代表前一次数据接收已经完成,接下来就是把我们自定义接收缓冲的数据发送到串口。

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);

上述代码就是我们发送一个字节之后之后,要检测这个数据是否已经被发送完成了。

6.实验现象 

 

原网站

版权声明
本文为[Bitter tea seeds]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_69250798/article/details/125469499