【第一章】:物联网简介(什么是物联网)
【第二章】:物联网十大应用场景
【第三章】:什么是MCU?
【第四章】:MCU的应用范围
【第五章】:咱们要怎么入门MCU开发?
【第六章】:如何使用STM32Cube MX进行STM32的快速开发
【第七章】:ESP8266+MQTT上阿里云物联网平台实践(附源码)php
STM32CubeMX AT指令实现MQTT协议并接入阿里云IOT平台 源码解析
CSDN源代码下载
Github源代码下载html
在用cube配置时钟时,有下面两个选项
BYPASS Clock Source(旁路时钟源)
Crystal/Ceramic Resonator(晶体/陶瓷晶振)
下面来解释一下:
所谓HSE旁路时钟源,是指无需使用外部晶体时所需的芯片内部时钟驱动组件,直接从外界导入时钟信号。犹如芯片内部的驱动组件被旁路了。
外部晶体/陶瓷谐振器(HSE晶体)模式该时钟源是由外部无源晶体与MCU内部时钟驱动电路共同配合造成,有必定的启动时间,精度较高。git
查看原理图github
LED_R——PH10 红灯web
LED_G——PH11 绿灯算法
LED_B——PH12 蓝灯编程
低电平有效,IO口要设置为推挽输出,上拉json
工程配置数组
选择引脚设置为GPIO_Ooutput安全
配置标签 LED_R LED_G LED_B,方便工程直接调用
设置上下拉
#include "stdio.h"
// 重定向printf函数 int fputc(int ch,FILE *f) { uint8_t temp[1]={ch}; HAL_UART_Transmit(&huart2,temp,1,2); return 0; }
#define USER_MAIN_DEBUG #ifdef USER_MAIN_DEBUG #define user_main_printf(format, ...) printf( format "\r\n",##__VA_ARGS__) #define user_main_info(format, ...) printf("【main】info:" format "\r\n",##__VA_ARGS__) #define user_main_debug(format, ...) printf("【main】debug:" format "\r\n",##__VA_ARGS__) #define user_main_error(format, ...) printf("【main】error:" format "\r\n",##__VA_ARGS__) #else #define user_main_printf(format, ...) #define user_main_info(format, ...) #define user_main_debug(format, ...) #define user_main_error(format, ...) #endif
user_main_debug("我是USART2测试代码!\n"); HAL_Delay(1000);
//红灯亮,其它灭 HAL_GPIO_WritePin(LED_R_GPIO_Port,LED_R_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_G_GPIO_Port,LED_G_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED_B_GPIO_Port,LED_B_Pin,GPIO_PIN_SET); HAL_Delay(500); //绿灯亮,其它灭 HAL_GPIO_WritePin(LED_R_GPIO_Port,LED_R_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED_G_GPIO_Port,LED_G_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_B_GPIO_Port,LED_B_Pin,GPIO_PIN_SET); HAL_Delay(500); //蓝灯亮,其它灭 HAL_GPIO_WritePin(LED_R_GPIO_Port,LED_R_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED_G_GPIO_Port,LED_G_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(LED_B_GPIO_Port,LED_B_Pin,GPIO_PIN_RESET); HAL_Delay(500);
图片!!
/****************************** 按键中断测试代码 *****************************/ //KEY1按下动做执行函数 void KEY1_Pressed(void) { user_main_debug("我按下了KEY_1\r\n"); } //KEY2按下动做执行函数 void KEY2_Pressed(void) { user_main_debug("我按下了KEY_2\r\n"); } //按键中断处理函数 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { switch(GPIO_Pin) { case KEY_1_Pin:KEY1_Pressed();break; case KEY_2_Pin:KEY2_Pressed();break; default:break; } }
工程验证成功!!
首先去工程中设置定时器1
从新生成工程,来到tim.c,在/* USER CODE BEGIN 1 */中添加如下代码
//使用定时器1来作us级延时函数,温湿度传感器用,量程0-6553us void TIM1_Delay_us(uint16_t n_us) { __HAL_TIM_SetCounter(&htim1, 0);//htim1 /* 开启定时器1计数 */ __HAL_TIM_ENABLE(&htim1); while(__HAL_TIM_GetCounter(&htim1) < (10 * n_us));//计数频率10MHz,10次即为1us /* Disable the Peripheral */ __HAL_TIM_DISABLE(&htim1); }
void TIM1_Delay_us(uint16_t n_us);
// 自定义us级延时函数测试 static uint16_t tim1_test; //延时1000个1ms for(tim1_test = 0;tim1_test<1000;tim1_test++) { //延时1ms TIM1_Delay_us(1000); } user_main_debug("我是us级延时函数测试代码,1s打印一次!\n");
#include "hal_temp_hum.h"
//KEY1按下动做执行函数 void KEY1_Pressed(void) { user_main_debug("按下KEY_1\r\n"); uint8_t temperature; uint8_t humidity; uint8_t get_times; // 获取温湿度信息并用串口打印,获取十次,直到成功跳出 for(get_times=0;get_times<10;get_times++) { if(!dht11Read(&temperature, &humidity))//Read DHT11 Value { user_main_info("temperature=%d,humidity=%d \n",temperature,humidity); break; } } }
#include "esp8266_at.h"
//此处根据本身的wifi做调整 #define WIFI_NAME "HappyOneDay" #define WIFI_PASSWD "1234567890"
//KEY1按下动做执行函数 void KEY1_Pressed(void) { user_main_debug("我按下了KEY_1\r\n"); /* ESP8266测试代码 */ uint8_t status=0; //初始化 if(ESP8266_Init()) { user_main_info("ESP8266初始化成功!\r\n"); status++; } //链接热点 if(status==1) { if(ESP8266_ConnectAP(WIFI_NAME,WIFI_PASSWD)) { user_main_info("ESP8266链接热点成功!\r\n"); status++; } } }
//开启USART1接收中断 HAL_UART_Receive_IT(&huart1,usart1_rxone,1);
//USART1 ES8266驱动串口接收中断处理函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1) // 判断是由哪一个串口触发的中断 { //将接收到的数据放入接收usart1接收数组 usart1_rxbuf[usart1_rxcounter] = usart1_rxone[0]; usart1_rxcounter++; //接收数量+1 //从新使能串口1接收中断 HAL_UART_Receive_IT(&huart1,usart1_rxone,1); } }
#include "esp8266_mqtt.h"
//此处是阿里云服务器的登录配置 #define MQTT_BROKERADDRESS "a1lAoazdH1w.iot-as-mqtt.cn-shanghai.aliyuncs.com" #define MQTT_CLIENTID "00001|securemode=3,signmethod=hmacsha1|" #define MQTT_USARNAME "BZL01&a1lAoazdH1w" #define MQTT_PASSWD "51A5BB10306E976D6C980F73037F2D9496D2813A" #define MQTT_PUBLISH_TOPIC "/sys/a1lAoazdH1w/BZL01/thing/event/property/post" #define MQTT_SUBSCRIBE_TOPIC "/sys/a1lAoazdH1w/BZL01/thing/service/property/set"
//进入错误模式等待手动重启 void Enter_ErrorMode(uint8_t mode) { HAL_GPIO_WritePin(LED_G_GPIO_Port,LED_G_Pin,GPIO_PIN_SET); while(1) { switch(mode){ case 0:user_main_error("ESP8266初始化失败!\r\n");break; case 1:user_main_error("ESP8266链接热点失败!\r\n");break; case 2:user_main_error("ESP8266链接阿里云服务器失败!\r\n");break; case 3:user_main_error("ESP8266阿里云MQTT登录失败!\r\n");break; case 4:user_main_error("ESP8266阿里云MQTT订阅主题失败!\r\n");break; default:user_main_info("Nothing\r\n");break; } user_main_info("请重启开发板"); //HAL_GPIO_TogglePin(LED_R_GPIO_Port,LED_R_Pin); HAL_Delay(200); } }
/****************************** 按键中断测试代码 *****************************/ //KEY1按下动做执行函数 void KEY1_Pressed(void) { user_main_debug("我按下了KEY_1\r\n"); /* DHT11温湿度传感器测试 */ // uint8_t temperature; // uint8_t humidity; // uint8_t get_times; // // 获取温湿度信息并用串口打印,获取十次,直到成功跳出 // for(get_times=0;get_times<10;get_times++) // { // if(!dht11Read(&temperature, &humidity))//Read DHT11 Value // { // user_main_info("temperature=%d,humidity=%d \n",temperature,humidity); // break; // } // } /* ESP8266&MQTT测试代码 */ uint8_t status=0; //初始化 if(ESP8266_Init()) { user_main_info("ESP8266初始化成功!\r\n"); status++; } else Enter_ErrorMode(0); //链接热点 if(status==1) { if(ESP8266_ConnectAP(WIFI_NAME,WIFI_PASSWD)) { user_main_info("ESP8266链接热点成功!\r\n"); status++; } else Enter_ErrorMode(1); } //链接阿里云IOT服务器 if(status==2) { if(ESP8266_ConnectServer("TCP",MQTT_BROKERADDRESS,1883)!=0) { user_main_info("ESP8266链接阿里云服务器成功!\r\n"); status++; } else Enter_ErrorMode(2); } //登录MQTT if(status==3) { if(MQTT_Connect(MQTT_CLIENTID, MQTT_USARNAME, MQTT_PASSWD) != 0) { user_main_info("ESP8266阿里云MQTT登录成功!\r\n"); status++; } else Enter_ErrorMode(3); } //订阅主题 if(status==4) { if(MQTT_SubscribeTopic(MQTT_SUBSCRIBE_TOPIC,0,1) != 0) { user_main_info("ESP8266阿里云MQTT订阅主题成功!\r\n"); } else Enter_ErrorMode(4); } }
MQTT中文网:http://mqtt.p2hp.com/
官网地址:https://help.aliyun.com/product/30520.html
https://help.aliyun.com/document_detail/140507.html?spm=a2c4g.11174283.6.565.3a8b16686rXYnj
https://mqttfx.jensd.de/index.php/download?spm=a2c4g.11186623.2.20.17b67908o3uJ8y
此处对应着官方文档进行讲解
参数 | 说明 |
---|---|
Profile Name | 输入您的自定义名称。 |
Profile Type | 选择为MQTT Broker。 |
Broker Address | 链接域名。格式:${YourProductKey}.iot-as-mqtt.${region}.aliyuncs.com 。其中,${region}需替换为您物联网平台服务所在地域的代码。地域代码,请参见地域和可用区。如:alxxxxxxxxx.iot-as-mqtt.cn-shanghai.aliyuncs.com 。 |
Broker Port | 设置为1883。 |
Client ID | 填写mqttClientId,用于MQTT的底层协议报文。格式固定:${clientId}|securemode=3,signmethod=hmacsha1| 。完整示例:12345|securemode=3,signmethod=hmacsha1| 。其中,${clientId}为设备的ID信息。可取任意值,长度在64字符之内。建议使用设备的MAC地址或SN码。securemode为安全模式,TCP直连模式设置为securemode=3 ,TLS直连为securemode=2 。signmethod为算法类型,支持hmacmd5和hmacsha1。说明 输入Client ID信息后,请勿单击Generate。 |
地域名称 | 所在城市 | Region ID | 可用区数量 |
---|---|---|---|
华北 1 | 青岛 | cn-qingdao | 2 |
华北 2 | 北京 | cn-beijing | 8 |
华北 3 | 张家口 | cn-zhangjiakou | 2 |
华北 5 | 呼和浩特 | cn-huhehaote | 2 |
华东 1 | 杭州 | cn-hangzhou | 8 |
华东 2 | 上海 | cn-shanghai | 6 |
华南 1 | 深圳 | cn-shenzhen | 5 |
华南 2 | 河源 | cn-heyuan | 2 |
西南 1 | 成都 | cn-chengdu | 2 |
Broker Address: a1kvAFB5siA.iot-as-mqtt.cn-shanghai.aliyuncs.com Broker Port: 1883 Client ID: 00001|securemode=3,signmethod=hmacsha1|
参数 | 说明 |
---|---|
User Name | 由设备名DeviceName、符号(&)和产品ProductKey组成。固定格式:${YourDeviceName}&${YourPrductKey} 。完整示例如:device&alxxxxxxxxx 。 |
Password | 密码由参数值拼接加密而成。说明 若是您使用的MQTT.fx版本,在粘贴Password后不显示具体的字符串,只要光标已从输入框的前部移至了后部,则表示粘贴成功,请勿重复粘贴。您能够使用物联网平台提供的生成工具自动生成Password,也能够手动生成Password。单击下载Password生成小工具。解压缩下载包后,双击sign文件,便可使用。使用Password生成小工具的输入参数:productKey:设备所属产品Key。可在控制台设备详情页查看。deviceName:设备名称。可在控制台设备详情页查看。deviceSecret:设备密钥。可在控制台设备详情页查看。timestamp:(可选)时间戳。clientId:设备的ID信息,与Client ID中${clientId}一致。method:选择签名算法类型,与Client ID中signmethod肯定的加密方法一致。手动生成方法以下:拼接参数。提交给服务器的clientId、deviceName、productKey和timestamp(timestamp为非必选参数)参数及参数值依次拼接。本例中,clientId值为12345,deviceName值为device,productKey值为alxxxxxxxxx,拼接结果为:clientId12345deviceNamedeviceproductKeyalxxxxxxxxx 加密。经过Client ID中肯定的加密方法,使用设备deviceSecret,将拼接结果加密。假设设备的deviceSecret值为abc123,加密计算格式为hmacsha1(abc123,clientId12345deviceNamedeviceproductKeyalxxxxxxxxx) |
User Name: TESTDEVICE01&a1kvAFB5siA Password: E18BFBEE7686EC3FBC5EAB10BEB101FD0913CF39
/sys/a1kvAFB5siA/TESTDEVICE01/thing/service/property/set
推送地址:/sys/a1kvAFB5siA/TESTDEVICE01/thing/event/property/post
推送如下json消息
{ "method":"thing.service.property.set", "id":"354062502", "params":{ "temperature":20.0, "humidity":60.0, "switch_led_r":1, "switch_led_g":1, "switch_led_b":0 }, "version":"1.0.0" }
直接看代码
真机演示