你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于STM32F030的串口发送不能中断,请大侠们帮忙看看

[复制链接]
yinlian 提问时间:2015-7-26 00:11 /
本帖最后由 yinlian 于 2015-7-27 00:05 编辑

    最近在开发的一个案子,使用STM32F030C8T6 主芯片,需要用到STM32F030C8T6的串口与外设完成通讯和控制,现在遇到的问题是:接收没有问题,单独发送也没有问题,但是将接收到的信息转化为控制命令发送回去的时候,发现出程序不能产生中断,程序死在发送函数了:下面是源码,请大侠们帮忙看看问题出在哪里:
    static          void          USART1_Init_config()
{
                   GPIO_InitTypeDef      GPIO_Init_Struct;
                   NVIC_InitTypeDef      NVIC_Init_Struct;
                   USART_InitTypeDef      USART_Init_Struct;
                    //¶¨ÒåGPIO¡¢USART ³õʼ»¯½á¹¹Ìå
                   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
                   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
                   //´ò¿ªUSART1¡¢GPIOB(USART1 TX/RX ¸´ÓÃÒý½Å)ʱÖÓ
                   USART1_DMA_config();
                   //ÅäÖÃUSART1 µÄDMAͨµÀ£»
                   GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_0);
                   GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_0);
                   GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
                   GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_AF;
                   GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_Level_3 ;
                   GPIO_Init_Struct.GPIO_OType = GPIO_OType_PP;
                   GPIO_Init_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
                   GPIO_Init(GPIOB,&GPIO_Init_Struct);
                   //ÅäÖÃPB6 ¡¢PB7ΪUSART1 TX ¡¢RX£¨ÍÆÃâÊä³öģʽ£©
                   NVIC_Init_Struct.NVIC_IRQChannel = USART1_IRQn;
            NVIC_Init_Struct.NVIC_IRQChannelPriority = 0x01;
            NVIC_Init_Struct.NVIC_IRQChannelCmd = ENABLE;
            NVIC_Init(&NVIC_Init_Struct);
           //ÅäÖÃNVICÖжÏUSART1 ÖжÏ
                   USART_Init_Struct.USART_BaudRate = 57600;
                   USART_Init_Struct.USART_WordLength = USART_WordLength_8b;
                   USART_Init_Struct.USART_StopBits = USART_StopBits_1;
                   USART_Init_Struct.USART_Parity = USART_Parity_No;
          USART_Init_Struct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
          USART_Init_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
          USART_Init(USART1, &USART_Init_Struct);
          USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);
          USART_ITConfig(USART1, USART_IT_TXE,DISABLE);
          USART_Cmd(USART1, ENABLE);
          //ÅäÖÃUSART1 Ϊ57600¡¢8¡¢1¡¢ÎÞ È«Ë«¹¤Ò첽ͨѶ£»
    上面的代码是,打开串口1中断,配置串口1为全双工异步通讯模式,(配置:57600、8、无、无、1)
          void      USART1_IRQHandler(void)
{
          if  (USART_GetITStatus(USART1,USART_IT_RXNE) == ENABLE)
      {
         USART1_RxData_buffer[USART1_ReadData_count] = USART_ReceiveData(USART1);
         USART1_ReadData_count++;
         if (USART1_ReadData_count == 1 && \
           USART1_RxData_buffer[0] != 'A')
        {
           USART1_ReadData_count = 0;
        }
        else if (USART1_ReadData_count == 2 && \
                 USART1_RxData_buffer[1] != 'X')
        {
           USART1_ReadData_count = 0;
        }
        else if (USART1_ReadData_count == 3 && \
                 USART1_RxData_buffer[2] != 'X')
        {
           USART1_ReadData_count = 0;
        }
         if (USART1_ReadData_count >= 11)
        {
           USART1_Rx_Status = SET;
           USART1_RxData_buffer[USART1_ReadData_count] = '\n';
           USART1_RxData_buffer[USART1_ReadData_count+1] = '\0';
           USART1_ReadData_count = 0;   
        }
       }
      //串口接收
      if  (USART_GetITStatus(USART1,USART_IT_TXE) == ENABLE)
      {
             USART_ITConfig(USART1,USART_IT_TXE,DISABLE);
             USART1_Busy  =  RESET;
      }
}
      上面的代码是串口中断应用函数,当发送寄存器为空时产生中断,清除串口忙标志,以便发送函数判断发送是否完成。
      void            USART1_Printf(uint8_t*   String)
{
         while  (*String  !=  '\0')
          {
                   USART_SendData(USART1, (uint16_t)*String);
                    USART_ITConfig(USART1,USART_IT_TXE,ENABLE);
                    USART1_Busy  =  SET;
               while (USART1_Busy  ==  SET)
               {
                   Char_LED(ON);
               }
                String++;
          }
          USART_ITConfig(USART1,USART_IT_TXE,DISABLE);
}
         上面是串口发送函数,发送完成时由中断函数清除串口忙标志;
         下载程序后出现的现象是:程序启动时串口能够发送数据,比如我在主程序写这样一行代码:
              USART1_Printf("power on\n");
          串口助手能够看到打印信息;说明发送中断是可以工作的;但是当收到串口发来的字符串,再将字符串原样返回的时候 ,程序进入死循环了。在串口助手上只能看到第一个字符,其他字符打印不出来;说明程序发送第一个字符后进入死循环;分析程序,应该是死在这句:
          while (USART1_Busy  ==  SET)
                        {
                                  Char_LED(ON);
           }
         这个标志位是在串口中断函数中,清除的;难道没有产生串口中断????但是为什么这句:USART1_Printf("power on\n");能够打印出信息呢?
