本帖最后由 一路向北lm 于 2022-3-16 11:08 编辑
杂谈6 串口空闲中断 + DMA 不定长数据帧接收 串口不定长数据帧扮演者很重要的角色,我想一个写通讯的程序不会撸这段代码怎么能行呢?借着雅特力这块宝地,开始造起来! 第一步串口GPIO初始化 - //****************************************************************
- //****** 串口GPIO初始化函数
- //****** 输入参数: 无
- //****** 返回值: 无
- //****************************************************************
- static void PhyUartGpioInit()
- {
- gpio_init_type gpio_init_struct;
- crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
- gpio_default_para_init(&gpio_init_struct);
-
- gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
- gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
- gpio_init_struct.gpio_pins = GPIO_PINS_9|GPIO_PINS_10;
- gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
- gpio_init(GPIOA, &gpio_init_struct);
-
- gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE9, GPIO_MUX_1);
- gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE10, GPIO_MUX_1);
-
- }
第二步 串口参数初始化 - //****************************************************************
- //****** 串口参数初始化函数
- //****** 输入参数: uint32_t baudrate 波特率
- //****** 返回值: 无
- //****************************************************************
- static void PhyUartCoreInit(uint32_t baudrate)
- {
- crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
- usart_init(USART1, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
- usart_parity_selection_config(USART1, USART_PARITY_NONE);
- usart_transmitter_enable(USART1, TRUE);
- usart_receiver_enable(USART1, TRUE);
- usart_dma_receiver_enable(USART1, TRUE);
- nvic_irq_enable(USART1_IRQn, 0, 0);
- usart_interrupt_enable(USART1, USART_IDLE_INT, TRUE);
- usart_enable(USART1, TRUE);
- }
第三步 串口DMA初始化 - //****************************************************************
- //****** 串口DMA参数初始化函数
- //****** 输入参数: 无
- //****** 返回值: 无
- //****************************************************************
- void PhyUartDmaInit()
- {
- dma_init_type dma_init_struct;
- crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
- dma_reset(DMA1_CHANNEL3);
- dma_default_para_init(&dma_init_struct);
- dma_init_struct.buffer_size = USART_RX_BUFFER_SIZE;
- dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
- dma_init_struct.memory_base_addr = (uint32_t)UartRxBuffer;
- dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
- dma_init_struct.memory_inc_enable = TRUE;
- dma_init_struct.peripheral_base_addr = (uint32_t)&USART1->dt;
- dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
- dma_init_struct.peripheral_inc_enable = FALSE;
- dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
- dma_init_struct.loop_mode_enable = FALSE;
- dma_init(DMA1_CHANNEL3, &dma_init_struct);
- dma_channel_enable(DMA1_CHANNEL3, TRUE);
- }
第四步 串口初始化,以上三个**合力! - //****************************************************************
- //****** 串口初始化函数
- //****** 输入参数: 无
- //****** 返回值: 无
- //****************************************************************
- void PhyUartInit()
- {
- PhyUartGpioInit();
- PhyUartDmaInit();
- PhyUartCoreInit(115200);
- }
第五步 最关键的一步,串口空闲中断处理函数! - //****************************************************************
- //****** 串口中断处理函数
- //****** 输入参数: 无
- //****** 返回值: 无
- //****************************************************************
- void USART1_IRQHandler()
- {
- uint16_t rc_len;
- if(usart_flag_get(USART1, USART_IDLEF_FLAG) != RESET)
- {
- usart_data_receive(USART1);
- dma_channel_enable(DMA1_CHANNEL3,FALSE);
- rc_len = USART_RX_BUFFER_SIZE - dma_data_number_get(DMA1_CHANNEL3);
- dma_data_number_set(DMA1_CHANNEL3, USART_RX_BUFFER_SIZE);
- dma_channel_enable(DMA1_CHANNEL3,TRUE);
- if((UartRxBuffer[1]>=0x80) && (UartRxBuffer[1]<=0x90)) //使用命令码过滤错误帧
- {
- UartRecvSta = 1;
- UartFramRecvLen = rc_len;
- }
- else
- {
- UartFramRecvLen = 0;
- UartRecvSta = 0;
- }
- }
- }
最后,在补充一些变量哈,大家知道它是怎么来的。 - #define USART_RX_BUFFER_SIZE 1024
- uint8_t UartRxBuffer[1024]; //串口接收帧Buffer
- uint16_t UartFramRecvLen; //串口接收帧长度
- uint8_t UartRecvSta; //串口接收帧完成标志位
|