STM32串口发送接收数据

Posted 一只小阿大嗷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32串口发送接收数据相关的知识,希望对你有一定的参考价值。

串口通信

在这里插入图片描述
我用的32是stm32f10x最小系统没有UART4和UART5
USART : 通用同步异步收发器
UART : 通用异步收发器
nRTS : 请求发送
nCTS : 请求接收
区别:USART指单片机的一个IO端口模块,可以根据需要配置成同步模式(SPI,IIC),也可以配置成异步模式(UART).可以理解为USART为SPI,IIC对等的”协议”。 UART则不是一个协议,为一个实体。

串口的结构体

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Fck : 串口的时钟(APB1 36M / APB2 72M )
USARTDIV : 无符号的定点数

115200= 72 * 1000000/16 * USARTDIV

如何配置串口的发送

1.配置时钟: GPIO口的时钟,串口的时钟, 引脚复用的时钟
2.配置GPIO的结构体
3.配置串口的结构体
4.串口的发送

在这里插入图片描述

通过串口向电脑发送ok字符

按照上面的四个步骤进行编写
我们会发现只能一个一个发送字符,比较麻烦,所以后面封装了一个可以发送字符串的函数。
usart.c

#include "usart.h"
#include "stm32f10x.h"

void usart_init(void)
{
	GPIO_InitTypeDef gpio_init;
	USART_InitTypeDef usartStruct;
	
	//1.ÅäÖÃʱÖÓ£ºGPIO¿ÚµÄʱÖÓ£¬Òý½Å¸´ÓõÄʱÖÓ£¬´®¿ÚµÄʱÖÓ
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//2.ÅäÖÃGPIOµÄ½á¹¹Ìå
	//2.1 TX
	gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio_init.GPIO_Pin = GPIO_Pin_9;
	gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
	
	GPIO_Init(GPIOA,&gpio_init);
	
	//2.2 RX
	gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	gpio_init.GPIO_Pin = GPIO_Pin_10;
	
	GPIO_Init(GPIOA,&gpio_init);
	
	//3.ÅäÖô®¿ÚµÄ½á¹¹Ìå
	usartStruct.USART_BaudRate = 115200;
	usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	usartStruct.USART_Parity = USART_Parity_No;
	usartStruct.USART_StopBits = USART_StopBits_1;
	usartStruct.USART_WordLength = USART_WordLength_8b;
	
	USART_Init(USART1,&usartStruct);
	USART_Cmd(USART1, ENABLE );
	
}

usart.h

#include "stm32f10x.h"

void usart_init(void);

main.c

#include "stm32f10x.h"
#include "led.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"
#include "usart.h"

void delay(uint16_t time)
{
	uint16_t i =0;
	while(time--){
		i=12000;
		while(i--);
	}
}

int main()
{
	Led_init();
	Relay_Init();
	Shake_init();
	exti_init();
	usart_init();
	
	while(1)
	{
		USART_SendData(USART1,'n');
		//ÏÂÃæUSART_GetFlagStatusΪÁËÅжÏÊý¾Ý¼Ä´æÆ÷ÊÇ·ñΪ¿Õ
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
		USART_SendData(USART1,'t');
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
		USART_SendData(USART1,'\\n');
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
		delay(1000);
	}

}

//这是中断函数,前面做震动感应灯用的,没删。
void EXTI1_IRQHandler(void)
{
	if (EXTI_GetITStatus( EXTI_Line1 ) != RESET){// ÅжÏÊÇ·ñ·¢ÉúÖжÏ
		GPIO_ResetBits(GPIOA, GPIO_Pin_3);
		delay(1000);
		GPIO_SetBits(GPIOA, GPIO_Pin_3);
	}

	EXTI_ClearFlag(EXTI_Line1);
	
}

在这里插入图片描述

封装发送字符串函数

注意:在封装发送字符串函数时,while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);是为了把数据发送完
usart.c

#include "usart.h"
#include "stm32f10x.h"

void usart_init(void)
{
	GPIO_InitTypeDef gpio_init;
	USART_InitTypeDef usartStruct;
	
	//1.ÅäÖÃʱÖÓ£ºGPIO¿ÚµÄʱÖÓ£¬Òý½Å¸´ÓõÄʱÖÓ£¬´®¿ÚµÄʱÖÓ
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//2.ÅäÖÃGPIOµÄ½á¹¹Ìå
	//2.1 TX
	gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio_init.GPIO_Pin = GPIO_Pin_9;
	gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
	
	GPIO_Init(GPIOA,&gpio_init);
	
	//2.2 RX
	gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	gpio_init.GPIO_Pin = GPIO_Pin_10;
	
	GPIO_Init(GPIOA,&gpio_init);
	
	//3.ÅäÖô®¿ÚµÄ½á¹¹Ìå
	usartStruct.USART_BaudRate = 115200;
	usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	usartStruct.USART_Parity = USART_Parity_No;
	usartStruct.USART_StopBits = USART_StopBits_1;
	usartStruct.USART_WordLength = USART_WordLength_8b;
	
	USART_Init(USART1,&usartStruct);
	USART_Cmd(USART1, ENABLE );
	
}

//·â×°ÁËһϷ¢ËÍ×Ö·û
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data)
{
	USART_SendData(USARTx,Data);
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

}

//·¢ËÍ×Ö·û´®
void usartSendStr(USART_TypeDef* USARTx,char *str)
{
	uint16_t i = 0;
	do{
		usartSendByte(USARTx,*(str+i));
		i++;
	}while(*(str+i) != '\\0');

	//ÅжÏÊÇ·ñ·¢ËÍÍê
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}

usart.h

#include "stm32f10x.h"

void usart_init(void);
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data);
void usartSendStr(USART_TypeDef* USARTx,char *str);

main.c

#include "stm32f10x.h"
#include "led.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"
#include "usart.h"

void delay(uint16_t time)
{
	uint16_t i =0;
	while(time--){
		i=12000;
		while(i--);
	}
}

int main()
{
	Led_init();
	Relay_Init();
	Shake_init();
	exti_init();
	usart_init();
	
	while(1)
	{
		usartSendStr(USART1,"Finny\\r\\n");
		delay(1000);
	}

}
//这是中断函数,前面做震动感应灯用的,没删。
void EXTI1_IRQHandler(void)
{
	if (EXTI_GetITStatus( EXTI_Line1 ) != RESET){// ÅжÏÊÇ·ñ·¢ÉúÖжÏ
		GPIO_ResetBits(GPIOA, GPIO_Pin_3);
		delay(1000);
		GPIO_SetBits(GPIOA, GPIO_Pin_3);
	}

	EXTI_ClearFlag(EXTI_Line1);
	
}

在这里插入图片描述

以上是关于STM32串口发送接收数据的主要内容,如果未能解决你的问题,请参考以下文章

stm32串口发送正常,接受只能收到一个字符,求解,急

用stm32串口1发送05 04 01 1A F1 00 0004 00 08在串口二只接收01 1A F1 00 00 04其他的

STM32使用DMA接收串口数据

STM32串口发送接收数据

STM32串口接收小结

stm32发送数据给上位机用串口调试助手接收为什么只接收到第一个字节数据?