51单片机连接阿里云代码
时间: 2023-10-21 15:05:41 浏览: 147
51单片机采集环境数据并使用MQTT协议上传至阿里云.zip
以下是51单片机连接阿里云的示例代码:
```c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <reg52.h>
/**********************阿里云设备信息************************/
//设备三元组
#define PRODUCT_KEY "your_product_key"
#define DEVICE_NAME "your_device_name"
#define DEVICE_SECRET "your_device_secret"
//MQTT服务器地址和端口
#define MQTT_SERVER_HOST "your_mqtt_server_host"
#define MQTT_SERVER_PORT 1883
//发布和订阅的主题
#define SUB_TOPIC "/sys/"DEVICE_NAME"/"PRODUCT_KEY"/thing/service/property/set" //订阅主题
#define PUB_TOPIC "/sys/"DEVICE_NAME"/"PRODUCT_KEY"/thing/event/property/post" //发布主题
//MQTT客户端ID和用户名密码
#define MQTT_CLIENT_ID DEVICE_NAME"@@@12345"
#define MQTT_USERNAME PRODUCT_KEY"&"DEVICE_NAME
#define MQTT_PASSWORD "1234567890ABCDEF"
/**********************阿里云设备信息************************/
#define uchar unsigned char
#define uint unsigned int
sbit LED = P1^0; //控制LED的IO口
//串口通信相关变量
uchar RX_Buffer[32]; //串口接收缓冲区
uchar RX_Count = 0; //串口接收计数器
bit RX_Flag = 0; //串口接收完成标志
//MQTT相关变量
uchar MQTT_Send_Buffer[128]; //MQTT发送缓冲区
uchar MQTT_Rev_Buffer[128]; //MQTT接收缓冲区
uint MQTT_Send_Len = 0; //MQTT发送数据长度
uint MQTT_Rev_Len = 0; //MQTT接收数据长度
bit MQTT_Connect_Flag = 0; //MQTT连接状态标志
//函数声明
void Init_Timer0(void);
void Init_UART(void);
void UART_SendByte(uchar dat);
void UART_SendString(uchar *str);
void MQTT_Connect(void);
void MQTT_Subscribe(void);
void MQTT_Publish(uchar *payload);
void main()
{
EA = 1; //开启总中断
Init_Timer0(); //初始化定时器0
Init_UART(); //初始化串口
while(1)
{
if(RX_Flag) //如果串口接收完成
{
RX_Flag = 0; //清除串口接收完成标志
if(strncmp(RX_Buffer, "LED_ON", 6) == 0) //如果接收到"LED_ON"指令
{
LED = 0; //点亮LED
MQTT_Publish("LED_ON"); //发布LED状态
}
else if(strncmp(RX_Buffer, "LED_OFF", 7) == 0) //如果接收到"LED_OFF"指令
{
LED = 1; //熄灭LED
MQTT_Publish("LED_OFF"); //发布LED状态
}
memset(RX_Buffer, 0, sizeof(RX_Buffer)); //清空串口接收缓冲区
RX_Count = 0; //清空串口接收计数器
}
}
}
//定时器0初始化函数
void Init_Timer0(void)
{
TMOD |= 0x01; //定时器0工作在模式1
TH0 = 0xFC; //定时器初值
TL0 = 0x67;
ET0 = 1; //开启定时器0中断
TR0 = 1; //启动定时器0
}
//定时器0中断函数
void Timer0_ISR() interrupt 1
{
TH0 = 0xFC; //重新赋初值
TL0 = 0x67;
}
//串口初始化函数
void Init_UART(void)
{
TMOD &= 0x0F; //使用定时器1的模式2
TMOD |= 0x20;
SCON = 0x50; //串口工作在模式1
TH1 = 0xFD; //波特率9600
TL1 = 0xFD;
ET1 = 0; //禁用定时器1中断
ES = 1; //开启串口中断
TR1 = 1; //启动定时器1
}
//串口发送一个字节
void UART_SendByte(uchar dat)
{
SBUF = dat;
while(!TI); //等待发送完成
TI = 0; //清除发送完成标志
}
//串口发送一个字符串
void UART_SendString(uchar *str)
{
while(*str)
{
UART_SendByte(*str++);
}
}
//MQTT连接函数
void MQTT_Connect(void)
{
memset(MQTT_Send_Buffer, 0, sizeof(MQTT_Send_Buffer)); //清空发送缓冲区
MQTT_Send_Buffer[0] = 0x10; //MQTT连接请求标志
MQTT_Send_Buffer[1] = 0x1F; //MQTT报文固定头部长度
MQTT_Send_Buffer[2] = 0x00; //MQTT协议名长度
MQTT_Send_Buffer[3] = 0x06;
MQTT_Send_Buffer[4] = 'M';
MQTT_Send_Buffer[5] = 'Q';
MQTT_Send_Buffer[6] = 'T';
MQTT_Send_Buffer[7] = 'T';
MQTT_Send_Buffer[8] = '3';
MQTT_Send_Buffer[9] = '1';
MQTT_Send_Buffer[10] = 0x04; //MQTT协议级别
MQTT_Send_Buffer[11] = 0xC2; //MQTT连接标志
MQTT_Send_Buffer[12] = 0x00; //MQTT心跳周期
MQTT_Send_Buffer[13] = 0x3C;
MQTT_Send_Buffer[14] = 0x00; //MQTT客户端ID长度
MQTT_Send_Buffer[15] = 0x0D;
MQTT_Send_Buffer[16] = 'A'; //MQTT客户端ID
MQTT_Send_Buffer[17] = 'L';
MQTT_Send_Buffer[18] = 'I';
MQTT_Send_Buffer[19] = '_';
MQTT_Send_Buffer[20] = 'M';
MQTT_Send_Buffer[21] = 'Q';
MQTT_Send_Buffer[22] = 'T';
MQTT_Send_Buffer[23] = 'T';
MQTT_Send_Buffer[24] = '_';
MQTT_Send_Buffer[25] = 'E';
MQTT_Send_Buffer[26] = 'M';
MQTT_Send_Buffer[27] = 'B';
MQTT_Send_Buffer[28] = 'E';
MQTT_Send_Buffer[29] = 'D';
MQTT_Send_Buffer[30] = 0xC0; //MQTT遗嘱标志
MQTT_Send_Buffer[31] = 0x00; //MQTT遗嘱QoS
MQTT_Send_Buffer[32] = 0x00; //MQTT遗嘱主题长度
MQTT_Send_Buffer[33] = 0x00;
MQTT_Send_Buffer[34] = 0x00; //MQTT遗嘱消息长度
MQTT_Send_Buffer[35] = 0x00;
MQTT_Send_Len = 36; //MQTT连接请求长度
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+TCLOSE\r\n"); //关闭TCP连接
delay_ms(1000);
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+CGATT?\r\n"); //查询GPRS网络状态
delay_ms(1000);
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+NETOPEN\r\n"); //打开GPRS网络
delay_ms(5000);
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+IPSTATUS\r\n"); //查询IP地址
delay_ms(1000);
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+MQTTDISC\r\n"); //断开MQTT连接
delay_ms(1000);
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+MQTTCONN?\r\n"); //查询MQTT连接状态
delay_ms(1000);
memset(MQTT_Rev_Buffer, 0, sizeof(MQTT_Rev_Buffer)); //清空接收缓冲区
MQTT_Rev_Len = 0; //清空接收数据长度
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+MQTTCONN="); //连接MQTT服务器
UART_SendString("\"tcp://");
UART_SendString(MQTT_SERVER_HOST);
UART_SendByte(':');
UART_SendByte(MQTT_SERVER_PORT/256);
UART_SendByte(MQTT_SERVER_PORT%256);
UART_SendString("\",\"");
UART_SendString(MQTT_CLIENT_ID);
UART_SendString("\",\"");
UART_SendString(MQTT_USERNAME);
UART_SendString("\",\"");
UART_SendString(MQTT_PASSWORD);
UART_SendString("\"\r\n");
delay_ms(5000);
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+MQTTCONN?\r\n"); //查询MQTT连接状态
delay_ms(1000);
if(strstr(MQTT_Rev_Buffer, "CONNECTED") != NULL) //如果连接成功
{
MQTT_Connect_Flag = 1; //设置连接状态标志
MQTT_Subscribe(); //订阅主题
}
else
{
MQTT_Connect_Flag = 0; //连接失败,清除连接状态标志
}
}
//MQTT订阅函数
void MQTT_Subscribe(void)
{
memset(MQTT_Send_Buffer, 0, sizeof(MQTT_Send_Buffer)); //清空发送缓冲区
MQTT_Send_Buffer[0] = 0x82; //MQTT订阅请求标志
MQTT_Send_Buffer[1] = 0x0C; //MQTT报文固定头部长度
MQTT_Send_Buffer[2] = 0x00; //MQTT报文标识符高位
MQTT_Send_Buffer[3] = 0x01; //MQTT报文标识符低位
MQTT_Send_Buffer[4] = 0x00; //MQTT主题长度高位
MQTT_Send_Buffer[5] = strlen(SUB_TOPIC); //MQTT主题长度低位
memcpy(&MQTT_Send_Buffer[6], SUB_TOPIC, strlen(SUB_TOPIC)); //MQTT主题
MQTT_Send_Buffer[6+strlen(SUB_TOPIC)] = 0x00; //MQTT订阅QoS
MQTT_Send_Len = 7+strlen(SUB_TOPIC); //MQTT订阅请求长度
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+MQTTSUB="); //订阅主题
UART_SendByte(MQTT_Send_Len/256);
UART_SendByte(MQTT_Send_Len%256);
UART_SendByte(0x01); //MQTT订阅请求标志
UART_SendString("\r\n");
for(uint i=0; i<MQTT_Send_Len; i++)
{
UART_SendByte(MQTT_Send_Buffer[i]); //发送MQTT订阅请求
}
delay_ms(1000);
}
//MQTT发布函数
void MQTT_Publish(uchar *payload)
{
if(!MQTT_Connect_Flag) //如果MQTT未连接
{
return; //退出函数
}
memset(MQTT_Send_Buffer, 0, sizeof(MQTT_Send_Buffer)); //清空发送缓冲区
MQTT_Send_Buffer[0] = 0x30; //MQTT发布请求标志
MQTT_Send_Buffer[1] = strlen(PUB_TOPIC)+strlen(payload)+2; //MQTT报文固定头部长度+主题长度+消息长度
MQTT_Send_Buffer[2] = 0x00; //MQTT主题长度高位
MQTT_Send_Buffer[3] = strlen(PUB_TOPIC); //MQTT主题长度低位
memcpy(&MQTT_Send_Buffer[4], PUB_TOPIC, strlen(PUB_TOPIC)); //MQTT主题
MQTT_Send_Buffer[4+strlen(PUB_TOPIC)] = 0x00; //MQTT报文标识符高位
MQTT_Send_Buffer[5+strlen(PUB_TOPIC)] = 0x01; //MQTT报文标识符低位
memcpy(&MQTT_Send_Buffer[6+strlen(PUB_TOPIC)], payload, strlen(payload)); //MQTT消息
MQTT_Send_Len = 6+strlen(PUB_TOPIC)+strlen(payload); //MQTT发布请求长度
UART_SendByte(0x1A); //发送AT指令
UART_SendString("AT+MQTTPUB="); //发布主题
UART_SendByte(MQTT_Send_Len/256);
UART_SendByte(MQTT_Send_Len%256);
UART_SendByte(0x01); //MQTT发布请求标志
UART_SendString("\r\n");
for(uint i=0; i<MQTT_Send_Len; i++)
{
UART_SendByte(MQTT_Send_Buffer[i]); //发送MQTT发布请求
}
delay_ms(1000);
}
//串口中断函数
void UART_ISR() interrupt 4
{
if(RI) //接收到一个字节
{
RI = 0; //清除接收标志
RX_Buffer[RX_Count++] = SBUF; //保存接收到的字节
if(RX_Count == sizeof(RX_Buffer)) //如果接收缓冲区已满
{
RX_Count = 0; //清空计数器
}
if(SBUF == '\n') //如果接收到回车符
{
RX_Flag = 1; //设置接收完成标志
}
}
}
//延时函数
void delay_ms(uint ms)
{
uint i, j;
for(i=0; i<ms; i++)
{
for(j=0; j<110; j++);
}
}
```
注意,以上代码仅为示例代码,需要根据自己的情况进行修改。在使用该代码之前,需要先在阿里云控制台创建设备并获取设备三元组,然后将相应的信息填写到代码中。同时,还需要在阿里云控制台配置相应的规则引擎和数据流转等功能,才能实现设备与云端的数据通信。
阅读全文