赞
踩
ESP8266是一款超低功耗的UART-WiFi 透传模块,拥有业内极富竞争力的封装尺寸和超低能耗技术,专为移动设备和物联网应用设计,可将用户的物理设备连接到Wi-Fi 无线网络上,进行互联网或局域网通信,实现联网功能。
支持无线802.11 b/g/n 标准
支持STA/AP/STA+AP三种工作模式
内置TCP/IP协议栈,支持多路TCP Client连接
支持丰富的Socket AT指令
支持UART/GPIO数据通信接口
支持Smart Link 智能联网功能
支持远程固件升级(OTA)
内置32位MCU, 可兼作应用处理器
超低能耗,适合电池供电应用
3.3V 单电源供电
ESP8266硬件接口丰富,可支持UART,IIC,PWM,GPIO,ADC等,适用于各种物联网应用场合
ESP8266可以实现的主要功能包括:串口透传,PWM 调控,GPIO控制。
串口透传:数据传输,传输的可靠性好,最大的传输速率为:460800bps。
PWM 调控:灯光调节,三色LED 调节,电机调速等。
GPIO控制:控制开关,继电器等。
ESP8266WIFI模块 | USB转TTL模块 | 面包板 |
---|---|---|
TX | RX | None |
RX | TX | None |
GND | GND | GND |
EN | None | VCC |
3V3 | None | VCC |
IO0 | None | VCC |
IO2 | None | VCC |
RST | None | VCC |
注意: 面板板处于通电状态
接好线后,将USB转TTL模块接入电脑打开串口助手,发送AT+RST指令
本小节参考:
ESP8266新手入门调试指导(ESP-01).pdf
ESP8266-01 WiFi模块用户手册V1.0
开发的一些教程和资料
创建产品、APP和自动生成代码服务
开发流程:
官方提供的固件,可将其烧录进ESP8266WIFI模组;烧录后,模组原来的AT指令集失去作用,模组能够接入机智云平台,并自动完成模组与平台间的数据交换
GAgent配网方式
ESP8266用UART通信,并有应答机制;MCU与WIFI模块的通讯可以用MCU自带的USART(支持UART)资源
本小节参考:
烧录的方法有两种,一是用烧录器烧录,而是用USB转TTL模块烧录,由于我没有烧录器,就只介绍用USB转TTL烧录的方式
1.下载GAgent固件包
下载好的固件包的内容,根据参数选择烧录的固件包
安信可ESP8266系列接入机智云方案及问题排查指引 - Gizwits
接线:
ESP-01s | USB转TTL | 面包板 |
---|---|---|
RX | TX | None |
TX | RX | None |
3V3 | VCC | None |
IO0 | None | GND |
GND | GND | GND |
一直点进去直到找到.exe文件
打开后是这样的
查看芯片参数(之前调试的时候有)
参数配置
点击start
完成
本小节参考资料:
(1条消息) 个人项目——STM32接入机智云教程_at指令能连机智云吗_唯恋殊雨的博客-CSDN博客
安信可ESP8266系列接入机智云方案及问题排查指引 - Gizwits
说明: 若问题无法解决 ESP01或ESP01-s系列接线可参考B站大佬的视频,烧录的步骤可参考官网文档和另一个大佬写的博客
注意: 烧写失败有可能是线接触不良(Combine包比较大),有时候需重试几次才能烧录成功!!!
随便加个数据点(不然调试助手会检测不到产品)
ESP-01s | USB转TTL | 面包板 |
---|---|---|
RX | TX | None |
TX | RX | None |
3V3 | VCC | None |
IO0 | None | VCC |
GND | GND | GND |
ESP其他引脚都接VCC(手册上说悬空也行,但有的芯片必须得全接好才能正常工作!!!)
本小节参考:
更多细节参考官方视频
机智云虚拟设备
本小节参考:
更多细节参考官方视频
下载代码即可
自动生成代码中,Gizwits和Utils是我们需要的(一个建立起与机智云的通讯,一个是工具包)
可以看到,需要用一个定时器(Timer)和两个串口(USART)
说明:
定时器也可以用TIM1、TIM3,同理串口也不一定要用USART1和USART2
USART1用于打印调试信息,这一部分功能可以删去,但相应要修改一些代码
关于USART1:
在gizwits_product.c大概两百多行的位置,重写了fputc函数
然后再utils/common.h文件中可以看到GIZWITS_LOG(日志函数)就是printf
在自动生成的代码中,很多调试信息的打印都调用了GIZWITS_LOG
当完成USART1的初始化并重写fputc函数后, 将USART1的端口与usb转TTL模块连接后接入电脑,借助串口助手可以打印调试信息到串口助手
重写的方式如上(本质上就是用USART1发送数据)
文件 | 说明 |
---|---|
Gizwits_product.c | 该文件为产品相关处理函数,如gizEventProcess()平台相关硬件初始化,如串口、定时器等。 |
Gizwits_product.h | 该文件为gizwits_product.c的头文件,存放产品相关宏定义如:HARDWARE_VERSION、SOFTWARE_VERSION |
Gizwits_protocol.c | 该文件为SDK API接口函数定义文件 |
Gizwits_protocol.h | 该文件为gizwits_protocol.c对应头文件,相关API的接口声明均在此文件中。 |
API名称 | API功能 |
---|---|
Void gizwitsInit(void) | gizwits 协议初始化接口。用户调用该接口可以完成 Gizwits 协议相关初始化(包括协议相关定时器、串口的初始化)。 |
Void gizwitsSetMode(unit8_t mode) | 参数mode[in]:仅支持0,1和2,其他数据无效。参数为 0,恢复模组出厂配置接口,调用会清空所有配置参数,恢复到出厂默认配置; 参数为 1 时配置模组进入 SoftAp 模式; 参数为 2 配置模组进入 AirLink 模式。 |
Void gizwitsHandle(dataPoint_t *dataPoint) | 参数 dataPoint[in]:用户设备数据点。该函数中完成了相应协议数据的处理即数据上报的等相关操作。 |
Int8_t gizwitsEventProcess(eventInfo_t *info,uint8_t *data,uint32_t len) | 参数 info[in]:事件队列参数 ; data[in]:数据; 参数 len [in]:数据长度。用户数据处理函数,包括 wifi 状态更新事件和控制事件。a) Wifi 状态更新事件WIFI_开头的事件为 wifi 状态更新事件,data 参数仅在WIFI_RSSI 有效,data 值为 RSSI 值,数据类型为 uint8_t,取值范围 0~7。 b) 控制事件与数据点相关,本版本代码会打印相关事件信息,相关数值也一并打印输出,用户只需要做命令的具体执行即可。 |
可参考官方文档: 独立MCU方案接入机智云 - Gizwits
#include "stm32f10x.h" #include "Server.h" #include "gizwits_protocol.h" /* * WIFI模块通信初始化 USART2 */ void Serial_WIFI_Init(uint32_t BoundRate) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置GPIO // Tx GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // Rx GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置USART USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate=BoundRate; USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; USART_InitStructure.USART_Parity=USART_Parity_No; // 无奇偶校验 USART_InitStructure.USART_StopBits=USART_StopBits_1; // 一位停止位 USART_InitStructure.USART_WordLength=USART_WordLength_8b; // 传输字长 USART_Init(USART2, &USART_InitStructure); // 打开USART中断 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 打开接收寄存器非空中断 // 配置NVIC NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; // 抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; // 响应优先级 NVIC_Init(&NVIC_InitStructure); // 启动USART USART_Cmd(USART2, ENABLE); } void USART2_IRQHandler(void) { uint8_t Data=0; if(USART_GetITStatus(USART2, USART_IT_RXNE)!=RESET) { Data = USART_ReceiveData(USART2); gizPutData(&Data, 1); // 解析数据 } } /* * 调试端口USART1 */ void Serial_DebugInit(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //TX PA9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //RX PA10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); //Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //USART 初始化设置 USART_InitStructure.USART_BaudRate = 9600;//串口波特率 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_Cmd(USART1, ENABLE); } void USART1_IRQHandler(void) { }
#include "stm32f10x.h" #include "Serial.h" #include "gizwits_product.h" // TIM3 void Timer_TIM3Init(uint16_t PSC, uint16_t CNT) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_InternalClockConfig(TIM3); // TimeBase TIM_TimeBaseInitTypeDef TimerBaseInitStructure; TimerBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TimerBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; TimerBaseInitStructure.TIM_Period=CNT; TimerBaseInitStructure.TIM_Prescaler=PSC; TimerBaseInitStructure.TIM_RepetitionCounter=0; TIM_TimeBaseInit(TIM1, &TimerBaseInitStructure); TIM_ClearFlag(TIM1, TIM_FLAG_Update); // 使能更新中断 TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; // 抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=3; // 响应优先级 NVIC_Init(&NVIC_InitStructure); // 开启TIM TIM_Cmd(TIM1, ENABLE); } /* * TIM3 中断函数 */ void TIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3, TIM_IT_Update)) { gizTimerMs(); // 机智云计数 // 清除标志位 TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } }
#include "stm32f10x.h" #include "delay.h" #include "Server.h" #include "gizwits_protocol.h" // PA1作为按键输入 // 2023年4月18日16:32:06 /* * 按键初始化函数 下降沿触发 配置为上拉输入 */ void Key_Init(void) { // RCC 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 配置GPIO GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置AFIO GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1); // PA1 // 配置EXTI EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line=EXTI_Line1; EXTI_InitStructure.EXTI_LineCmd=ENABLE; EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; // 下降沿触发 EXTI_Init(&EXTI_InitStructure); // 配置NVIC分组 只需配置一次 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 配置NVIC NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; // 抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; // 响应优先级 NVIC_Init(&NVIC_InitStructure); } /* * EXTI 中断函数 */ void EXTI1_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line1)) { // 消抖 Delay_ms(40); if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0) { Serve_Angle += 30; } while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0); if(Serve_Angle>180) { Serve_Angle = 0; } Server_SetAngle((float)Serve_Angle); // 清除标志位 EXTI_ClearITPendingBit(EXTI_Line1); } } // 机智云模式配置按钮 AirLink SoftAP Reset 三种模式 void Key_WIFIModeInit(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; // PB10 按下低电平 配置成上拉输入 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // PB12 PB13 按下高电平 配置成下拉输入 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_14; GPIO_Init(GPIOB, &GPIO_InitStructure); // AFIO GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource10); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14); // EXTI // PB1 下降沿触发 EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line=EXTI_Line10; EXTI_InitStructure.EXTI_LineCmd=ENABLE; EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; EXTI_Init(&EXTI_InitStructure); // PB12 PB14 上升沿触发 EXTI_InitStructure.EXTI_Line=EXTI_Line12|EXTI_Line14; EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_Init(&EXTI_InitStructure); // NVIC NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; // 抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; // 响应优先级 NVIC_Init(&NVIC_InitStructure); } /* * EXTI通道10-15中断函数 PB10 PB12 PB14 分别对应WIFI模块工作的三种模式 */ void EXTI15_10_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line10)) { // 消抖 Delay_ms(40); if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==0) { gizwitsSetMode(WIFI_AIRLINK_MODE); GIZWITS_LOG("AirLink mode\r\n"); } while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==0); // clear EXTI_ClearITPendingBit(EXTI_Line10); } else if(EXTI_GetITStatus(EXTI_Line12)) { // 消抖 Delay_ms(40); if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==1) { gizwitsSetMode(WIFI_SOFTAP_MODE); GIZWITS_LOG("Soft AP mode\r\n"); } while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==1); // clear EXTI_ClearITPendingBit(EXTI_Line12); } else if(EXTI_GetITStatus(EXTI_Line14)) { // 消抖 Delay_ms(40); if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1) { gizwitsSetMode(WIFI_RESET_MODE); GIZWITS_LOG("Reset mode\r\n"); } while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1); // clear EXTI_ClearITPendingBit(EXTI_Line14); } }
/** ************************************************************ * @file gizwits_product.c * @brief Gizwits control protocol processing, and platform-related hardware initialization * @author Gizwits * @date 2017-07-19 * @version V03030000 * @copyright Gizwits * * @note 机智云.只为智能硬件而生 * Gizwits Smart Cloud for Smart Products * 链接|增值ֵ|开放|中立|安全|自有|自由|生态 * www.gizwits.com * ***********************************************************/ #include <stdio.h> #include <string.h> // #include "hal_key.h" #include "gizwits_product.h" #include "common.h" #include "LED.h" #include "Server.h" #include "AD.h" static uint32_t timerMsCount; //static uint32_t timerMsCount; uint8_t aRxBuffer; /** User area the current device state structure*/ dataPoint_t currentDataPoint; //extern TIM_HandleTypeDef htim2; //extern UART_HandleTypeDef huart1; //extern UART_HandleTypeDef huart2; /**@} */ /**@name Gizwits User Interface * @{ */ /** * @brief Event handling interface * Description: * 1. Users can customize the changes in WiFi module status * 2. Users can add data points in the function of event processing logic, such as calling the relevant hardware peripherals operating interface * @param [in] info: event queue * @param [in] data: protocol data * @param [in] len: protocol data length * @return NULL * @ref gizwits_protocol.h */ int8_t gizwitsEventProcess(eventInfo_t *info, uint8_t *gizdata, uint32_t len) { uint8_t i = 0; dataPoint_t *dataPointPtr = (dataPoint_t *)gizdata; moduleStatusInfo_t *wifiData = (moduleStatusInfo_t *)gizdata; protocolTime_t *ptime = (protocolTime_t *)gizdata; #if MODULE_TYPE gprsInfo_t *gprsInfoData = (gprsInfo_t *)gizdata; #else moduleInfo_t *ptModuleInfo = (moduleInfo_t *)gizdata; #endif if((NULL == info) || (NULL == gizdata)) { return -1; } for(i=0; i<info->num; i++) { switch(info->event[i]) { case EVENT_Angle: currentDataPoint.valueAngle = dataPointPtr->valueAngle; GIZWITS_LOG("Evt:EVENT_Angle %4f\n",currentDataPoint.valueAngle); //user handle Serve_Angle=currentDataPoint.valueAngle; Server_SetAngle(currentDataPoint.valueAngle); // 设置电机角度 break; case WIFI_SOFTAP: break; case WIFI_AIRLINK: break; case WIFI_STATION: break; case WIFI_CON_ROUTER: break; case WIFI_DISCON_ROUTER: break; case WIFI_CON_M2M: break; case WIFI_DISCON_M2M: break; case WIFI_RSSI: GIZWITS_LOG("RSSI %d\n", wifiData->rssi); break; case TRANSPARENT_DATA: GIZWITS_LOG("TRANSPARENT_DATA \n"); //user handle , Fetch data from [data] , size is [len] break; case WIFI_NTP: GIZWITS_LOG("WIFI_NTP : [%d-%d-%d %02d:%02d:%02d][%d] \n",ptime->year,ptime->month,ptime->day,ptime->hour,ptime->minute,ptime->second,ptime->ntp); break; case MODULE_INFO: GIZWITS_LOG("MODULE INFO ...\n"); #if MODULE_TYPE GIZWITS_LOG("GPRS MODULE ...\n"); //Format By gprsInfo_t GIZWITS_LOG("moduleType : [%d] \n",gprsInfoData->Type); #else GIZWITS_LOG("WIF MODULE ...\n"); //Format By moduleInfo_t GIZWITS_LOG("moduleType : [%d] \n",ptModuleInfo->moduleType); #endif break; default: break; } } return 0; } /** * User data acquisition * Here users need to achieve in addition to data points other than the collection of data collection, can be self-defined acquisition frequency and design data filtering algorithm * @param none * @return none */ void userHandle(void) { currentDataPoint.valueLED = LED_Info();//Add Sensor Data Collection currentDataPoint.valueAD_Voltage = AD_Voltage;//Add Sensor Data Collection } /** * Data point initialization function * In the function to complete the initial user-related data * @param none * @return none * @note The developer can add a data point state initialization value within this function */ void userInit(void) { memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t)); /** Warning !!! DataPoint Variables Init , Must Within The Data Range **/ /* currentDataPoint.valueLED = ; currentDataPoint.valueAD_Voltage = ; currentDataPoint.valueAngle = ; */ } /** * @brief Millisecond timing maintenance function, milliseconds increment, overflow to zero * @param none * @return none */ void gizTimerMs(void) { timerMsCount++; } /** * @brief Read millisecond count * @param none * @return millisecond count */ uint32_t gizGetTimerCount(void) { return timerMsCount; } /** * @brief MCU reset function * @param none * @return none */ void mcuRestart(void) { __set_FAULTMASK(1); NVIC_SystemReset(); } /**@} */ #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */ /** * @brief Retargets the C library printf function to the USART. * @param None * @retval None */ PUTCHAR_PROTOTYPE { /* Place your implementation of fputc here */ /* e.g. write a character to the USART1 and Loop until the end of transmission */ // HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); USART_SendData(USART1, (uint8_t)ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET); return ch; } ///** // * @brief Period elapsed callback in non blocking mode // * @param htim : TIM handle // * @retval None // */ //void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //{ // if(htim==&htim2) // { // keyHandle(); // gizTimerMs(); // } //} ///** //* @brief Timer TIM3 init function //* @param none //* @return none //*/ //void timerInit(void) //{ // HAL_TIM_Base_Start_IT(&htim2); //} ///** // * @brief This function handles USART IDLE interrupt. // */ //void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle) //{ // if(UartHandle->Instance == USART2) // { // gizPutData((uint8_t *)&aRxBuffer, 1); // HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);//开启下一次接收中断 // } //} ///** //* @brief USART init function //* Serial communication between WiFi modules and device MCU //* @param none //* @return none //*/ //void uartInit(void) //{ // HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);//开启下一次接收中断 //} /** * @brief Serial port write operation, send data to WiFi module * * @param buf : buf address * @param len : buf length * * @return : Return effective data length;-1,return failure */ int32_t uartWrite(uint8_t *buf, uint32_t len) { uint8_t crc[1] = {0x55}; uint32_t i = 0; if(NULL == buf) { return -1; } for(i=0; i<len; i++) { // HAL_UART_Transmit_IT(&huart2, (uint8_t *)&buf[i], 1); // while (huart2.gState != HAL_UART_STATE_READY);//Loop until the end of transmission // if(i >=2 && buf[i] == 0xFF) // { // HAL_UART_Transmit_IT(&huart2, (uint8_t *)&crc, 1); // while (huart2.gState != HAL_UART_STATE_READY);//Loop until the end of transmission // } USART_SendData(USART2, (uint8_t)buf[i]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE)==RESET); if(i>=2 && buf[i] == 0xFF) { USART_SendData(USART2, crc[0]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE)==RESET); } } #ifdef PROTOCOL_DEBUG GIZWITS_LOG("MCU2WiFi[%4d:%4d]: ", gizGetTimerCount(), len); for(i=0; i<len; i++) { GIZWITS_LOG("%02x ", buf[i]); if(i >=2 && buf[i] == 0xFF) { GIZWITS_LOG("%02x ", 0x55); } } GIZWITS_LOG("\n"); #endif return len; }
#include "stm32f10x.h" #include "delay.h" #include "OLED.h" #include "key.h" #include "Server.h" #include "Timer.h" #include "Serial.h" #include "AD.h" #include "LED.h" #include "gizwits_protocol.h" #include "gizwits_product.h" /* * 单片机课设 * 2023年4月18日16:06:37 * 需求: 1. 上位机控制舵机旋转的角度(0-180°) * 2. 每5秒返回一次信息(传给上位机和OLED屏幕) * 3. 按下按键使舵机角度增加30°(若超过180°则回到0°) * 4. LED灯闪烁作为系统指示灯 * 5. 光敏传感器 控制蜂鸣器报警 * 6. 加入机智云物联网方案 * 程序设计: * 1. 硬件: STM32F103c8t6、面包板、舵机、OLED屏幕 * 2. 上位机与单片机的通信用USART1和DMA1(PA9 Tx, PA10 Rx) * 3. TIM1用来计时 * 4. TIM2_CH1 用来输出PWM信号控制舵机旋转角度 PA0 * 5. B6、B7、B8、B9接OLED屏幕 * 6. PA1作为按键输入 */ void Gitwits_Init(void) { Timer_TIM3Init(10-1, 7200-1); // 1ms Serial_WIFI_Init(9600); // 波特率9600 Serial_DebugInit(); // 串口初始化 userInit(); // 数据初始化 gizwitsInit(); // 机智云初始化 Key_WIFIModeInit(); // 模式选择按键初始化 } int main(void) { OLED_Init(); Gitwits_Init(); Key_Init(); Server_Init(); AD_Init(); LED_Init(); OLED_ShowString(1, 1, "Angle:"); OLED_ShowString(2, 1, "AD_Value:"); OLED_ShowString(3, 1, "Voltage:0.00V"); while(1) { gizwitsHandle((dataPoint_t *)¤tDataPoint); // 机智云协议处理 必须 OLED_ShowNum(1, 7, Serve_Angle, 3); OLED_ShowNum(2, 10, AD_Value, 4); AD_Voltage = (float)AD_Value*3.3/4096; OLED_ShowNum(3, 9, AD_Voltage, 1); OLED_ShowNum(3, 11, (uint16_t)(AD_Voltage * 100)% 100, 2); LED_Off(); userHandle(); //数据上行 必须 上行的数据可在gizwits_product.c中修改 } }
#include "stm32f10x.h" #include "delay.h" /* * 初始化LED PB10 低电平驱动 */ void LED_Init(void) { // RCC使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 配置GPIO GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB, GPIO_Pin_10); } /* * LED灭 */ void LED_Off(void) { GPIO_SetBits(GPIOB, GPIO_Pin_10); } /* * LED亮 */ void LED_On(void) { GPIO_ResetBits(GPIOB, GPIO_Pin_10); } uint8_t LED_Info(void) { return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10); } #include "stm32f10x.h" #include "delay.h" /* * 初始化LED PB10 低电平驱动 */ void LED_Init(void) { // RCC使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 配置GPIO GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB, GPIO_Pin_10); } /* * LED灭 */ void LED_Off(void) { GPIO_SetBits(GPIOB, GPIO_Pin_10); } /* * LED亮 */ void LED_On(void) { GPIO_ResetBits(GPIOB, GPIO_Pin_10); } uint8_t LED_Info(void) { return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10); }
#include "stm32f10x.h" float Serve_Angle; // TIM2_CH1 用来输出PWM信号控制舵机旋转角度 PA0 // 频率50Hz void Server_Init(void) { // RCC使能时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置GPIO GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 选择内部时钟作为TIM2的时钟 TIM_InternalClockConfig(TIM2); // 配置时基单元 TIM_TimeBaseInitTypeDef TimeBase_InitStructure; TimeBase_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TimeBase_InitStructure.TIM_CounterMode=TIM_CounterMode_Up; TimeBase_InitStructure.TIM_Period=20000-1; // ARR TimeBase_InitStructure.TIM_Prescaler=72-1; TimeBase_InitStructure.TIM_RepetitionCounter=0; TIM_TimeBaseInit(TIM2, &TimeBase_InitStructure); // 配置OC单元(输出比较单元 OutPut Compare) OC1 TIM_OCInitTypeDef OC_InitStructure; TIM_OCStructInit(&OC_InitStructure); OC_InitStructure.TIM_OCMode=TIM_OCMode_PWM1; OC_InitStructure.TIM_Pulse=0; // CCR寄存器 OC_InitStructure.TIM_OCPolarity=TIM_OCPolarity_High; // 设置有效电平 OC_InitStructure.TIM_OutputState=TIM_OutputState_Enable; TIM_OC1Init(TIM2, &OC_InitStructure); // 开启TIM TIM_Cmd(TIM2, ENABLE); } /* * 设置OC1 CCR寄存器的值 */ void Server_Set_Compare1(uint16_t Compare) { TIM_SetCompare1(TIM2, Compare); } /* 设置舵机角度 因为舵机需要20ms的波长来驱动 可知频率为50Hz 若ARR设置为 20000-1 则PSC设置为72-1 又0.5ms~2.5ms对应舵机角度的0~180° 0.5ms 对应ARR为500 2.5ms 对应ARR为2500 对应角度的CCR应该设置为(Angle / 180 * 2000 + 500) */ void Server_SetAngle(float Angle) { Server_Set_Compare1(Angle / 180 * 2000 + 500); }
#include "stm32f10x.h" #include "MyDMA.h" #include "LED.h" uint16_t AD_Value; float AD_Voltage; /* * 初始化ADC */ void AD_Init(void) { // 初始化DMA通道1运输ADC1的数据 AD_MyDMA_Init(); // RCC使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 12MHz mm // 配置GPIO口 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_Init(GPIOA, &GPIO_InitStructure); // 选择规则通道 ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_55Cycles5); // 配置ADC转换器 ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 单次转换或者连续转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据对齐模式 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // ADC模式, 单独还是交叉 ADC_InitStructure.ADC_NbrOfChannel = 1; // 扫描的通道数 ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 扫描模式或者非扫描模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 触发控制 ADC_Init(ADC1, &ADC_InitStructure); // 开启DMA转运 ADC_DMACmd(ADC1, ENABLE); // 开启模拟看门狗 ADC_AnalogWatchdogThresholdsConfig(ADC1, 0xFFF, 0x5DC); // 设置看门狗阈值 ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_7); // 对通道7设置看门狗 ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleRegEnable); // 使能单通道模拟看门狗 ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE); // 开启模拟看门狗中断 // 配置NVCI NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=ADC1_2_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStructure.NVIC_IRQChannelSubPriority=2; NVIC_Init(&NVIC_InitStructure); // 开启ADC功能 ADC_Cmd(ADC1, ENABLE); // ADC校准 ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1) == SET); // 已初始化为零 ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1) == SET); ADC_SoftwareStartConvCmd(ADC1, ENABLE); } /* * ADC中断函数 */ void ADC1_2_IRQHandler(void) { if(ADC_GetITStatus(ADC1, ADC_IT_AWD)==SET) { // 开启警报灯 LED_On(); // 清除中断标志 ADC_ClearITPendingBit(ADC1, ADC_IT_AWD); } }
#include "stm32f10x.h" #include "Serial.h" #include "AD.h" #define TXBUFFERSIZE 11 #define RXBUFFERSIZE 15 /* * ADC DMA初始化 */ void AD_MyDMA_Init(void) { // RCC使能时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 配置DMA DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // ADC的数据寄存器 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 地址非自增, ADC可以理解为上菜的桌子只有一个 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AD_Value; // 保存的地址 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 这里要自增 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 转运方向 DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 自动重装 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 硬件触发 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_Init(DMA1_Channel1, &DMA_InitStructure); // 开启DMA DMA_Cmd(DMA1_Channel1, ENABLE); // 通道1 }
将移植后的代码下载进单片机中,连接好硬件电路后,即可进入下一步
接线示范 (仅供参考,根据自己的实际需求接)
说明:
准备工作
需要: 机智云APP,两台移动设备(手机,一台用来开热点,热点频率为2.4G)
机智云APP下载
输入热点密码,下一步
选择乐鑫 (选择模块对应的模组) 继续点直到进入,这时候先别点,先按下B10的按键(SoftAP模式的按键)让模组进入SoftAP工作模式,然后点几蓝色字体
点击XPG-GAgent-7067(漏了一步,在点击XPG前,手机要先连上热点)
若找不到: XPG开头的,则可将MCU与WIFI模组通信的串口的发送口,通过USB转TTL接到电脑上,用串口助手查看发送的信息是否正确(与实操02中的协议一致),若不一致则需进一步进行检查
还有一种情况,需接受调试串口的信息,看程序是否运行正常,见参考资料【STM32移植机智云】超详细教程#2ESP8266移植机智云教程‘代码移植的最后
这是大佬文章的最后:
回到机智云调试APP,等待设备连接
若连接失败: 则检查热点质量,检查输入的热点密码是否正确
可以看到设备在线,点进去后
可以通过手机控制舵机的角度
本小节参考以下资料
参考文档:
安信可ESP8266系列接入机智云方案及问题排查指引 - Gizwits
参考视频:
参考博客:
【STM32移植机智云】超详细教程#2ESP8266移植机智云教程‘代码移植
创建
→
\rightarrow
→移动应用
→
\rightarrow
→应用名称、应用包名随便填(应用包名最好英文)
→
\rightarrow
→关联应用,不关联
在这里插入图片描述
关联应用 → \rightarrow →选择产品 (图标壁纸可以根据喜好,自己上传资源)
添加设备 (过程与在调试APP添加设备类似)
展示一下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。