qq_57550717 2024-04-23 21:20 采纳率: 66.7%
浏览 56
已结题

stm32阿里云飞燕平台数据下发

各位大lao,我用stm32和ESP8266连接阿里云,已经实现了向阿里云发送数据,但是接收一直实现不了,以下是我的代码:
我是用串口2发送数据,串口1接收数据,这是串口1配置代码:

void Uart1_init(u32 bound)
{
      //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
     
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);    //使能USART1,GPIOA时钟
    
    //USART1_TX   GPIOA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
    
    //USART1_RX      GPIOA.10初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
    
    //Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2 ;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器
    
    //USART 初始化设置
    
    USART_InitStructure.USART_BaudRate = bound;//串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    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); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断
    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口空闲中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1

}

这是接收阿里云指令代码:

char MQTT_Head[]="+MQTTSUBRECV";
void USART1_IRQHandler(void)                    //串口1中断服务程序  PA10为输入
{
    int i;
    uint8_t uart1RecvFlag = 0;        //接收完成标志位
    static uint8_t uart1RecvLen = 0;            //接收数据的长度
    extern char MQTT_Receive_Data[176];
 
    if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)  //接收中断
    {
        USART_RX_BUF[uart1RecvLen] = USART1->DR;
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);    
        uart1RecvLen++;
    }
    else if(USART_GetITStatus(USART1,USART_IT_IDLE) ==SET)        //空闲中断
    {
        USART1->SR;
        USART1->DR;    //作用是清除IDLE标志位, 根据规格要求, 清除IDLE是要先读取SR后读DR, 因为中断是IDLE, 所以从DR读出来的是没意思的数据,
                
        for(i=0;i<11;i++)
        {
            if( USART_RX_BUF[i] != MQTT_Head[i])        //接收到的数据不是云平台发来的
            {
                memset(USART_RX_BUF,0x00,sizeof(USART_RX_BUF));
                uart1RecvFlag = 0;            
                break;
            }
            else uart1RecvFlag = 1;                //接收到的数据是云平台发来的
        }
    if(uart1RecvFlag == 1 )            
        {    
            for(i = 0;i < uart1RecvLen;i++)
            {    
                  MQTT_Receive_Data[i] = USART_RX_BUF[i];    //将缓冲区数据传给另一个数组                    
            }        
        }    
    uart1RecvLen = 0;
    }
}

这是截取数据代码(截取我需要的数值):

char MQTT_Receive_Data[176];
char ESP01FStruct_MQTT_Param[6];
void Receive_Deal(void)
{
    u8 ESP01FStruct_MQTT_Param_Value;
    u8 ESP01FStruct_Led_State_flag;
    u8 ESP01FStruct_Led_flag;
    extern u8 key1;
    int i = 0,index;    
  char MQTT_Power_State[]="Switch";//6个
  char *p;      
    p = MQTT_Receive_Data;                    //指针p指向接受数组的第一个元素
    
    for(i=0;i<sizeof(MQTT_Receive_Data);i++)
    {
        if(*(p+i)=='p' && *(p+i+1)=='a' && *(p+i+2) == 'r')
        {
            index = i+10; 
            break;
        }
    }
 
    for(i=0;i<6;i++,index++)
    {
        ESP01FStruct_MQTT_Param[i] = MQTT_Receive_Data[index];
    }
    ESP01FStruct_MQTT_Param_Value = MQTT_Receive_Data[index+2];    
    
    for(i=0;i<6;i++)
    {
        if(ESP01FStruct_MQTT_Param[i] != MQTT_Power_State[i])
        {
            ESP01FStruct_Led_State_flag=0;
            break;
        }
        else
            ESP01FStruct_Led_State_flag=1;
    }

    if(ESP01FStruct_Led_State_flag==1)
    {
        switch (ESP01FStruct_MQTT_Param_Value)
        {
            case 0x30:
            {    
                ESP01FStruct_Led_flag=0; 
                break;
            }
            case 0x31:
            {        
                ESP01FStruct_Led_flag=1;    
                break;
            }                
        }
    }    

    if(ESP01FStruct_Led_State_flag==1 && ESP01FStruct_Led_flag==1)
    {
        BUZZxhb_ON();
        key1 = 1;
    }
    if(ESP01FStruct_Led_State_flag==1 && ESP01FStruct_Led_flag==0)
    {
        BUZZxhb_OFF();
        key1 = 0;
    }
 
}    

