打印

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

[复制链接]
14580|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:

  }

}

使用特权

评论回复
5
不锈钢铁|  楼主 | 2012-4-21 19:27 | 只看该作者
3# **kfu 已经附上,请帮忙看看,我哪里弄错了,先行谢过

使用特权

评论回复
6
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);
    }   
  }
}

使用特权

评论回复
7
不锈钢铁|  楼主 | 2012-4-22 15:51 | 只看该作者
6# airwill 高手,刚看了这个例子~有个疑问,为什么到了一个中断后,要失能中断?如果关了,上位机不久没法和板子通讯了

使用特权

评论回复
8
logokfu| | 2012-4-22 16:21 | 只看该作者
防止一直终端,51单片机里面也是这样用的啊

使用特权

评论回复
9
不锈钢铁|  楼主 | 2012-4-23 09:04 | 只看该作者
8# **kfu 那如果再来信息不就进不来中断了嘛?

使用特权

评论回复
10
logokfu| | 2012-4-23 10:01 | 只看该作者
硬件中断,这里只是软件清除一下。

使用特权

评论回复
11
不锈钢铁|  楼主 | 2012-4-23 10:11 | 只看该作者
10# **kfu USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
这条语句不是直接关上了中断嘛,不是指清除中断标志位

使用特权

评论回复
12
mcuatmel| | 2012-4-23 11:02 | 只看该作者
我也遇到了类似问题,我用的是TC中断,现在搞不懂到底是该用哪个中断来收发数据。
我收8个字符,发也是8个字符,用了TC中断,103RC MCU,共用了四个串口,1-4,现在是发现3时常不好用,不能全部把数据发出,或是最后几个不对。
资料上说单字节收发用TXE中断,多字节用TC中断合适,不知细节到底该如何控制?
我在其它产品中用TC中断,发的也是不过10个字节上下,只用了两个串口,没发现有这问题。

使用特权

评论回复
13
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();
}

使用特权

评论回复
14
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在数据寄存器为空的时候就会置一,也就是说你的数据发送完成之后,如果没有数据发送了,这一位就是置一的。既然是置一的,那么就会发生中断。所以要关一下中断,要发送数据的时候可以再开启中断。

使用特权

评论回复
15
不锈钢铁|  楼主 | 2012-4-24 15:42 | 只看该作者
14# LAORUAN 多谢~

使用特权

评论回复
16
qinweixing| | 2012-4-25 09:19 | 只看该作者
发送完数据要关掉发送中断,接受中断不用关,如果你不关闭发送中断,那程序会永远死在中断里的

使用特权

评论回复
17
gudujiangren| | 2012-9-25 10:03 | 只看该作者
我也觉得好奇,既然TXE中断时,处理的时候要关掉中断,为什么不用TC中断,发送完成中断,读状态清掉TC或者直接给0清掉,我觉得TC中断不是更好用些,又不用关中断,只要中断处理数据非常短的话,只有每次发数据,而且是自个发送完之后才中断,多好啊,不知道我这样理解对不对。

使用特权

评论回复
18
天罡星lmy| | 2013-5-28 18:07 | 只看该作者
mark

使用特权

评论回复
19
djqinqing| | 2013-7-9 09:12 | 只看该作者
mark

使用特权

评论回复
20
leshak| | 2013-8-20 14:30 | 只看该作者
mark

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:小鸟快跑

31

主题

730

帖子

5

粉丝