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

关于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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版