stm32f1dma中断标准modbus485收发例程
时间: 2023-05-10 20:02:48 浏览: 173
stm32 485小例子
5星 · 资源好评率100%
STMicroelectronics的STM32F1系列是面向高性能嵌入式应用的32位Flash MCU。而在工业自动化控制领域中,常使用Modbus协议实现设备之间的通信。因此在这样的应用场景中,STM32F1系列与Modbus协议的结合是非常相符的。
在STM32F1中,使用DMA可以大大提高UART的通信效率。DMA是一种专门用来处理数据传输的硬件模块,它可以独立地、自动地完成存储器与外设之间的数据传输,而不需要CPU干预。因此在这篇文章中,我们将使用STM32F1的DMA模块结合Modbus协议实现485通信。
一般的Modbus中断接收代码如下:
```
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET) {
/* Clear interrupt flag. */
USART1->SR &= ~USART_SR_RXNE;
/* Put received data into buffer. */
buffer[dma_buf_cnt++] = USART1->DR;
/* Increase buffer count. */
if(dma_buf_cnt >= MODBUS_BUFFER_SIZE)
{
dma_buf_cnt = 0;
}
}
}
```
对此,我们只需要使用STM32F1的DMA来取代一般的中断接收程序即可。大致步骤如下:
1. 配置USART的DMA模式
```
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
DMA_InitTypeDef dma_InitStruct;
DMA_DeInit(DMA1_Channel5);
dma_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR);
dma_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma_InitStruct.DMA_MemoryBaseAddr = (uint32_t)recv_buf;
dma_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
dma_InitStruct.DMA_BufferSize = RECV_BUF_SIZE;
dma_InitStruct.DMA_Mode = DMA_Mode_Circular;
dma_InitStruct.DMA_Priority = DMA_Priority_VeryHigh;
DMA_Init(DMA1_Channel5, &dma_InitStruct);
DMA_Cmd(DMA1_Channel5, ENABLE);
```
2. 配置USART的中断
```
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
```
3. 配置DMA的中断
```
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
```
4. 在DMA传输完成中断中处理数据
```
void DMA1_Channel5_IRQHandler(void)
{
if (DMA_GetITStatus(DMA1_IT_TC5))
{
DMA_ClearITPendingBit(DMA1_IT_TC5);
modbus_master_execute(recv_buf, res_buf);
}
}
```
上述过程仅为一个大致的流程说明。具体详细的代码实现可参考ST微电子官方提供的STM32F1系列Modbus通信例程。此例程中,在STM32的USART1上实现了Modbus协议485通信,采用DMAMode2传输方式,降低了CPU的工作负担,提高了数据传输效率。
阅读全文