STM32-串口通信发送+接收信息(标准库+代码)

avatar
作者
筋斗云
阅读量:0

目录

一、串口简介

二、串口配置流程

三、代码实现

四、实现效果


一、串口简介

        通用异步收发器 UART(Universal Asynchronous Receiver/Transmitter),是一种串行、异步、全双工的通信协议。通过发送线(TX)、接收线(RX)、GND就可以进行全双工通信。需要确定好通信双方的波特率(bps指每秒传输的码元数量)

        串口通信是一位一位地传输,每传输一个字符总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。每一个字符的前面都有一位起始位(低电平),后面由7位数据位组成,接着是1位校验位,最后是1位停止位。停止位后面是不定长的空闲位,停止位和空闲位都规定为高电平。

一般的数据格式:(1bit)起始位+(7bit) 数据位 + (None)校验位 + (1bit)停止位

起始位:通信线路上空闲时为“1”,当检测到“0”即下降沿时,认为数据传输开始
有效数据位:传输开始后传递的需要接收和发送的数据值,可以表示指令或数据
奇偶校验位:奇偶校验,通过来校验传输数据中“1”的个数为奇数个(奇校验)或偶数个(偶校验)来指示传输数据是否正确
停止位:数据传输结束,传输线恢复常“1”状态
此外,还需关注数据传输波特率,波特率表示一秒内传输了多少个码元数量,一般波特率为300,1200,2400,9600,19200,38400,115200等。例如9600 Baud表示一秒内传输了9600个码元信息,当一个码元只含1 bit信息时,波特率=比特率

二、串口配置流程

一般我们使用串口,都需要有以下几个步骤:

1.开启GPIO时钟和串口时钟

2.配置GPIO模式并初始化

3.配置串口参数

4.使能串口

三、代码实现

Usart.c        (这里的重定义函数需要勾选Use MicroLIB)

#include "stm32f10x.h"                  // Device header #include "Usart.h"  u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节. //接收状态 //bit15,	接收完成标志 //bit14,	接收到0x0d //bit13~0,	接收到的有效字节数目 u16 USART_RX_STA=0;       //接收状态标记	   //重定义fputc函数  int fputc(int ch, FILE *f) {           USART_SendData(USART1, (uint8_t) ch);     while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待发送完成  	return ch;  }   void Usart1_Init(uint32_t bound) {	 	GPIO_InitTypeDef GPIO_InitStructure; 	USART_InitTypeDef USART_InitStructure; 	NVIC_InitTypeDef NVIC_InitStructure; 	 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); 	 	//USART1_TX 	PA9  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 	GPIO_Init(GPIOA,&GPIO_InitStructure); 	 	//USART1_RX 	PA10 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 	GPIO_Init(GPIOA,&GPIO_InitStructure); 	 	//USART1 NVIC 配置 	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 	NVIC_Init(&NVIC_InitStructure); 	 	//USART1 初始化配置 	USART_InitStructure.USART_BaudRate = bound; 	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 	USART_InitStructure.USART_Parity = USART_Parity_No; 	USART_InitStructure.USART_StopBits = USART_StopBits_1; 	USART_InitStructure.USART_WordLength = USART_WordLength_8b; 	 	USART_Init(USART1,&USART_InitStructure);		//初始化串口 1 	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);	//开启串口接收中断 	USART_Cmd(USART1,ENABLE);						//使能串口 1 }  void USART1_IRQHandler( void )                                                                          /* 串口1中断服务程序 */ { 	u8 Res; 	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾) 	{ 		Res =USART_ReceiveData(USART1);	//读取接收到的数据 		 		if((USART_RX_STA&0x8000)==0)//接收未完成 			{ 			if(USART_RX_STA&0x4000)//接收到了0x0d 				{ 				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 				else USART_RX_STA|=0x8000;	//接收完成了  				} 			else //还没收到0X0D 				{	 				if(Res==0x0d)USART_RX_STA|=0x4000; 				else 					{ 					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; 					USART_RX_STA++; 					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	   					}		  				} 			}   		       }  } 

Usart.h

#ifndef __USART_H_ #define __USART_H_ #include "stm32f10x.h"                  // Device header #include <stdio.h>  #define USART_REC_LEN  			200  	//定义最大接收字节数 200 #define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收 extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符  extern u16 USART_RX_STA;         		//接收状态标记	  void Usart1_Init(uint32_t bound);    #endif 

main.c

#include "stm32f10x.h"                  // Device header #include "Delay.h" #include "Usart.h" //硬件部分 #include "LED.h" #include "KEY.h"  int main(void) { 	Usart1_Init(9600);		//串口1 初始化 	LED_Init(); 	while(1) 	{		   		LED_ON; 		Delay_ms(500); 		LED_OFF; 		Delay_ms(500); 		printf("hello word\r\n"); 		if(USART_RX_STA & 0x8000) //接收完成         {             printf("Received data: %s\n", USART_RX_BUF);             USART_RX_STA = 0; //清除接收状态标记         } 	} } 

四、实现效果

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!