STM32串口数据接收 --环形缓冲区
环形缓冲区简介
在单片机中串口通信是我们使用最频繁的,使用串口通信就会用到串口的数据接收与发送,环形缓冲区方式接收数据可以更好的保证数据丢帧率第。
在通信程序中,经常使用环形缓冲器作为数据结构来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。
环形缓冲区的一个有用特性是:当一个数据元素被用掉后,其余数据元素不需要移动其存储位置。相反,一个非圆形缓冲区(例如一个普通的队列)在用掉一个数据元素后,其余数据元素需要向前搬移。换句话说,环形缓冲区适合实现先进先出缓冲区,而非环形缓冲区适合后进先出缓冲区。
STM32环形缓冲区示例
#include "usart.h"
void Usartx_Init(USART_TypeDef *USARTx,u32 baud,u32 sysclk)
{
if(USART1 == USARTx)
{
RCC->APB2ENR|=1<<2;
RCC->APB2ENR|=1<<14;
RCC->APB2RSTR|=1<<14;
RCC->APB2RSTR&=~(1<<14);
GPIOA->CRH&=0xFFFFF00F;
GPIOA->CRH|=0x000008B0;
#ifdef USART1_IQR
USART1->CR1|=1<<5;
STM32_NVIC_SetPriority(USART1_IRQn,0,1);
#endif
}
else if(USART2 == USARTx)
{
RCC->APB2ENR|=1<<2;
RCC->APB1ENR|=1<<17;
RCC->APB1RSTR|=1<<17;
RCC->APB1RSTR&=~(1<<17);
GPIOA->CRL&=0xFFFF00FF;
GPIOA->CRL|=0x00008B00;
#ifdef USART2_IRQ
USART2->CR1|=1<<5;
STM32_NVIC_SetPriority(USART2_IRQn,1,2);
#endif
}
else if(USART3 == USARTx)
{
RCC->APB2ENR|=1<<3;
RCC->APB1ENR|=1<<18;
RCC->APB1RSTR|=1<<18;
RCC->APB1RSTR&=~(1<<18);
GPIOB->CRH&=0xFFFF00FF;
GPIOB->CRH|=0x00008B00;
#ifdef USART3_IRQ
USART3->CR1|=1<<5;
STM32_NVIC_SetPriority(USART3_IRQn,0,0);
#endif
}
else return;
USARTx->BRR=sysclk*1000000/baud;
USARTx->CR1|=1<<2;
USARTx->CR1|=1<<3;
USARTx->CR1|=1<<13;
}
void Usartx_SendString(USART_TypeDef *USARTx,u8 *str,u8 len)
{
while(len--)
{
USARTx->DR=*str;
while((USARTx->SR&1<<7)==0){}
str++;
}
}
int fputc(int c,FILE *stream)
{
USART1->DR=c;
while(!(USART1->SR&1<<7)){}
return c;
}
#define USART1_LEN 200
typedef struct
{
char buff[USART1_LEN];
u8 usart1_rx_len;
u8 usart1_flag;
u8 w;
u8 r;
}USART1_RX;
USART1_RX USART1_rx={{0},0,0,0,0};
void USART1_IRQHandler(void)
{
u8 c;
if(USART1->SR&1<<5)
{
c=USART1->DR;
if(USART1_rx.usart1_rx_len<USART1_LEN)
{
USART1_rx.buff[USART1_rx.w]=c;
USART1_rx.w=(USART1_rx.w+1)%USART1_LEN;
USART1_rx.usart1_rx_len++;
TIM2->CNT=0;
TIM2->CR1|=1<<0;
}
else USART1_rx.usart1_flag=1;
}
USART1->SR=0;
}
u8 Usart1_Annular_txdata(u8 *tx_data)
{
u8 len=0;
if(USART1_rx.usart1_rx_len==0 || USART1_rx.usart1_flag==0)return 0;
while(USART1_rx.usart1_rx_len)
{
*tx_data=USART1_rx.buff[USART1_rx.r];
USART1_rx.r= (USART1_rx.r+1)%USART1_LEN;
USART1_rx.usart1_rx_len--;
tx_data++;
len++;
}
USART1_rx.usart1_flag=0;
*tx_data='\0';
return len;
}
#include "stm32f10x.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
u8 buff[200];
int main()
{
u8 stat=0;
Led_Init();
Usartx_Init(USART1,115200,72);
TIMx_Init(TIM2,72,20000);
printf("串口初始化完成\r\n");
while(1)
{
stat=Usart1_Annular_txdata(buff);
if(stat)
{
Usartx_SendString(USART1,buff,stat);
}
}
}
示例工程
示例工程链接:https://download.csdn.net/download/weixin_44453694/14981774
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)