STM32F405--USART中断收发数据

功能描述:使用STM32F405RGT6的USART1实现数据收发。USART串口配置为:波特率115200,8位数据位,无校验位,1位停止位。数据帧配置为:包头为‘@’,包尾为"\r\n"。

  •  main.c文件内容如下
#include "stm32f4xx.h"                  // Device header
#include "OLED.h"
#include "Serial.h"

uint8_t data[100] = {0};		//数据接收指针

int main(void)
{
	Serial_Init();	//初始化串口
	OLED_Init();	//初始化OLED
	OLED_Clear();	//清屏OLED
	OLED_Refresh();	//刷新OLED
	
	Serial_SendString(USART1, "hello,world\r\n");	//串口1发送"hello,world"字符串

	while(1)
	{
		if(Serial_GetRxFlag() == 1)		//判断接收标志位
		{
			for(uint8_t i=0; i<100; i++)				//清除数据接收区,避免上一次的干扰
			{
				if(data[i] == '\0')
					break;
				data[i] = '\0';
			}
			Serial_GetRxData(data);						//接收数据
			OLED_ClearArea(0,0,127,15);					//清屏OLED第一大行
			OLED_ShowString(0,0,(const char*)data,8);	//在OLED上显示接收到的数据
			OLED_Refresh();								//刷新OLED
			Serial_ClearRxFlag();						//清除接收标志位	
		}	
	}
}

  • Serial.c文件内容如下
#include "Serial.h"             

uint8_t RxPackage[100]={0};
uint8_t RxBuff1[100]={0};
uint8_t RxFlag1 = 0;

/**
  * @摘要  		初始化USART
  * @参数  		无
  * @返回值  	无
  * @说明  		无
  */
void Serial_Init(void)
{
	//开启GPIOA时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	//将PA9配置为复用模式,复用为USART1的TX引脚
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
	//将PA10配置为复用模式,复用为USART1的RX引脚
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
	
	//定义GPIO初始化结构体
	GPIO_InitTypeDef GPIO_InitStructure;
	//初始化上述结构体
	GPIO_StructInit(&GPIO_InitStructure);
	//配置GPIO模式为复用模式
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	//配置GPIO输出类型为推挽输出
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	//配置GPIO输入类型为上拉输入
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	//配置GPIO的速度为快速50MHZ
	GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;
	//指定GPIO引脚为Pin9和Pin10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
	//初始化对应的GPIO
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//开启USART1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	//定义USART初始化结构体
	USART_InitTypeDef USART_InitStructure;
	//初始化上述结构体
	USART_StructInit(&USART_InitStructure);
	//配置波特率为115200
	USART_InitStructure.USART_BaudRate = 115200;
	//配置数据长度为8位
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	//配置校验位为无
	USART_InitStructure.USART_Parity = USART_Parity_No;
	//配置停止位为1位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	//配置串口模式为接收和发送模式
	USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
	//配置硬件流控制为无
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	//初始化对应的USART
	USART_Init(USART1, &USART_InitStructure);
	
	//使能USART1的接收寄存器非空中断到NVIC
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	//开启USART1
	USART_Cmd(USART1, ENABLE);
	
	//NVIC优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	//定义NVIC初始化结构体
	NVIC_InitTypeDef NVIC_InitStructure;
	//选择NVIC通道为USART1_IRQn
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	//使能该通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	//配置抢占优先级为1
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	//配置响应优先级为1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	//初始化NVIC
	NVIC_Init(&NVIC_InitStructure);
}

/**
  * @摘要  		串口发送一个字节数据
  * @参数  		USARTx:串口号,x可以为1、2、3...(根据具体芯片型号选择)
  * @参数  		Byte:	要发送的字节数据
  * @返回值  	0或1:0代表发送失败,1代表发送成功
  * @说明  		无
  */
uint8_t Serial_SendByte(USART_TypeDef* USARTx, uint8_t Byte)
{
	uint16_t timeout = 10000;
	USART_SendData(USARTx, Byte);
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
	{
		timeout--;
		if(timeout == 0)
			return 0;
	}
	return 1;
}

uint8_t Serial_SendArray(USART_TypeDef* USARTx, uint8_t *array, uint16_t length)
{
	uint8_t state = 0;
	for(uint16_t i=0; i<length; i++)
	{
		state = Serial_SendByte(USARTx, array[i]);
		if(state == 0)
			return 0;
	}
	return 1;
}

/**
  * @摘要  		串口发送一个字符串
  * @参数  		USARTx:串口号,x可以为1、2、3...(根据具体芯片型号选择)
  * @参数  		str:	要发送的字符串
  * @返回值  	0或1:0代表发送失败,1代表发送成功
  * @说明  		无
  */
