stm32循环buffer数据处理实例

接着上次的《stm32实用循环buffer》,给大家提供一个参考实例,根据实际情况改改就能用。

/******************************************************************************
* @File 	: usart2.c
* @Author   : qianxin.chen@qq.com
* @Version  : V0.0.1
* @Date 	: 20-February-2020
* @Brief	: This file provides all the usart2 functions.
******************************************************************************
* @Attention:
* Non
*
******************************************************************************/
/* Includes -----------------------------------------------------------------*/
#include "includes.h"
#include "usart2.h"
#include "fifo.h"	//fifo头文件
#include "crc.h"	//用于校验
#include "usart1.h"	//用于printf打印

/* Define -------------------------------------------------------------------*/
#define USART2_FIFO_LEN 64
#define FRAME_HEAD1 0xAA
#define FRAME_TAIL1 0x55
#define FRAME_TAIL2 0x55	
#define FRAME_LEN 5
#define complement(a) (FRAME_LEN-a)

/* Variables ----------------------------------------------------------------*/
struct fifo fifo2;
static unsigned char copy_len = FRAME_LEN; 
#ifdef FIX_BUFFER //用于区分固定分配或动态分配buffer
unsigned char fifo_buf[USART2_FIFO_LEN];
#endif

/* Functions ----------------------------------------------------------------*/
/* must init this function */
void init_usart2_fifo(void)
{	
	signed int ret;
	
	ret = fifo_alloc(&fifo2, USART2_FIFO_LEN);
#ifdef FIX_BUFFER
	ret = fifo_init(&fifo2, fifo_buf, USART2_FIFO_LEN);
#endif
	if(ret<0){
		printf("fifo2 alloc fail!\n");
	}
}

void usart2_Init(u32 bound)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 	
	
 	USART_DeInit(USART2); 	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	
	GPIO_Init(GPIOA, &GPIO_InitStructure); 
   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	

	USART_Init(USART2, &USART_InitStructure); 
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

	USART_Cmd(USART2, ENABLE);
}

void usart2_send_data(u8 *sdata, u8 len) 
{
	u8 i; 
	
	GPIO_ResetBits(GPIOA, GPIO_Pin_4);
	USART_ClearFlag(USART2,USART_FLAG_TC);
	for(i=0;i<len;i++) 
		{
		USART_SendData(USART2, sdata[i]);
		while(USART_GetFlagStatus(USART2, USART_FLAG_TC)!=SET);
	}
	GPIO_SetBits(GPIOA, GPIO_Pin_4);
}

void USART2_IRQHandler(void) 
{
	unsigned int ret;
	unsigned char buf[1];
	
	OSIntEnter();	//如果没有用ucos屏蔽此行
	if(USART_GetITStatus(USART2, USART_IT_RXNE)!= RESET){	
		USART_ClearITPendingBit(USART2,USART_IT_RXNE);
		buf[0] = USART_ReceiveData(USART2);
		ret = fifo_in(&fifo2, buf, 1);
		if(ret<1){
		   printf("fifo2 in err!\n");
		}	 
	 }
	 OSIntExit();	//如果没有用ucos屏蔽此行
}

