287_基于DMA的串口收发

64 篇文章 163 订阅

完整的S32K144的学习汇总如下:

https://github.com/GreyZhang/g_s32k144

DMA一直以来也是一个只闻其名的模块,在我的实际的实践中几乎没有用到。也许是我解决的问题大都不需要这么高端的功能就能够cover得了吧!

还没有看文档,直接看了一下SDK的IDE可配置信息,似乎实现这个功能基于SDK的话是很容易的。

SDK中做相应的配置,传输模式不再使用中断,而是使用DMA。之后,选择DMA通道。这个通道是需要在DMA的模块中配置的。

代码生成,之后,初始化DMA,然后做收发的测试。

首先,看得出串口的发送功能是OK的,这个打印显示功能还是正常的。接下来看看接收的功能:

从上面的结果看,这个接收功能也是可以工作的。但是,之前发现的接收数据丢失的问题似乎还是存在。后面,这个问题还是需要进一步分析解决。

完整的S32K144的学习汇总如下:

https://github.com/GreyZhang/g_s32k144

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是使用STM32F1标准库中的DMA实现串口收发的示例代码,供您参考: ``` // 定义缓冲区大小 #define BUFFER_SIZE 100 // 定义缓冲区 uint8_t RxBuffer[BUFFER_SIZE]; uint8_t TxBuffer[BUFFER_SIZE]; // 定义DMA通道和USART DMA_Channel_TypeDef* DMA_CHx; USART_TypeDef* USARTx; // 初始化串口 void USART_Init(void) { // 使能USART时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 配置USART参数 USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); // 使能USART USART_Cmd(USART1, ENABLE); } // 初始化DMA void DMA_Init(void) { // 使能DMA时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 配置DMA通道 DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USARTx->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA_CHx, &DMA_InitStructure); // 使能DMA通道中断 DMA_ITConfig(DMA_CHx, DMA_IT_TC, ENABLE); // 使能DMA通道 DMA_Cmd(DMA_CHx, ENABLE); } // DMA传输完成中断处理函数 void DMA1_Channel4_IRQHandler(void) { // 判断传输是否完成 if (DMA_GetFlagStatus(DMA_CHx, DMA_FLAG_TC)) { // 清除传输完成标志 DMA_ClearFlag(DMA_CHx, DMA_FLAG_TC); // 处理接收数据 uint16_t length = BUFFER_SIZE - DMA_GetCurrDataCounter(DMA_CHx); for (uint16_t i = 0; i < length; i++) { // 处理接收到的数据 // ... } // 启动下一次DMA传输 DMA_SetCurrDataCounter(DMA_CHx, BUFFER_SIZE); DMA_Cmd(DMA_CHx, ENABLE); } } // 发送数据 void USART_SendData(uint8_t* data, uint16_t length) { // 等待USART发送缓冲区为空 while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); // 启动DMA传输 DMA_Cmd(DMA_CHx, DISABLE); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)data; DMA_InitStructure.DMA_BufferSize = length; DMA_Init(DMA_CHx, &DMA_InitStructure); DMA_Cmd(DMA_CHx, ENABLE); // 等待DMA传输完成 while (DMA_GetFlagStatus(DMA_CHx, DMA_FLAG_TC) == RESET); } ``` 以上代码仅供参考,具体实现还需要根据实际情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值