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

main()和中断里没有串口1的处理语句,但跟上位机的通讯正常

[复制链接]
jstiger 提问时间:2019-6-28 10:37 /
新手咨询个问题,一直困惑很久了,求解答。
板子是采用STM32L151,程序是前人写的,其中有一功能块是跟上位机或后台485通讯,用的是UART1,通讯很正常。但我一直在困惑程序是怎么处理串口1的,因为在main()里除了串口1初始化语句外,没有任何该串口的处理语句。在中断部分里也是普通的串口发送接收语句。系统里也没看到OS方面的语句(自己还没学过OS这一块,当时担心是不是程序里加了OS),但uart1跟后台通讯很正常,一直琢磨这程序是怎么运行的。我贴出具体程序,烦请帮忙分析一下。

在中断stm32l1xx_it.c里有串口的处理语句:
void USART1_IRQHandler(void)
{
  App_UART1_Irq_Handle();
  App_UART1_Task();    //通信任务
}


在App_UART1_Irq_Handle()里,就是正常的串口接收和发送,要说复杂点就是用了队列通讯方式,其他也没看出有跳转出去执行通讯处理部分。
void App_UART1_Irq_Handle(void)
{
  //接收中断
  if(USART_GetITStatus(RS485_USARTX, USART_IT_RXNE) != RESET)
  {
    g_Com_Buff.com_Buff[g_Com_Buff.com_lenth] = Sub_Com_check_even(USART_ReceiveData(RS485_USARTX)); //接收数据并进行偶校验
    g_Com_Buff.com_lenth++;
    //判断长度超标处理
    if (g_Com_Buff.com_lenth > MAX_ADU_LENTH)
    {
      g_Com_Buff.com_lenth = 0;
    }
    //发送串口接收消息
    Queue_Insert(&Com_Queue ,COM_MSQ_IDLE_RX_ONE_BYTE);
    USART_ClearFlag(RS485_USARTX, USART_FLAG_RXNE);//清除中断标志
  }

  //发送中断
  if(USART_GetITStatus(RS485_USARTX, USART_IT_TXE) != RESET)
  {
    USART_SendData(RS485_USARTX, g_Com_Buff.com_Buff[current_send++]);
    if(current_send >= g_Com_Buff.com_lenth)
    {
      //等待最后一个数据送完
      while(USART_GetFlagStatus(RS485_USARTX, USART_FLAG_TC) == RESET);
      USART_ClearFlag(RS485_USARTX, USART_FLAG_TC);
      //关发送中断
      Bsp_rs485_Tx_Int_Ctr(0);
      //current_send = 0;
      if(Queue_Insert(&Com_Queue ,COM_MSQ_RESPON_OK) != Q_OK)
      {
        Bsp_rs485_dir_Ctr(1);
        Bsp_rs485_Rx_Int_Ctr(1);
      }
    }
  }
}


在 App_UART1_Task();里
void App_UART1_Task(void)
{
    /*!< 消息数目变量*/
    d_uint8 qmsg_com_num = 0;

    /*!< 判断消息队列中是否有消息*/
    if (Queue_Query(&Com_Queue, &qmsg_com_num) == PAR_ERR)
    {
      /*!< 队列出现致命错误*/
      App_Com_Task_Init();
      com_state = COM_IDLE;
      com_last_state = COM_IDLE;
      return;
    }
    /*!< 消息队列中有消息*/
    while (qmsg_com_num > 0)
    {
      com_state = Com_Task_Table[com_last_state].pHandle();
      if (com_state != com_last_state)
      {
        Com_Task_Table[com_last_state].pExit();
        Com_Task_Table[com_state].pEnter();
        com_last_state = com_state;
      }

      /*!< 判断消息队列中是否有消息*/
      if (Queue_Query(&Com_Queue, &qmsg_com_num) == PAR_ERR)
      {
        /*!< 队列出现致命错误*/
        App_Com_Task_Init();
        com_state = COM_IDLE;
        com_last_state = COM_IDLE;
        return;
      }        
    }
}


这一块也没有看出系统执行到这里,跳出去处理其他语句函数啥的。

烦请大家帮我分析一下,如果上位机发送数据过来,程序中断跳转到这两个语句里,是怎么跳出去处理的?
收藏 评论7 发布时间:2019-6-28 10:37

举报

7个回答
七哥 回答时间:2019-6-28 10:55:18
发工程吧,仿真一下比什么都强
jstiger 回答时间:2019-6-28 13:48:55
本帖最后由 jstiger 于 2019-6-28 15:11 编辑
toofree 发表于 2019-6-28 10:55
发工程吧,仿真一下比什么都强

我用printf语句来测试,结果串口没有数据输出到上位机了。去除printf就正常了。不知你说的串口该怎么样仿真呢?
wenyangzeng 回答时间:2019-7-2 09:42:07
App_UART1_Task()就是USART的事件处理函数呀

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

byronsong 回答时间:2019-7-2 10:20:54
应该是这个部分

  1.       com_state = Com_Task_Table[com_last_state].pHandle();
  2.       if (com_state != com_last_state)
  3.       {
  4.         Com_Task_Table[com_last_state].pExit();
  5.         Com_Task_Table[com_state].pEnter();
  6.         com_last_state = com_state;
  7.       }
复制代码

”Com_Task_Table[]“应该是函数指针型数组,是个程序转移表。
七哥 回答时间:2019-7-2 11:43:06
jstiger 发表于 2019-6-28 13:48
我用printf语句来测试,结果串口没有数据输出到上位机了。去除printf就正常了。不知你说的串口该怎么样仿 ...

程序单步执行、或打断点执行,看什么时候串口能输出数据。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

bl2019 回答时间:2019-7-2 15:56:57
对于这种看不懂怎么运行的,我一般是打断点,慢慢执行

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

废鱼 回答时间:2019-7-2 23:20:04
从代码上分析是函数指针,具体操作应该在pHandle中。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版