STM32的USART做RS485通信发送时为何进入接收中断
最近用STM32F103的USART3做RS485通信,接口芯片是SP3485,因为RS485是半双工的工作方式,发送的时候不能接收,接收的时候不能发送,但是为什么我在调试的时候发现运行发送程序时会响应接收中断,且接收到的数据是十六进制的“00”,程序中我只开了接收中断。为此很不解,下面贴出我的部分程序,卡了几天不知道,请大家给点意见。
我的主程序是键一按下就发送一个字符,接收中断服务程序是将接收到的字符发送出去,如果正常的话,那么我按一个键就会PC就收到一个字符,但是我这里是按一下就收到2个字符,前一个是正确的,后一个是十六进制的“00”,因为这是这个“00”是STM32接收到的,再发送给PC的。(不管是两块STM32通信还是STM32和PC通信都会出现这个问题)
USART配置程序:
void RS485_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_2;
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(USART485, &USART_InitStructure);
USART_Cmd(USART485, ENABLE);
//打开接收中断
USART_ITConfig(USART485, USART_IT_RXNE, ENABLE);
}
发送程序:
void RS485PutChar(char c)
{
GPIO_SetBits(GPIOB, GPIO_RS485_DE_PIN);
GPIO_SetBits(GPIOB, GPIO_RS485_RE_PIN);
// 操作SP3458,改为发送模式
Delay(0x1fff); // 此处会触发接收中断
USART_SendData(USART485, c);
while (USART_GetFlagStatus(USART485, USART_FLAG_TXE) == RESET);
Delay(0xffff);
GPIO_ResetBits(GPIOB, GPIO_RS485_RE_PIN);
GPIO_ResetBits(GPIOB, GPIO_RS485_DE_PIN); // 操作SP3458,改为接收模式
}
中断服务程序:
void USART3_IRQHandler(void)
{
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_9,(BitAction)(1-GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9)) );
RS485PutChar(USART_ReceiveData(USART3));
//把接收到的字符通过//USART3(RS485)发送出去
}
}
我也用STM32做过RS485通信,印象里没有大问题。
有1点需要注意:串口的Rx引脚可能需要上拉电阻。
另外,建议用示波器看看串口的Rx引脚有没有毛刺。
谢谢 IJK的提醒。
但是目前碰到的这个问题让我很费解。
回 ploto ,开发板上的电路图里没有接上下拉电阻,我只是在外面接了个120欧的终端电阻。
回 版主主,,我用示波器测了下STM32 的RX 的信号,空闲时RX是高电平,在发送的时候确实有个大约10MS的负脉冲,所以触发了接收中断。但不知道为什么会有个这个负脉冲?
情况大概是这样的
void RS485PutChar(char c)
{
GPIO_SetBits(GPIOB, GPIO_RS485_DE_PIN);
GPIO_SetBits(GPIOB, GPIO_RS485_RE_PIN); //执行这句后RO=0
Delay(0x1fff); // 此处会触发接收中断,不知道为什么
USART_SendData(USART485, c);
while (USART_GetFlagStatus(USART485, USART_FLAG_TXE) == RESET); //此时测得RO=0
Delay(0xffff);
GPIO_ResetBits(GPIOB, GPIO_RS485_RE_PIN); //执行这句后RO=1
GPIO_ResetBits(GPIOB, GPIO_RS485_DE_PIN);
} 后来我就用了个一个折中的办法,就是在发送的时候把接收中断关了,这样还是可以,但对于RX为什么会出现负脉冲,我还是很不解。
void RS485PutChar(char c)
{
USART_ITConfig(USART485, USART_IT_RXNE, DISABLE);
GPIO_SetBits(GPIOB, GPIO_RS485_DE_PIN);
GPIO_SetBits(GPIOB, GPIO_RS485_RE_PIN); //执行这句后RO=0
Delay(0x1fff);
USART_SendData(USART485, c);
while (USART_GetFlagStatus(USART485, USART_FLAG_TXE) == RESET);
Delay(0xffff);
GPIO_ResetBits(GPIOB, GPIO_RS485_RE_PIN); //执行这句后RO=1
GPIO_ResetBits(GPIOB, GPIO_RS485_DE_PIN);
USART_ClearFlag(USART3, USART_FLAG_RXNE);
USART_ITConfig(USART485, USART_IT_RXNE, ENABLE);
}
回 ploto ,开发板上的电路图里没有接上下拉电阻,我只是在外面接了个120欧的终端电阻。
回 版主主,,我用示波器测了下STM32 的RX 的信号,空闲时RX是高电平,在发送的时候确实有个大约10MS的负脉冲,所以触发了接收中断。但不知道为什么会有个这个负脉冲?
这就说明STM32并没有误动作。这样的话,你就要检查一下这个10ms的负脉冲是哪里来的,但我可以肯定不是STM32的RX引脚出来的。
485的控制脚是自动倒向的还是GPIO控制的?怀疑一下控制电路
没有想到这么久的帖子还有人到。这个东西我已经没有做了。但是的做法是在7楼说的,在发送程序里关掉接受中断,且清除掉中断标志位,这样做勉强可以。
至于RX脚那个脉冲信号的来源,我不知道,现在也没有再搞这个了。
回 ploto ,485的控制脚是GPIO控制的。
我遇到过,你看看电路,接收端是否有上拉电阻,如果没有,你配置成上拉输入就可以了
楼主,我遇到相同的问题,我已经搞定,加我的QQ1650743869