/* 在buffer中查找、校验符合条件的帧数据 */
void usart2_data_handler(void)
{
	unsigned int len;
	unsigned char buf[FRAME_LEN];
	/* 执行到这里的时候,只要有数据就循环处理,直到处理完数据 */
	while((fifo_used(&fifo2))>((copy_len))){
		len = fifo_out(&fifo2, buf+complement(copy_len), (copy_len));	//fifo中提取需要的长度字节
		if(len <1){
			printf("usart2 fifo out err!\n");
		}
		/* 校验帧头、帧尾、和crc校验 */
		//if(buf[0] == FRAME_HEAD1 && buf[FRAME_LEN-1]==FRAME_TAIL1 && buf[FRAME_LEN-1]==FRAME_TAIL2
		//&& (buf[sizeof(buf)-2] == crc8_maxim(buf+CRC_OFFSET, (sizeof(buf)-SIZE_SUB+1)))){
		/* 只校验帧头、帧尾 */
		if(buf[0] == FRAME_HEAD1 && buf[FRAME_LEN-1]==FRAME_TAIL1 && buf[FRAME_LEN-1]==FRAME_TAIL2){
			copy_len=FRAME_LEN;
			{
				/* 帧数据处理 */
			}
			continue;
		}
		else{
			/* 不符合帧数据条件,循环查找帧头,并把找到的帧头移动到buf的前面,下次提取的数据附加在后边 */			
			for(copy_len=1;copy_len<FRAME_LEN;copy_len++){
				if(buf[copy_len] == FRAME_HEAD1){
					memcpy(buf,buf+copy_len,(complement(copy_len)));
				  break;
				}
			}
		}
	}
}

头文件:

/*******************************************************************************
* @File 	: usart.h
* @Author   : qianxin.chen@qq.com
* @Version  : V0.0.0
* @Date 	: 20-February-2016
* @Brief	: This file provides all the write internal usart2 functions.
********************************************************************************
* @Attention:
* Non
*
*******************************************************************************/

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _USART2_H
#define _USART2_H
#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "includes.h"

/* function prototypes -------------------------------------------------------*/
void init_usart2_fifo(void);	 
void usart2_Init(u32 bound);
void usart2_send_data(u8 *sdata,u8 len); 
void USART2_IRQHandler(void);
void usart2_data_handler(void);

#ifdef __cplusplus
}
#endif
#endif

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个基于STM32F407芯片的串口DMA接收数据的实例代码: ```c #include "stm32f4xx.h" #include <stdio.h> #include <string.h> #define USART1_DR_Address ((uint32_t)0x40011004) char RxBuffer[64]; uint8_t RxCounter = 0; uint8_t RxFlag = 0; void USART_Config(void); void DMA_Config(void); int main(void) { USART_Config(); DMA_Config(); while(1) { if(RxFlag) { printf("Received data: %s\r\n", RxBuffer); RxFlag = 0; memset(RxBuffer, 0, sizeof(RxBuffer)); RxCounter = 0; } } } void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } void DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); DMA_DeInit(DMA2_Stream2); DMA_InitStructure.DMA_Channel = DMA_Channel_4; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USART1_DR_Address; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)RxBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = sizeof(RxBuffer); DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream2, &DMA_InitStructure); DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); DMA_Cmd(DMA2_Stream2, ENABLE); } void DMA2_Stream2_IRQHandler(void) { if(DMA_GetITStatus(DMA2_Stream2, DMA_IT_TCIF2)) { DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF2); RxCounter = sizeof(RxBuffer) - DMA_GetCurrDataCounter(DMA2_Stream2); RxBuffer[RxCounter] = '\0'; RxFlag = 1; } } ``` 在这个例子中,我们使用USART1和DMA2_Stream2来接收串口数据。首先,在USART_Config函数中,我们进行了USART的配置,将USART1的TX和RX引脚分别配置为PA9和PA10,并设置波特率为115200。 接下来,在DMA_Config函数中,我们对DMA进行了配置。我们将DMA的通道设置为4,将DMA的方向设置为从外设到内存,并将DMA的模式设置为循环模式。我们还启用了DMA的中断,并将DMA2_Stream2_IRQHandler函数作为中断处理函数。 最后,在DMA2_Stream2_IRQHandler函数中,我们检查DMA传输完成中断标志位,并清除该标志位。然后,我们通过DMA_GetCurrDataCounter函数计算已经接收到的数据量,并将RxFlag设置为1,表示已经接收到了一条完整的数据。 在主函数中,我们不断地检查RxFlag标志位,如果该标志位为1,则表示已经接收到了一条完整的数据,我们将其打印出来,并将RxFlag和RxBuffer数组清零。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值