手把手配置HAL库串口的dma接收及程序编写
(1)首先在cubemx配置uart环境
1.首先在RCC中的high speed clock选择晶振 crystal.
2.在system core 中选中SYS,在右侧debug中选择serial wire.
在connectivity中选中USART1,mode选择asynchronous.
参数设置如图所示,我选择默认设置,波特率为115200。
这里面的不用管
在NVIC Settings中将USART global interrupt 的enabled选上。
点击添加add,点击select,选择dma请求
开启串口的dma发送与dma接收效果,如图所示
整体配置如图,只需要很少的配置。
最后点击 GENERATE CODE 完成框架的构建。
接下来是程序部分。
1
2
3
4
5
6
7
8
9
10
11
12
13
14int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_USART1_UART_Init(); while (1) { } }
在打开程序会显示出这样的代码。
此时在while(1)加入一个UART_Receive_DMA()函数进行接收,然后回显出来。程序添加如下图,num为测量字符串长度,特定长度回显。
1
2
3
4
5
6
7
8
9
10uint8_t buf[36]={0}; //假设num为2, while (1) { if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)buf, num)==0) { HAL_UART_Transmit_DMA(&huart1, (uint8_t *)buf ,num); } }
或者也可以写在中断中,效果是一样的,不过在配置时要打开
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);串口enabled.
1
2
3
4
5
6
7
8
9
10
11
12void USART1_IRQHandler(void) { if(HAL_UART_Receive_DMA(&huart1, (uint8_t *)sbus_rx_buf, 2)==0) { HAL_UART_Transmit_DMA(&huart1, (uint8_t *)sbus_rx_buf ,2); } HAL_UART_IRQHandler(&huart1); }
要想实现接收数据据包,还需要进一步配置。
接下来我们具体配置一下串口的dma. 配置如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#define RX_BUF_NUM 36u uint8_t cache[RX_BUF_NUM]={0}; DMA_config(&cache[0], RX_BUF_NUM); void DMA_config(uint8_t *rx_buf, uint16_t dma_buf_num) { SET_BIT(huart1.Instance->CR3, USART_CR3_DMAR); __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); __HAL_DMA_DISABLE(&hdma_usart1_rx); while(hdma_usart1_rx.Instance->CR & DMA_SxCR_EN) { __HAL_DMA_DISABLE(&hdma_usart1_rx); } hdma_usart1_rx.Instance->PAR = (uint32_t) & (USART1->DR); hdma_usart1_rx.Instance->M0AR = (uint32_t)(rx_buf); hdma_usart1_rx.Instance->M1AR = (uint32_t)(rx_buf); hdma_usart1_rx.Instance->NDTR = dma_buf_num; SET_BIT(hdma_usart1_rx.Instance->CR, DMA_SxCR_DBM); __HAL_DMA_ENABLE(&hdma_usart1_rx); }
这样,dma的config就完成了。
然后进行中断处理函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21UART_HandleTypeDef huart1; DMA_HandleTypeDef hdma_usart1_tx; DMA_HandleTypeDef hdma_usart1_rx; oid USART1_IRQHandler(void) { if(huart1.Instance->SR & UART_FLAG_RXNE)//接收到数据 { __HAL_UART_CLEAR_PEFLAG(&huart1); } else if(USART1->SR & UART_FLAG_IDLE) { __HAL_UART_CLEAR_PEFLAG(&huart1); __HAL_DMA_DISABLE(&hdma_usart1_rx); hdma_usart1_rx.Instance->NDTR = RX_BUF_NUM; DMA1_Stream1->CR &= ~(DMA_SxCR_CT); __HAL_DMA_ENABLE(&hdma_usart1_rx); } }
中断函数写完 让我们看一下现象。此时我们发送了三个1给主控,发现函数内数值已经发生改变。
重现发送数据,观察更新。
现在就可以实现一些基本的功能了。
最后把程序分享给大家
https://download.csdn.net/download/weixin_44748127/12728879
不清楚的可以在下方留言,我会尽快回复
最后
以上就是务实红牛最近收集整理的关于STM32 串口DMA方式接收字符串的全部内容,更多相关STM32内容请搜索靠谱客的其他文章。
发表评论 取消回复