将发送改到串口2发送,收到的字符串能够原样返回。调试了两天,实在百思不得其解!!!难道STM32的串口不能同时使用发送和接收中断吗?
         还望那位大侠能给小弟指点一二,不胜感激!!!!


STM32F0 project.rar

下载

4.94 MB, 下载次数: 134, 下载积分: ST金币 -1

完整工程文件

收藏 评论17 发布时间:2015-7-26 00:11

举报

17个回答
00-405686 回答时间:2015-7-26 02:17:44
USART_ITConfig(USART1, USART_IT_TXE,DISABLE);这里把发送中断关了;
if  (USART_GetITStatus(USART1,USART_IT_TXE) == ENABLE)
      {
             USART_ITConfig(USART1,USART_IT_TXE,DISABLE);
             USART1_Busy  =  RESET;
      }
这个条件应该一直不会执行;
所以Busy一直为1吧
yinlian 回答时间:2015-7-26 11:05:30
00-405686 发表于 2015-7-26 02:17
USART_ITConfig(USART1, USART_IT_TXE,DISABLE);这里把发送中断关了;
if  (USART_GetITStatus(USART1,US ...

      已经验证,不会是这个原因,程序中有两个地方关闭发送寄存器为空中断,一个在中断函数里、一个是当所有字符发送完成,遇到“\0”结束发送循环后,关闭发送寄存器为空中断,因为发送寄存器为空中断标志位必须通过写发送寄存器来清除,我的程序不上在中断函数写发送寄存器的,所以必须在响应中断后关闭中断请求;在发送函数里先写发送寄存器清除标志位,在开发送寄存器空中断请求:如下代码:
    while  (*String  !=  '\0')
           {
                    USART_SendData(USART1, (uint16_t)*String);
                     USART_ITConfig(USART1,USART_IT_TXE,ENABLE);
                     USART1_Busy  =  SET;
                while (USART1_Busy  ==  SET)
                {
                    Char_LED(ON);
                }
                 String++;
           }
         不然的话,程序会一直在响应中断,不能处理发送函数,造成程序死循环;
      我在主循环中写这样一句:USART1_Printf("main  run is  ok\n");在没有通过串口助手发送字符串之前,一直可以看到程序不断打印出这个消息;如果通过串口发送一个字符串,程序返回我发送的字符串的第一个字符,然后就进入死循环了。
     还是请再帮忙看看,是什么原因发送寄存器空中断没有响应?
Paderboy 回答时间:2015-7-26 11:29:34
帮顶。。。
00-405686 回答时间:2015-7-26 11:30:44
yinlian 发表于 2015-7-26 11:05
已经验证,不会是这个原因,程序中有两个地方关闭发送寄存器为空中断,一个在中断函数里、一个是当 ...

这样还是不好看,能把你的工程文件加上来吗
moyanming2013 回答时间:2015-7-26 13:47:27
1.jpg
yinlian 回答时间:2015-7-26 22:36:04
00-405686 发表于 2015-7-26 11:30
这样还是不好看,能把你的工程文件加上来吗

怎么上传附件呢?
第一次在论坛发帖,请多指教!!!
00-405686 回答时间:2015-7-26 23:23:20
yinlian 发表于 2015-7-26 22:36
怎么上传附件呢?
第一次在论坛发帖,请多指教!!!

压缩包,添加附件
yinlian 回答时间:2015-7-27 00:07:43
00-405686 发表于 2015-7-26 23:23
压缩包,添加附件

     完整的工程文件已经附上, 请帮忙看看是什么问题造成一旦接收中断产生后,就不能产生发送中断了????在没有产生接收中断前,发送中断是可以正常工作的!!!
yinlian 回答时间:2015-7-27 00:10:06

   需要帮忙看看程序出现了什么问题,顶贴不能解决什么问题,反而有借机赚分的嫌疑
12下一页
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版