前言:
前面已经说过,由于国赛的代码量的增加,cpu在其他代码的时间块会较省赛大大增加,为了减少对cpu的依赖所以学习DMA收发数据
对于串口中断收发来说串口接收数据无法收取不定长数据所以不好用,而DMA有收集不定长数据的函数,且不依赖cpu可谓一举两得
1、DMA收发原理:
配置好DMA,DMA就能代替cpu的工作,即将数据从源位置,转移至目的位置,如从寄存器搬给内存变量或返过来都可以,朴素的讲就是让DMA帮cpu干串口收发的活,cpu去跑其他代码,当收发完毕后DMA又会通知一声cpu,所以说DMA还是会与中断一起用
2、CUBEMX配置:
使能uart2后点击add添加传输通道和接收通道
其中increment Address 是增量地址的意思,例如传递完一个数据后指针向下移动一位,如传输hello,传递完h后再传递e,如果Memory下面不勾选,那么发送数据只会发送第一个字符
中断中的第二个唤醒中断一定要勾选,否者会产生一些不必要的BUG,如DMA发送只能发送一次,DMA接收数据不能定长接收等等
3、代码解析:
HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
DMA串口发送与接收函数,对于发送来说可以发送不定长,这个接收函数是接收定长的
对应的响应函数:
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
回调函数与中断回调函数是一致的其中cplt是complete即完成的缩写,即完成回调函数
不定长DMA接收:
DMA有扩展的不定长接收函数
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, RECEIVEMSG, 10);
其中第三个参数是能接收的最大数据长度,EX是EXTENDED即额外的意思idel是空闲的意思,这个函数在接收字符串后出现空闲,就会产生中断进入下面回调函数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
即扩展模块接收事件回调函数
DMA串口传输本就定长传输
注意DMA定长接收回调函数在接收最大设定长度一半的时候会自动进入中断函数一次
关闭过半中断函数:
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT)
也可以把接收最大参数设置大一点
总结:
总的来说uart发送字符串就用普通的UART_Transmit函数就可以因为发送一般不着急,主要时接收接收使用上述DMA的不定长接收即可