概述
1,DMA,UART配置:
2,代码配置
所用全局变量类型:
typedef struct QUE
{
uint8_t res_data[100];
uint8_t FLAG;
uint8_t res_counter;
struct QUE *next;
}QUE_UE_RES;
QUE_UE_RES QUE_buff[QUE_LEN];
QUE_UE_RES *UART_buff,*HAND_buff;
uint8_t RxCounter;
uint8_t *RxBuffer;
#define QUE_LEN 10 //uart缓存块长度
UART初始化:
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==LPUART1)
{
/* USER CODE BEGIN LPUART1_MspInit 0 */
/* USER CODE END LPUART1_MspInit 0 */
/* LPUART1 clock enable */
__HAL_RCC_LPUART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**LPUART1 GPIO Configuration
PB10 ------> LPUART1_TX
PB11 ------> LPUART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_LPUART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* LPUART1 DMA Init */
/* LPUART1_RX Init */
hdma_lpuart1_rx.Instance = DMA1_Channel3;
hdma_lpuart1_rx.Init.Request = DMA_REQUEST_5;
hdma_lpuart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_lpuart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_lpuart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_lpuart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_lpuart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_lpuart1_rx.Init.Mode = DMA_NORMAL;
hdma_lpuart1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_lpuart1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_lpuart1_rx);
/* LPUART1 interrupt Init */
HAL_NVIC_SetPriority(RNG_LPUART1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(RNG_LPUART1_IRQn);
/* USER CODE BEGIN LPUART1_MspInit 1 */
__HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_IDLE);//使能idle中断
HAL_UART_Receive_DMA(&hlpuart1,UART_buff->res_data,BUFFER_SIZE);//重新打开DMA接收
/* USER CODE END LPUART1_MspInit 1 */
}
缓存区初始化配置:
void QUE_INIT(void){
uint8_t i;
memset(QUE_buff,0,sizeof(QUE_buff));
for(i=0;i<QUE_LEN-1;i++){
QUE_buff[i].next=&QUE_buff[i+1];
QUE_buff[i].FLAG=0;
QUE_buff[i].res_counter=0;
}
QUE_buff[QUE_LEN-1].next=&QUE_buff[0];
QUE_buff[QUE_LEN-1].FLAG=0;
QUE_buff[QUE_LEN-1].res_counter=0;
UART_buff=QUE_buff;
HAND_buff=QUE_buff;
}
中断函数:
void RNG_LPUART1_IRQHandler(void)
{
/* USER CODE BEGIN RNG_LPUART1_IRQn 0 */
if((__HAL_UART_GET_FLAG(&hlpuart1,UART_FLAG_IDLE) != RESET))//判断是否为空闲中断
{
__HAL_UART_CLEAR_IDLEFLAG(&hlpuart1);//清除中断标志位
HAL_UART_DMAStop(&hlpuart1); //停止DMA传输
UART_buff->res_counter = BUFFER_SIZE - hdma_lpuart1_rx.Instance->CNDTR; //接收数据长度
UART_buff->FLAG=1; //可不要
UART_buff=UART_buff->next; //将指针指向下一个缓存区
}
HAL_UART_Receive_DMA(&hlpuart1,UART_buff->res_data,BUFFER_SIZE);//继续接收数据
/* USER CODE END RNG_LPUART1_IRQn 0 */
HAL_UART_IRQHandler(&hlpuart1);
/* USER CODE BEGIN RNG_LPUART1_IRQn 1 */
/* USER CODE END RNG_LPUART1_IRQn 1 */
}
读取UART缓存数据函数:
uint8_t RECCMD(uint16_t timeout){
uint32_t tickstart = HAL_GetTick();
while((HAND_buff==UART_buff)&&((HAL_GetTick() - tickstart) < timeout))
{
}
if(HAND_buff!=UART_buff){
RxBuffer=HAND_buff->res_data;
RxCounter=HAND_buff->res_counter;
HAND_buff->res_counter=0;
HAND_buff->FLAG=0;
HAND_buff=HAND_buff->next;
return 1;
}
return 0;
}
RxBuffer与RxCounter即为现在读出的数据,每次数据舍弃时将RxBuffer内容清空为0
最后
以上就是健康小懒猪为你收集整理的UART接收不定长数据块(队列缓存数据块)的全部内容,希望文章能够帮你解决UART接收不定长数据块(队列缓存数据块)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复