uint8_t Serial_SendString(USART_TypeDef* USARTx, const char *str)
{
	uint8_t state = 0;
	for(uint16_t i=0; str[i]!='\0'; i++)
	{
		state = Serial_SendByte(USARTx, str[i]);
		if(state == 0)
			return 0;
	}
	return 1;
}

/**
  * @摘要  		串口发送一个无符号整数
  * @参数  		USARTx:串口号,x可以为1、2、3...(根据具体芯片型号选择)
  * @参数		Number:指定要发送的数字,范围:0~4294967295
  * @参数  		type:	要以什么进制发送上述整数,比如2,8,10,16
  * @参数  		length:要发送的整数的长度
  * @返回值  	0或1:0代表发送失败,1代表发送成功
  * @说明  		无
  */
uint8_t Serial_SendNum(USART_TypeDef* USARTx, uint32_t Number, uint8_t type, uint8_t length)
{
	uint8_t state = 0;
	uint8_t temp;
	for(uint8_t i=0; i<length; i++)
	{
		temp = (Number/Pow(type,length-i-1))%type;
		if(temp > 9)
			state = Serial_SendByte(USARTx, temp-10+'A');
		else
			state = Serial_SendByte(USARTx, temp+'0');
		if(state == 0)
			return 0;
	}
	return 1;
}

/**
  * @摘要  		串口发送一个有符号整数
  * @参数  		USARTx:串口号,x可以为1、2、3...(根据具体芯片型号选择)
  * @参数  		Number:要发送的整数
  * @参数  		length:要发送的整数的长度
  * @参数		ShowSign:是否显示'+'号,ENABLE(显示)或DISABLE(不显示)
  * @返回值  	0或1:0代表发送失败,1代表发送成功
  * @说明  		Number会以十进制格式发送出去
  */
uint8_t Serial_SendSignedNum(USART_TypeDef* USARTx, int32_t Number, uint8_t length, FunctionalState ShowSign)
{
	uint8_t state = 0;
	if(Number < 0)
	{
		state = Serial_SendByte(USARTx, '-');
		if(state == 0)
			return 0;
		state = Serial_SendNum(USARTx, -Number,10,length);
		if(state == 0)
			return 0;
		
	}
	else
	{
		if(ShowSign == ENABLE)
		{
			state = Serial_SendByte(USARTx, '+');
			if(state == 0)
				return 0;
			state = Serial_SendNum(USARTx, Number,10,length);
			if(state == 0)
				return 0;
		}
		else
		{
			state = Serial_SendNum(USARTx, Number,10,length);
			if(state == 0)
				return 0;
		}
	}
	return 1;
}

/**
  * @摘要  		串口发送一个小数
  * @参数  		USARTx:串口号,x可以为1、2、3...(根据具体芯片型号选择)
  * @参数  		Number:要发送的小数,范围:-4294967295.0~4294967295.0
  * @参数  		type:要以什么进制发送上述小数,比如2,8,10,16
  * @参数		IntLength:指定数字的整数部分长度
  * @参数		FraLength:指定数字的小数部分长度,小数进行去尾补0显示
  * @返回值  	0或1:0代表发送失败,1代表发送成功
  * @说明  		无
  */
uint8_t Serial_SendFloatNum(USART_TypeDef* USARTx, double Number,uint8_t type, uint8_t IntLength, uint8_t FraLength)
{
	uint8_t state = 0;
	uint32_t tempNum = Number;
	uint8_t temp;
	for(uint8_t i=0; i<IntLength; i++)
	{
		temp = (tempNum/Pow(type,IntLength-i-1))%type;
		if(temp > 9)
			state = Serial_SendByte(USARTx, temp-10+'A');
		else
			state = Serial_SendByte(USARTx, temp+'0');
		if(state == 0)
			return 0;
	}
	
	state = Serial_SendByte(USARTx, '.');
	if(state == 0)
		return 0;
	
	tempNum = (Number-tempNum)*Pow(10,FraLength);
	for(uint8_t i=0; i<FraLength; i++)
	{
		tempNum = tempNum*type;
		temp = tempNum/Pow(10,FraLength);
		tempNum = tempNum-tempNum/Pow(10,FraLength)*Pow(10,FraLength);
		if(temp > 9)
			state = Serial_SendByte(USARTx, temp-10+'A');
		else
			state = Serial_SendByte(USARTx, temp+'0');
		if(state == 0)
			return 0;
	}
	return 1;
}

/**
  * @摘要  		这是一个可变参数函数,用于格式化发送字符串
  * @参数  		USARTx:串口号,x可以为1、2、3...(根据具体芯片型号选择)
  * @参数		format:字符串
  * @参数		...:可变参数
  * @返回值  	0或1:0代表发送失败,1代表发送成功
  * @说明  		无
  */
