STM32的串口发送中断总是乱进怎么回事?求助香城主

[复制链接]
15809|27
 楼主| 不锈钢铁 发表于 2012-4-20 14:38 | 显示全部楼层 |阅读模式
我同事开启了USART的发送和接收中断,但是程序一跑就不停的进USART中断。这是为什么?是不是接收和发送中断不能同时开?求助香城主GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;

  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
  /*
  *  USART1_TX -> PA9 , USART1_RX -> PA10
  */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
         
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  GPIO_Init(GPIOA, &GPIO_InitStructure);
   

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 9600;
  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_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
  USART_ClearFlag(USART1,USART_FLAG_TC);
  USART_Cmd(USART1, ENABLE);
airwill 发表于 2012-4-20 15:46 | 显示全部楼层
全双工方式通信吗? 上中断服务程序代码
logokfu 发表于 2012-4-20 20:50 | 显示全部楼层
中断程序拿出来看看先
 楼主| 不锈钢铁 发表于 2012-4-21 19:26 | 显示全部楼层
2# airwill 这是测试,在终端子程序中没做什么复杂的事,
void USART1_IRQHandler(void)
{
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)!= RESET)

  {  
    USART_ClearITPendingBit(USART1,  USART_IT_RXNE);  //清除中断标志
    NVIC_ClearPendingIRQ(USART1_IRQn);//清除中断标志
   a=1;
  }
if(USART_GetFlagStatus(USART1, USART_FLAG_TXE)!= RESET)

  {  
    USART_ClearITPendingBit(USART1,  USART_IT_TXE);  //清除中断标志
    NVIC_ClearPendingIRQ(USART1_IRQn);//清除中断标志
    a=0:

  }

}
 楼主| 不锈钢铁 发表于 2012-4-21 19:27 | 显示全部楼层
3# **kfu 已经附上,请帮忙看看,我哪里弄错了,先行谢过
airwill 发表于 2012-4-22 09:24 | 显示全部楼层
这是 USART 中断应用中的中断服务例子. 给你参考一下

void USART1_IRQHandler(void)
{
  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {
    /* Read one byte from the receive data register */
    RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);

    if(RxCounter1 == NbrOfDataToRead1)
    {
      /* Disable the USART1 Receive interrupt */
      USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
    }
  }
  
  if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
  {   
    /* Write one byte to the transmit data register */
    USART_SendData(USART1, TxBuffer1[TxCounter1++]);

    if(TxCounter1 == NbrOfDataToTransfer1)
    {
      /* Disable the USART1 Transmit interrupt */
      USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
    }   
  }
}
 楼主| 不锈钢铁 发表于 2012-4-22 15:51 | 显示全部楼层
6# airwill 高手,刚看了这个例子~有个疑问,为什么到了一个中断后,要失能中断?如果关了,上位机不久没法和板子通讯了
logokfu 发表于 2012-4-22 16:21 | 显示全部楼层
防止一直终端,51单片机里面也是这样用的啊
 楼主| 不锈钢铁 发表于 2012-4-23 09:04 | 显示全部楼层
8# **kfu 那如果再来信息不就进不来中断了嘛?
logokfu 发表于 2012-4-23 10:01 | 显示全部楼层
硬件中断,这里只是软件清除一下。
 楼主| 不锈钢铁 发表于 2012-4-23 10:11 | 显示全部楼层
10# **kfu USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
这条语句不是直接关上了中断嘛,不是指清除中断标志位
mcuatmel 发表于 2012-4-23 11:02 | 显示全部楼层
我也遇到了类似问题,我用的是TC中断,现在搞不懂到底是该用哪个中断来收发数据。
我收8个字符,发也是8个字符,用了TC中断,103RC MCU,共用了四个串口,1-4,现在是发现3时常不好用,不能全部把数据发出,或是最后几个不对。
资料上说单字节收发用TXE中断,多字节用TC中断合适,不知细节到底该如何控制?
我在其它产品中用TC中断,发的也是不过10个字节上下,只用了两个串口,没发现有这问题。
mcuatmel 发表于 2012-4-23 11:13 | 显示全部楼层
我的中断函数
void USART3_IRQHandler(void)
{
    /*数据发送部分*/
    if(USART_GetITStatus(USART3, USART_IT_TC) != RESET)
    {
                /* Write one byte to the transmit data register */
                /* 发送数据 */
        if(g_u8Uart3_SendSum<g_u8Uart3_SendLong)
        {
                        USART3->DR = g_u8Uart3_sbuf[g_u8Uart3_SendSum++] & 0x01FF;
        }
        else
        {
            g_u8Uart3_SendSum=g_u8Uart3_SendLong;
        }
        /* Clear the USART3 transmit interrupt */
        USART_ClearITPendingBit(USART3, USART_IT_TC);
    }
    /* 数据接收部分 */
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
    {
                /* Read one byte from the receive data register */
                g_u8Uart3_Rdelay=1;
        if (g_u8Uart3_rEnd==0)
        {
            if (g_u8Uart3_RecvSum<g_u8Uart3_RecvLong)
            {
                g_u8Uart3_rbuf[g_u8Uart3_RecvSum] = USART_ReceiveData(USART3);
                g_u8Uart3_RecvSum++;
                if (g_u8Uart3_RecvSum>=g_u8Uart3_RecvLong)
                {
                    g_u8Uart3_rEnd=1;
                                        g_u8Uart3_RecvSum=0;
                                        g_u8Uart3_Rdelay=0;
                }
            }
        }
        /* Clear the USART1 Receive interrupt */
        USART_ClearITPendingBit(USART3, USART_IT_RXNE);
    }
//        Uart3Isr();
}
LAORUAN 发表于 2012-4-23 11:58 | 显示全部楼层
Bit 7 TXE : Transmit data register empty
This bit is set by hardware when the content of the TDR register has been transferred into
the shift register. An interrupt is generated if  the TXEIE bit =1 in the USART_CR1 register. It
is cleared by a write to the USART_DR register.
0: Data is not transferred to the shift register
1: Data is transferred to the shift register)

仔细看看这段话。TXE在数据寄存器为空的时候就会置一,也就是说你的数据发送完成之后,如果没有数据发送了,这一位就是置一的。既然是置一的,那么就会发生中断。所以要关一下中断,要发送数据的时候可以再开启中断。
 楼主| 不锈钢铁 发表于 2012-4-24 15:42 | 显示全部楼层
14# LAORUAN 多谢~
qinweixing 发表于 2012-4-25 09:19 | 显示全部楼层
发送完数据要关掉发送中断,接受中断不用关,如果你不关闭发送中断,那程序会永远死在中断里的
gudujiangren 发表于 2012-9-25 10:03 | 显示全部楼层
我也觉得好奇,既然TXE中断时,处理的时候要关掉中断,为什么不用TC中断,发送完成中断,读状态清掉TC或者直接给0清掉,我觉得TC中断不是更好用些,又不用关中断,只要中断处理数据非常短的话,只有每次发数据,而且是自个发送完之后才中断,多好啊,不知道我这样理解对不对。
天罡星lmy 发表于 2013-5-28 18:07 | 显示全部楼层
djqinqing 发表于 2013-7-9 09:12 | 显示全部楼层
leshak 发表于 2013-8-20 14:30 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:小鸟快跑

31

主题

730

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部