历史上的今天
今天是:2025年03月06日(星期四)
2019年03月06日 | STM32中485采用串口DMA发送,切换收发状态问题
2019-03-06 来源:eefocus
RS485使用DMA发送,切换收发状态,有以下几种实现方式:
开启DMA的“发送完成中断”,在DMA的发送完成中断中,切换收发的状态。但是,这会导致最后的2个字节发送不出去,这是因为:DMA的“发送完成中断”出现在刚发送倒数第二个字节的起始位置,这个时候切换485的收发,若接收端不是奇校验的话 将会误收到0xFF 最后第一肯定也出不去。
网上提供的解决办法是:①在DMA的TC中断里面 加大于两个字节的延时 这是OK的。 ②在DMA的TC中断里面 开启USART的“发送完成中断” 去USART的中断里面去处理 这是OK的。
看数据手册,可以利用串口的“发送完成中断TC”实现。开启USART的DMA,开启DMA传输通道,开启USART的“发送完成中断TC”
具体实现:
配置USART和DMA ,DMA中断不用开。
准备发送的时候,
切换为485发送 RS485EN_TX();-
配置好DMA。传输的数据,与长度。
开启USART的传输完成TC中断
使能DMA =======等串口TC中断就行。
中断服务函数中,失能TC 切换485接收。
开始传输:
//-----尝试不开启DMA TC中断 直接直观传输
void USART2_SendMsg(INT8U *msg,INT8U len)
{
SET_RS485_SEND; //高发送
DMA_ClearFlag(DMA1_FLAG_TC7); //清DMA发送完成标志
USART_ClearITPendingBit(USART2,USART_IT_TC);
DMA_Cmd(DMA1_Channel7, DISABLE); //停止DMA
DMA1_Channel7->CMAR = (INT32U) msg; //源地址
DMA1_Channel7->CNDTR = len;//重设传输长度
USART_ITConfig(USART2,USART_IT_TC,ENABLE);
DMA_Cmd(DMA1_Channel7, ENABLE); //启动DMA
}
传输完成后:
void USART2_IRQHandler(void)
{
/*
...................
*/
if(0x00000040 & (USART2->SR))//(USART_GetITStatus(USART2,USART_IT_TC))
{
USART2->SR &= ~0x00000040;//USART_ClearITPendingBit(USART2,USART_IT_TC);
OSSemPost(Sem_Usart2Send);
SET_RS485_RECV; //发送完毕 改成接收状态
USART2->CR1 &= ~0x00000040;//USART_ITConfig(USART2,USART_IT_TC,DISABLE);
//OSIntExit();
return;
}
/*
...................
*/
}
这里说一下,我由于使用的时候,在发送的时候没有“清除发送完成标志”,导致传输第一个字节后,就进入了TC中断,切换了485状态。
代码:
RS485EN_TX(); //485切换为发送模式
__HAL_UART_DISABLE_IT(&UART3_Handler,USART_IT_RXNE); /* 禁止接收中断 */
__HAL_UART_ENABLE_IT(&UART3_Handler,USART_IT_TC); /* 使能发送完成中断 */
if(__HAL_DMA_GET_FLAG(&UART3TxDMA_Handler,DMA_FLAG_TCIF3_7)) //等待传输完成
{
__HAL_DMA_CLEAR_FLAG(&UART3TxDMA_Handler,DMA_FLAG_TCIF3_7);//清除DMA1_Steam3传输完成标志
HAL_UART_DMAStop(&UART3_Handler); //传输完成以后关闭串口DMA
}
时序:

修改后,在前面添加清除发送完成标志TC”后,既可以。
代码:
RS485EN_TX(); //485切换为发送模式
__HAL_UART_CLEAR_FLAG(&UART3_Handler,UART_FLAG_TC);
if(__HAL_DMA_GET_FLAG(&UART3TxDMA_Handler,DMA_FLAG_TCIF3_7)) //等待传输完成
{
__HAL_DMA_CLEAR_FLAG(&UART3TxDMA_Handler,DMA_FLAG_TCIF3_7);//清除DMA1_Steam3传输完成标志
HAL_UART_DMAStop(&UART3_Handler); //传输完成以后关闭串口DMA
}
__HAL_UART_DISABLE_IT(&UART3_Handler,USART_IT_RXNE); /* 禁止接收中断 */
__HAL_UART_ENABLE_IT(&UART3_Handler,USART_IT_TC); /* 使能发送完成中断 */
MYDMA_USART_Transmit(&UART3_Handler,(u8*)USART3_TX_BUF,DRIVER_FRAME_LENGTH); //启动传输
传输完成后:
//串口3中断服务程序
void USART3_IRQHandler(void)
{
uint8_t Res=0;
uint16_t u16CheckCrcTemp = 0;
if((__HAL_UART_GET_FLAG(&UART3_Handler,UART_FLAG_TC)!=RESET))
{
__HAL_UART_CLEAR_FLAG(&UART3_Handler,UART_FLAG_TC);
RS485EN_RX();
__HAL_UART_ENABLE_IT(&UART3_Handler,USART_IT_RXNE);
__HAL_UART_DISABLE_IT(&UART3_Handler,USART_IT_TC);
}
if((__HAL_UART_GET_FLAG(&UART3_Handler,UART_FLAG_RXNE)!=RESET))
{
__HAL_UART_CLEAR_FLAG(&UART3_Handler,UART_FLAG_RXNE);
Res = USART3->DR;
g_us485AlarmCnt=0; //485通信5s报警检测
if(USART3_RX_STA & 0x4000)
{
++USART3_RX_STA;
USART3_RX_BUF[USART3_RX_STA & 0xfff] = Res;
if((USART3_RX_STA & 0xfff) == DRIVER_FRAME_LENGTH-1) //接收帧尾
{
u16CheckCrcTemp = *(uint16_t*)(USART3_RX_BUF + DRIVER_FRAME_LENGTH - 2);
if(u16CheckCrcTemp == crc_16((unsigned char *)USART3_RX_BUF,DRIVER_FRAME_LENGTH-2))
{
if(USART3_RX_BUF[2]==0xff || USART3_RX_BUF[2]==g_ulaGdBuf[INDEX_ID]) //是否是正确的ID
{
run_driver_cmd();
}
}
USART3_RX_STA = 0;
}
}
else if(USART3_RX_STA & 0x8000) //接收一帧数据的第二个数据 ---0xef 2017.1.13
{
if(Res != 0xfb)
USART3_RX_STA = 0;
else
{
USART3_RX_BUF[(++USART3_RX_STA)&0xfff] = Res;
USART3_RX_STA |= 0x4000;
}
}
else if(Res == 0xbf) //接收一帧数据的第一个数据 ---0xfb 2017.1.13
{
USART3_RX_BUF[USART3_RX_STA & 0xfff] = Res;
USART3_RX_STA |= 0x8000;
}
}
}
时序为:

下一篇:STM32外部晶振不起振
史海拾趣
|
前段时间比较忙,没来得及分析LM3S8962串口问题。今天花了一上午时间搞定了,原来是232片子坏了,换了个新的,串口能调通了。顺便发点LM3S8962串口的资料,大家共同学习进步。 [ 本帖最后由 beyondvv 于 2010-9-25 22:27 编辑 ]… 查看全部问答> |
|
图中是一个产生500V左右高压的稳幅振荡电路,其中振荡电路点部分有一个磁罐,其中绕线如下图所示,磁罐输出端是100匝绕线,500V高压,和三极管 连接的是1匝和4匝绕线,电感分别是0.2uH和1.1uH左右,分别接在三极管的发射级和集电极,发射极的2个电 ...… 查看全部问答> |
|
就是防止程序被读出来,看手册上有一种是通过设置flash寄存器加密。但是有看见别人提到利用96位的stm32芯片ID号加 ...… 查看全部问答> |
|
使用msp430f5418+HT1621B驱动段式液晶 先调试了两块样机 一切正常 但是后来把样机发给客户之后 客户再回发给我后 我想再做一些相关测试 供电一段时间后发现显示忽然不正常了 灰度很暗很暗 随后又焊接两块板子进行调试 都是一样的症状 最后进行相关 ...… 查看全部问答> |