不知道哪里错了,能不能麻烦各位大lao帮我指正一下,谢谢!

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2024-04-23 21:27
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    【问题概括】:您遇到的问题是在STM32微控制器上使用ESP8266模块连接阿里云飞燕平台时,已经能够向阿里云发送数据,但是无法接收数据。

    【问题出现原因】:根据您提供的代码,可能的原因包括但不限于:

    1. 串口接收中断配置或处理逻辑存在问题。
    2. 数据匹配和解析逻辑可能存在缺陷,导致无法正确识别和处理接收到的数据。

    【问题解决方案】:为了解决您的问题,我将提供一些建议和代码修改建议:

    1. 确保串口接收中断的配置正确,特别是中断触发条件和中断服务程序(ISR)的实现。
    2. 检查数据匹配和解析逻辑,确保能够正确识别和处理来自阿里云的数据包。

    【提供代码】:以下是对您现有代码的一些修改建议:

    // 假设您的USART_RX_BUF是一个足够大的缓冲区,用于存储接收到的数据
    // 以下是修改后的USART1中断服务程序
    void USART1_IRQHandler(void) {
        if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) { // 接收中断
            // 存储接收到的数据
            USART_RX_BUF[uart1RecvLen] = USART1->DR;
            uart1RecvLen++;
            USART_ClearITPendingBit(USART1, USART_IT_RXNE); // 清除中断标志位
        }
        else if (USART_GetITStatus(USART1, USART_IT_IDLE) == SET) { // 空闲中断
            // 检查是否接收到了完整的数据包
            if (uart1RecvLen >= sizeof(MQTT_Head)) {
                for (int i = 0; i < sizeof(MQTT_Head) - 1; i++) {
                    if (USART_RX_BUF[i] != MQTT_Head[i]) {
                        // 如果数据不匹配,重置接收标志和长度
                        uart1RecvFlag = 0;
                        uart1RecvLen = 0;
                        return;
                    }
                }
                // 如果数据匹配,处理接收到的数据
                uart1RecvFlag = 1;
                // 处理MQTT_Receive_Data数组中的数据
                Receive_Deal();
            }
            // 重置接收长度,准备接收下一条消息
            uart1RecvLen = 0;
        }
    }
    
    // 确保Receive_Deal函数能够正确处理接收到的数据
    void Receive_Deal(void) {
        // 这里应该是您的数据处理逻辑
        // 确保ESP01FStruct_MQTT_Param和MQTT_Receive_Data数组正确填充
        // 并根据接收到的数据执行相应的操作
    }
    

    【示例代码运行方式】:您需要在STM32开发环境中编译并烧录修改后的代码到STM32微控制器上。确保您的硬件连接正确,包括STM32与ESP8266之间的串口连接,以及ESP8266与阿里云的网络连接。

    【示例代码预期运行结果】:当STM32通过ESP8266成功接收到来自阿里云的数据时,Receive_Deal函数将被调用,并且能够正确解析和处理接收到的数据。如果接收到的数据匹配预定义的头部(MQTT_Head),则认为数据有效,并进行进一步处理。

    请注意,这些代码仅作为修改建议,您可能需要根据您的具体硬件配置和软件需求进行调整。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 5月1日
  • 已采纳回答 4月23日
  • 修改了问题 4月23日
  • 创建了问题 4月23日

悬赏问题

  • ¥15 有两个非常“自以为是”烦人的问题急期待大家解决!
  • ¥30 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧,别用大模型回答,大模型的答案没啥用
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error