写这篇纯为自己记录,之前踩过无数坑,这次把所有关键步骤和必踩坑点列清楚,下次再忘直接看这篇就行。
一、平台准备
1.登录 机智云开发者中心(提前注册好账号)
2.智能产品 → + 创建 → 自定义产品

3.填写信息:产品名称随便写,类型选单品 - Wi-Fi ,数据传输方式选变长,功耗正常

4.进入产品 → 功能定义 → 去编辑 → 添加数据点

读写类型:传感器数据选只读,控制开关选可写数据类型:布尔值(开关)、数值(温度 / 湿度等)
二. 下载必备资源
1.下载中心 → 下载 机智云产品调试 APP(手机端)


下载完手机APP后通过虚拟设备绑定即可实现简易通信,如图。

2.产品页面 → MCU 开发 → 选择独立 MCU 方案 → 硬件平台选其他平台 → 下载自动生成的代码包。

3.下载中心 → GAgent → 下载 GAgent for ESP8266(04020034) 固件(ESP8266 专用)。

ESP8266机智云固件烧录这里不做细讲,有需要可以网上找找教程。
三、代码移植(核心步骤)
1. 导入代码
-
解压自动生成的代码包,复制Gizwits 和Utils 两个文件夹到你的工程目录(在工程目录下新建个Gizwits文件夹),如图所示:

-
- Keil 工程 → Manage Project Items → 添加组:
Gizwits - 添加
Gizwits文件夹里所有文件文件
- 魔法棒 → C/C++ → Include Paths → 添加文件夹的路径:
..\Gizwits、..\Utils
2. 关键接口实现(一个都不能少!)
(1)通信串口(和 ESP8266 连接,必须 9600 波特率)及其接收中断修改。
// 以USART2为例,必须开启接收中断 void Usart2_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; 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(USART2, &USART_InitStructure); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_Cmd(USART2, ENABLE); } // 接收中断:必须把数据写入机智云的环形缓冲区 void USART2_IRQHandler(void) { if(USART_GetITStatus(USART2, USART_IT_RXNE)) { uint8_t data = USART_ReceiveData(USART2); gizPutData(&data, 1); // 这行是核心! USART_ClearITPendingBit(USART2, USART_IT_RXNE); } }(2)uartWrite () 函数(在
gizwits_product.c中实现) - Keil 工程 → Manage Project Items → 添加组:
将函数内的for循环替换为如下代码(以USART2为例,按需自行更改)
for(i=0; i<len; i++)
{
USART_SendData(USART2, buf[i]);//STM32 test demo
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
//Serial port to achieve the function, the buf[i] sent to the module
if(i >=2 && buf[i] == 0xFF)
{
//Serial port to achieve the function, the 0x55 sent to the module
USART_SendData(USART2, 0x55);//STM32 test demo
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}
}
需要包含一下#include "stm32f10x.h"头文件,否则会标红报错。
(3)1ms 定时器(协议时基,必须精确)
由于我用的是系统滴答定时器,所以我的代码如下图:(只需要在1ms中断调用gizTimerMs()函数就可以了,使用的时候也要注意包含头文件#include "gizwits_product.h"。

(4)mcuRestart () 函数(在gizwits_product.c中实现)
将图中函数内容改为:
void mcuRestart(void)
{
__set_FAULTMASK(1);
NVIC_SystemReset();
}
(5)printf 重定向(容易踩坑导致卡死)
// 方法1(推荐):直接关闭机智云日志,一劳永逸
// 打开gizwits_config.h,把这个宏改成0
#define GIZWITS_LOG_ENABLE 0
// 方法2:正确重定向printf到你初始化过的串口
int fputc(int ch, FILE *f)
{
// 这里用你实际初始化的串口!比如USART3
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
if(ch == '\n')
{
USART_SendData(USART3, '\r');
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
}
USART_SendData(USART3, (uint8_t)ch);
return ch;
}
四、初始化与主循环
-
初始化顺序(不能乱!)
void Gizwits_Init(void)
{
Usart1_Init();//调试串口
Usart2_Init();//通信串口
userInit();//赋变量初始值
gizwitsInit();//机智云连接初始化
Delay_Ms(500);//延时稳定
gizwitsSetMode(WIFI_AIRLINK_MODE);//设置配网模式 手机广播配网
} -
主循环
int main(void)
{
SystemInit();
// 你的其他初始化:OLED、传感器等
Gizwits_Init();while(1) { gizwitsHandle(¤tDataPoint); // 必须一直调用! userHandle(); // 数据上报 // 其他业务逻辑 // ❌ 不要在这里加超过100ms的延时! }}业务逻辑
五、数据上下发
在userHandle()函数中给currentDataPoint赋值:
void userHandle(void)
{
// 读取传感器数据
float temp = DHT11_Read_Temp();
float humi = DHT11_Read_Humi();
// 赋值给对应的数据点
currentDataPoint.valueTemp = (int32_t)temp;
currentDataPoint.valueHumi = (int32_t)humi;
}
2. 命令接收(下行)
在gizwitsEventProcess()函数中处理 APP 下发的命令:
int8_t gizwitsEventProcess(eventInfo_t *info, uint8_t *gizdata, uint32_t len)
{
dataPoint_t *dataPointPtr = (dataPoint_t *)gizdata;
for(uint8_t i=0; i<info->num; i++)
{
switch(info->event[i])
{
case EVENT_Led1: // 对应你创建的数据点标识名
currentDataPoint.valueLed1 = dataPointPtr->valueLed1;
if(currentDataPoint.valueLed1 == 1)
{
LED1_ON(); // 你的控制代码
}
else
{
LED1_OFF();
}
break;
// 其他数据点同理
}
}
return 0;
}
六、常见问题快速排查
1.gizwitsInit () 运行就崩溃:99% 是 printf 重定向到了未初始化的串口,直接关闭GIZWITS_LOG_ENABLE。
2.ESP8266 通信失败:检查串口波特率是不是 9600,接线是否正确,固件是不是 GAgent。
3.APP 搜不到设备:ESP8266 有没有进入配网模式,手机有没有连 2.4G WiFi(不支持 5G)。
4.数据点不更新:主循环有没有一直调用gizwitsHandle(),userHandle()里有没有正确赋值。
5.配网成功但控制没反应:检查gizwitsEventProcess()里的事件名和数据点标识名是否一致。
七、配网操作
1.手机连接 2.4G WiFi。
2.打开机智云调试 APP → 添加设备 → 一键配网 → 输入 WiFi 密码 →乐鑫→设备端断电→我已完成上述操作→设备点上电→等待配网完成。
3.配网成功后设备会自动出现在 APP 列表里,就可以控制和查看数据了。