uint8_t Serial_Printf(USART_TypeDef* USARTx, char* format,...)
{
	uint8_t state = 0;
	char str[100];
	va_list arg;
	va_start(arg,format);
	vsprintf(str,format,arg);
	va_end(arg);
	state = Serial_SendString(USART1,str);
	if(state == 0)
		return 0;
	return 1;
}

/**
  * @摘要  		串口发送中文字符串(或一个字符)
  * @参数  		USARTx:串口号,x可以为1、2、3...(根据具体芯片型号选择)
  * @参数  		Chinese:要发送的中文字符串
  * @返回值  	0或1:0代表发送失败,1代表发送成功
  * @说明  		无
  */
uint8_t Serial_SendChinese(USART_TypeDef* USARTx, char *Chinese)
{
	uint8_t state = 0;
	uint8_t cnt = 0, pChinese = 0, SingleChinese[4] = {0};
	uint8_t index;
	
	for(uint8_t i=0; Chinese[i]!='\0'; i++)
	{
		SingleChinese[pChinese] = Chinese[i];
		pChinese++;
		if(pChinese>=Serial_CHN_CHAR_WIDTH)
		{
			pChinese = 0;
			cnt++;
			for(index=0; strcmp(Serial_Chinese[index].Index, "") != 0; index++)
			{
				if(strcmp(Serial_Chinese[index].Index, (const char*)SingleChinese) == 0)
					break;
			}
			state = Serial_SendArray(USARTx, (uint8_t *)Serial_Chinese[index].Data, 3);
			if(state == 0)
				return 0;
		}
	}
	return 1;
}

/**
  * @摘要  		串口发送数据包
  * @参数  		USARTx:串口号,x可以为1、2、3...(根据具体芯片型号选择)
  * @参数  		package:要发送的数据包
  * @返回值  	0或1:0代表发送失败,1代表发送成功
  * @说明  		无
  */
uint8_t Serial_SendPackage(USART_TypeDef* USARTx, uint8_t* package)
{
	uint8_t state = 0;
	state = Serial_SendByte(USART1,'@');			//包头
	if(state == 0)
		return 0;
	state = Serial_SendArray(USART1, package, 4);	//数据
	if(state == 0)
		return 0;
	state = Serial_SendString(USART1, "\r\n");		//包尾
	if(state == 0)
		return 0;
	return 1;
}

/**
  * @摘要  		获取接收标志位
  * @参数  		无
  * @返回值  	接收标志:1(完成接收),0(未完成接收或未接收)
  * @说明  		无
  */
uint8_t Serial_GetRxFlag(void)
{
	return RxFlag1;
}

/**
  * @摘要  		清除接收标志位
  * @参数  		无
  * @返回值  	无
  * @说明  		无
  */
void Serial_ClearRxFlag(void)
{
	RxFlag1 = 0;
}

/**
  * @摘要  		获取接收数据
  * @参数  		Rxdata:指向存储接收数据地址的指针
  * @返回值  	接收到的数据包的指针
  * @说明  		调用此函数会自动清除接收缓冲区
  */
void Serial_GetRxData(uint8_t* Rxdata)
{
	for(uint8_t i=0; i<100; i++)
	{
		if(RxBuff1[i] == 0)
			break;
		Rxdata[i] = RxBuff1[i];
		RxBuff1[i] = 0;
	}
}

/**
  * @摘要  		USART1中断服务函数
  * @参数  		无
  * @返回值  	无
  * @说明  		无
  */
void USART1_IRQHandler(void)
{
	static uint8_t RxState = 0;
	static uint8_t RxIndex = 0;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
		if(RxState == 0)		//状态0:等待包头
		{
			if((USART_ReceiveData(USART1) == '@') && (RxFlag1 == 0))
			{
				RxState = 1;
				RxIndex = 0;
			}
		}
		else if(RxState == 1)	//状态1:接收数据并等待包尾标志1
		{
			RxBuff1[RxIndex] = USART_ReceiveData(USART1);
			if(RxBuff1[RxIndex] == '\r')
			{
				RxState = 2;
				RxBuff1[RxIndex] = '\0';
			}
			RxIndex++;
		}
		else if(RxState == 2)	//状态2:等待包尾标志2
		{
			if((USART_ReceiveData(USART1) == '\n'))
			{
				RxState = 0;
				RxFlag1 = 1;
			}
		}
	}
}

  • Serial.h文件内容如下
#ifndef __SERIAL_H
#define __SERIAL_H

#include <String.h>
#include <stdarg.h>
#include <stdio.h>
#include "stm32f4xx.h"                  // Device header
#include "Serial_Data.h"
#include "MyMath.h"

