MQTT 移植STM32+GPRS(串口透传)(四)

版权声明:欢迎大家吐槽! https://blog.csdn.net/qq_20251069/article/details/63735625
在完成相应的初始化和参数设置后主函数中while(1)执行等待读消息,timer3定时器中断中发送采集到的传感器数值,timer4定时器中断中发送ping报文。接着上一篇继续,首先说移植需要的部分
##开发环境:
stm32f103 + esp6288(固件中支持自动连接服务器) 裸机开发

##步骤
发布/接收消息,我们是通过串口函数实现,因此发布时需要修改transport.c中的int transport_sendPacketBuffer(unsigned char* buf, int buflen)函数(因为没有使用到socket,所以可以去掉这个形参),需要串口函数支持发送字符串。

具体代码如下

    void USART2_Putc(unsigned char c)
    {
        while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET );
        USART_SendData(USART2, c);
        while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET );
    }
    //串口2 发送字符串 
    void usart2_send_nbyte(unsigned char *str, int len)
    {
        int i;
        for(i = 0; i < len; i++)
        {
            USART2_Putc(*str++);
        }
    }

接口函数部分具体修改为:

    int transport_sendPacketBuffer(unsigned char* buf, int buflen)
    {
        int rc = 0;
        usart2_send_nbyte(buf, buflen);
        //printf("Debug %s\r\n",buf);
        return rc;
    }

同样接收部分需要修改transport.c中的int transport_getdata(unsigned char* buf, int count),因为源码中提供的是recv()系统函数调用,经过反复修改该部分函数修改。需要有一个带缓存区的中断接收FIFO。

具体修改为:

    int transport_getdata(unsigned char* buf, int count)
    {
        memcpy(buf, (void*)&USART2_RX_BUF[read_buf_len], count);//(void*)强转why?
        read_buf_len += count;
        return count;
    }
其中串口接收中断如下,每次收到一个字节串口串口接收中断中,会将定时器的计数值重置为0,并使能定时器。(不重新使能,只是重置计数值,测试并没有什么效果)

    #define USART_REC_LEN              200      //定义最大接收字节数 200
    volatile u8 USART2_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
    extern volatile u16 rx_buf_len;               //串口2 接收FIFO计数值
    
    void USART2_IRQHandler(void)
    {   
          if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
          {   
            TIM_Cmd(TIM2, DISABLE);
            USART_ClearITPendingBit(USART2,USART_IT_RXNE); 
            USART2_RX_BUF[rx_buf_len] = USART_ReceiveData(USART2);
            rx_buf_len++; //串口2接收FIFO计数值加1
            TIM_SetCounter(TIM2, 0);//定时器计数清零
    
            TIM_Cmd(TIM2, ENABLE);                           // 使能TIM2. 先开定时器,再开中断
            TIM_ClearFlag(TIM2,TIM_FLAG_Update);              //清除标志位。定时器一打开便产生更新事件,若不清除,将会进入中断
            TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);      //打开TIM2更新中断  
          }
    }
定时器2的目的是:做超时检测(一段时间内没有接收到数据再次发来,既可以认为是此条消息发送完成,时间设定为2个数据接收的时间),定时器采用向上自增模式计数

其中定时器中断处理函数如下

    extern volatile u16 USART2_RX_OK_FLAG;               //接收完成标志
 
    //实现功能:超时表明接收结束 改接收完成标志位 关闭定时器。
    volatile int TIM2_count = 0;
    void TIM2_IRQHandler(void)   //TIM2中断
    {
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
        {
            TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update);//TIM_FLAG_Update  //清除TIMx的中断待处理位:TIM 中断源 
            USART2_RX_OK_FLAG = 1;
            TIM_ITConfig(  //使能或者失能指定的TIM中断
            TIM2, //TIM2
            TIM_IT_Update,
            DISABLE  //失能
            );
            TIM_Cmd(TIM2, DISABLE);
        }
    }
完成以上的步骤移植基本完成,下一篇中就详细介绍具体移植例子

猜你喜欢

转载自blog.csdn.net/qq_20251069/article/details/63735625