void Serial_Init(void);
uint8_t Serial_SendByte(USART_TypeDef* USARTx, uint8_t Byte);
uint8_t Serial_SendArray(USART_TypeDef* USARTx, uint8_t *array, uint16_t length);
uint8_t Serial_SendString(USART_TypeDef* USARTx, const char *str);
uint8_t Serial_SendNum(USART_TypeDef* USARTx, uint32_t Number, uint8_t type, uint8_t length);
uint8_t Serial_SendSignedNum(USART_TypeDef* USARTx, int32_t Number, uint8_t length,FunctionalState ShowSign);
uint8_t Serial_SendFloatNum(USART_TypeDef* USARTx, double Number,uint8_t type, uint8_t IntLength, uint8_t FraLength);
uint8_t Serial_SendChinese(USART_TypeDef* USARTx, char *Chinese);
uint8_t Serial_Printf(USART_TypeDef* USARTx, char* format,...);
uint8_t Serial_SendPackage(USART_TypeDef* USARTx, uint8_t* package);
uint8_t Serial_GetRxFlag(void);
void Serial_ClearRxFlag(void);
void Serial_GetRxData(uint8_t* Rxdata);

#endif

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: STM32F405 USART是一款由意法半导体开发的串口通信模块。它是STM32F405系列微控制器上的一个重要功能模块,可用于与外部设备进行数据传输和通信。 STM32F405 USART具有多种功能和特性。首先,它支持全双工通信,可以同时发送和接收数据。其次,它支持异步和同步通信模式,可以根据需要选择合适的模式进行数据传输。除此之外,它还提供了多种数据传输格式,例如8位、9位或字节传输格式。 此外,STM32F405 USART还具备高性能和低功耗的特点。它能够以很快的速度进行数据传输,同时在待机模式下能够有效降低功耗,提高系统的能效。 另外,STM32F405 USART还具备多个功能寄存器,用于配置串口通信参数和状态判断。它还支持硬件流控制和中断控制,方便用户对数据传输过程进行灵活的控制和管理。 总的来说,STM32F405 USART是一款功能强大、易于使用的串口通信模块,在工业控制、通信设备和嵌入式系统等领域有广泛的应用前景。它的出现为数据传输和设备通信提供了可靠的解决方案,帮助用户更好地实现数据交换和系统集成。 ### 回答2: STM32F405 USARTSTM32F4系列微控制器上的一种通信接口,用于实现串行数据传输。该微控制器具有多个USART模块,可用于与其他设备进行异步的串行通信。 STM32F405 USART具有许多功能,例如全双工通信、异步或同步传输模式、帧错误检测等。它还支持多种传输速率和数据位数,使得它成为连接各种外部设备的理想选择。 USART模块通过发送和接收引脚与其他设备进行通信。发送数据时,我们可以通过设置USART的发送寄存器来发送字节。接收数据时,我们可以通过读取USART接收寄存器获取接收到的字节。这使得我们可以轻松地在微控制器和其他设备之间进行双向数据通信。 除了基本的数据传输功能外,STM32F405 USART还支持中断和DMA传输,以提高数据传输的效率。通过使用中断和DMA,我们可以在接收或发送完成时立即触发相应的中断或DMA传输。 总的来说,STM32F405 USART是一种功能强大的串行通信接口,适用于各种应用场景。无论是与传感器、无线模块、显示器还是其他设备进行通信,都可以通过该接口轻松实现数据传输。 ### 回答3: STM32F405 是意法半导体(STMicroelectronics)生产的一款32位微控制器,采用ARM Cortex-M4内核。它的主要特性包括高性能、低功耗、丰富的外设和多种接口选项,使其在各种应用领域中得以广泛应用。 USARTSTM32F405微控制器上的一种通信接口,代表"通用同步/异步串行收发传输器"(Universal Synchronous/Asynchronous Receiver Transmitter)的缩写。它可以用于实现串行数据的发送和接收,并且支持同步和异步的数据传输方式。USART接口提供了多种功能和配置选项,使其能够适应不同的通信需求。 STM32F405USART接口具有以下特点: 1. 可配置性:USART接口支持多种工作模式,包括同步模式、异步模式、单向模式和全双工模式,可根据具体需求进行配置。 2. 高速传输:USART接口支持高速串行通信,最高传输速率可达到25Mbps,可以满足对数据传输速度要求较高的应用。 3. 异常检测和处理:USART接口具有错误检测和处理功能,可以检测和纠正传输过程中出现的错误,提高数据传输的可靠性。 4. DMA支持:USART接口支持DMA(直接存储器访问)功能,可以通过设置DMA通道实现大量数据的高速传输,减轻CPU的负担。 5. 多种接口模式:USART接口可通过配置选择不同的工作模式,包括主机模式、从机模式和多主机模式,以适应不同的通信需求。 总之,STM32F405USART接口是一种灵活、高性能的通信接口,可以用于实现各种串行数据传输应用。无论是工业控制、通信设备还是消费电子产品,都可以通过该接口实现可靠的数据通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值