收藏官网首页
查看: 8488|回复: 0

[经验分享] 机友分享|ESP8266+机智云平台实现APP控制舵机旋转

682

主题

741

帖子

3万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
36647
跳转到指定楼层
楼主
 楼主| 发表于 2023-8-9 16:56:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
校园创客福利
本帖最后由 Kara 于 2023-8-9 17:42 编辑

机友分享|esp8266+机智云平台实现APP控制舵机旋转
一、ESP8266模块简介
ESP8266是一款超低功耗的UART-WiFi 透传模块,拥有业内极富竞争力的封装尺寸和超低能耗技术,专为移动设备和物联网应用设计,可将用户的物理设备连接到Wi-Fi 无线网络上,进行互联网或局域网通信,实现联网功能。

1.1 模块特点
  • 支持无线802.11 b/g/n 标准
  • 支持STA/AP/STA+AP三种工作模式
  • 内置TCP/IP协议栈,支持多路TCP Client连接
  • 支持丰富的Socket AT指令
  • 支持UART/GPIO数据通信接口
  • 支持Smart Link 智能联网功能
  • 支持远程固件升级(OTA)
  • 内置32位MCU, 可兼作应用处理器
  • 超低能耗,适合电池供电应用
  • 3.3V 单电源供电

1.2 引脚介绍
ESP8266硬件接口丰富,可支持UART,IIC,PWM,GPIO,ADC等,适用于各种物联网应用场合。



1.3 主要功能和工作模式

*主要功能
  • ESP8266可以实现的主要功能包括:串口透传,PWM 调控,GPIO控制。
  • 串口透传:数据传输,传输的可靠性好,最大的传输速率为:460800bps。
  • PWM 调控:灯光调节,三色LED 调节,电机调速等。
  • GPIO控制:控制开关,继电器等。

*工作模式ESP8266模块支持STA/AP/STA+AP 三种工作模式。
  • STA 模式:ESP8266模块通过路由器连接互联网,手机或电脑通过互联网实现对设备的远程控制。
  • AP 模式:ESP8266模块作为热点,实现手机或电脑直接与模块通信,实现局域网无线控制。
  • STA+AP 模式:两种模式的共存模式,即可以通过互联网控制可实现无缝切换,方便操作。

1.4 调试模块
*硬件接线

注意: 面板板处于通电状态

*发送AT+RST指令
接好线后,将USB转TTL模块接入电脑打开串口助手,发送AT+RST指令。


串口接收到模块返回的信息,调试完成。

二、机智云平台
机智云平台是机智云物联网公司经过多年行业内的耕耘及对物联网行业的深刻理解,而推出的面向个人、企业开发者的一站式智能硬件开发及云服务平台。平台提供了从定义产品、设备端开发调试、应用开发、产测、云端开发、运营管理、数据服务等覆盖智能硬件接入到运营管理全生命周期服务的能力。
机智云平台为开发者提供了自助式智能硬件开发工具与开放的云端服务。通过傻瓜化的自助工具、完善的SDK与API服务能力最大限度降低了物联网硬件开发的技术门槛,降低开发者的研发成本,提升开发者的产品投产速度,帮助开发者进行硬件智能化升级,更好的连接、服务最终消费者。

*文档中心:提供一些开发教程和资料,让快速掌握物联网开发技术变得非常简单。


*开发者中心:创建产品、APP和自动生成代码服务等,提供更高效、更便捷的开发平台服务与交互体验


三、基于机智云平台的物联网开发

3.1 开发流程
  • 在平台开发者界面创建产品和小程序
  • GAgent固件烧入WiFi模组中
  • 平台自动生成MCU方案代码
  • 将自动生成的代码移植到ST标准库(主要完成硬件功能设计、WiFi模块与MCU的通信)

3.2关键词介绍

*GAgent:机智云官方提供的固件,可将其烧录进ESP8266 WiFi模组;烧录后,模组原来的AT指令集失去作用,模组能够接入机智云平台,并自动完成模组与平台间的数据交换。GAgent配网方式有airlink和softap。


*MCU与WIFI模块的通信ESP8266用UART通信,并有应答机制;MCU与WIFI模块的通讯可以用MCU自带的USART(支持UART)资源。

四、实操内容
4.1 GAgent固件的烧写(ESP8266)
烧录的方法有两种,一是用烧录器烧录,二是用USB转TTL模块烧录。由于没有烧录器,下面介绍用USB转TTL烧录的方式。
1)下载GAgent固件包


下载好的固件包的内容,根据参数选择烧录的固件包


2)下载安可信ESP8266资料



3)硬件接线(ESP-01s为例)
接线:

4)打开ESP8266资料中的烧录软件


一直点进去直到找到.exe文件


打开后是这样的图


查看芯片参数(之前调试的时候有)


参数配置


点击start


完成烧录

注意: 烧写失败有可能是线接触不良(Combine包比较大),有时候需重试几次才能烧录成功。

4.2 检查GAgent固件是否烧录成功
1)进入机智云平台随便新建一个产品


随便加个数据点(不然调试助手会检测不到产品)


可以看到左上角有PK和PS


2)下载机智云的串口调试助手


打开串口调试助手


3)将EPS8266模块与usb-TTL连接


注意:ESP其他引脚都接VCC(手册上说悬空也行,但有的芯片必须得全接好才能正常工作)

4)进入模拟MCU、选择串口、SoftAP


点击SoftAp后,串口向模块发送进入SoftAP模式的信息,模块收到后会进行应答。若能接收到模块的信息则说明GAgent烧录成功。

5)打开手机WIFI界面可以看到XPG-GAgent开头的WiFi


4.3 创建产品
根据自己的需求,按照步骤完成产品的创建






4.4 机智云虚拟设备
1)下载中心下载机智云APP


2)开发者中心->虚拟设备->打开APP扫码绑定设备


3)APP上改变舵机角度,云端数据发生相应变化


4.5 MCU自动代码生成+代码移植到标准库(*)

1)自动生成代码服务


下载代码即可


2)自动生成代码说明a. 两个重要的包


自动生成代码中,Gizwits和Utils是我们需要的,一个建立起与机智云的通讯,一个是工具包。

b. 打开MDK-ARM文件夹,打开keil工程文件
可以看到,自动生成的代码是基于Hal库的,我们需要实现自己的功能,并将其移植到标准库中


c. 打开Gizwits中的gizwits_product.c


d. 机智云服务用到的三个外设

可以看到,需要用一个定时器(Timer)和两个串口(USART)


说明:
  • 定时器也可以用TIM1、TIM3,同理串口也不一定要用USART1和USART2
  • USART1用于打印调试信息,这一部分功能可以删去,但相应要修改一些代码

e. 关于USART1在gizwits_product.c大概两百多行的位置,重写了fputc函数



然后再utils/common.h文件中可以看到GIZWITS_LOG(日志函数)就是printf



在自动生成的代码中,很多调试信息的打印都调用了GIZWITS_LOG


当完成USART1的初始化并重写fputc函数后, 将USART1的端口与usb转TTL模块连接后接入电脑,借助串口助手可以打印调试信息到串口助手


重写的方式如上(本质上就是用USART1发送数据)

f. 主要文件和接口




可参考官方文档: 独立MCU方案接入机智云 - Gizwits

3)代码移植 (需要根据需求进行修改)
*串口通信(Serial.c)
  1. #include "STM32f10x.h"
  2. #include "Server.h"
  3. #include "gizwits_protocol.h"
  4. /*
  5. * WIFI模块通信初始化 USART2
  6. */
  7. void Serial_WIFI_Init(uint32_t BoundRate)
  8. {
  9.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  10.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  11.         
  12.         // 配置GPIO
  13.         // Tx
  14.         GPIO_InitTypeDef GPIO_InitStructure;
  15.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
  16.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
  17.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  19.         // Rx
  20.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
  21.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
  22.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  23.         
  24.         // 配置USART
  25.         USART_InitTypeDef USART_InitStructure;
  26.         USART_InitStructure.USART_BaudRate=BoundRate;
  27.         USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
  28.         USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
  29.         USART_InitStructure.USART_Parity=USART_Parity_No;  // 无奇偶校验
  30.         USART_InitStructure.USART_StopBits=USART_StopBits_1; // 一位停止位
  31.         USART_InitStructure.USART_WordLength=USART_WordLength_8b;  // 传输字长
  32.         USART_Init(USART2, &USART_InitStructure);
  33.         
  34.         // 打开USART中断
  35.         USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  // 打开接收寄存器非空中断
  36.         // 配置NVIC
  37.         NVIC_InitTypeDef NVIC_InitStructure;
  38.         NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn;
  39.         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  40.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;  // 抢占优先级
  41.         NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;  // 响应优先级
  42.         NVIC_Init(&NVIC_InitStructure);
  43.         // 启动USART
  44.         USART_Cmd(USART2, ENABLE);
  45. }

  46. void USART2_IRQHandler(void)
  47. {
  48.         uint8_t Data=0;
  49.         if(USART_GetITStatus(USART2, USART_IT_RXNE)!=RESET)
  50.         {
  51.                 Data = USART_ReceiveData(USART2);
  52.                 gizPutData(&Data, 1);  // 解析数据
  53.         }
  54. }

  55. /*
  56. *  调试端口USART1
  57. */
  58. void Serial_DebugInit(void)
  59. {
  60.         GPIO_InitTypeDef GPIO_InitStructure;
  61.         USART_InitTypeDef USART_InitStructure;
  62.         NVIC_InitTypeDef NVIC_InitStructure;
  63.          
  64.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);        
  65.         //TX   PA9
  66.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  67.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  68.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  69.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  70.    
  71.         //RX        PA10
  72.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  73.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  74.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  75.         //Usart1 NVIC 配置
  76.         NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  77.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  78.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
  79.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
  80.         NVIC_Init(&NVIC_InitStructure);        
  81.   
  82.    //USART 初始化设置
  83.         USART_InitStructure.USART_BaudRate = 9600;//串口波特率
  84.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
  85.         USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
  86.         USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
  87.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  88.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收发模式

  89.         USART_Init(USART1, &USART_InitStructure); //初始化串口1
  90.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  91.         USART_Cmd(USART1, ENABLE);                    
  92. }        

  93. void USART1_IRQHandler(void)   
  94. {
  95.         
  96. }
复制代码

*Timer.c
  1. #include "stm32f10x.h"
  2. #include "Serial.h"
  3. #include "gizwits_product.h"

  4. // TIM3
  5. void Timer_TIM3Init(uint16_t PSC, uint16_t CNT)
  6. {
  7.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  8.         
  9.         TIM_InternalClockConfig(TIM3);
  10.         // TimeBase
  11.         TIM_TimeBaseInitTypeDef TimerBaseInitStructure;
  12.         TimerBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  13.         TimerBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
  14.         TimerBaseInitStructure.TIM_Period=CNT;
  15.         TimerBaseInitStructure.TIM_Prescaler=PSC;
  16.         TimerBaseInitStructure.TIM_RepetitionCounter=0;
  17.         TIM_TimeBaseInit(TIM1, &TimerBaseInitStructure);
  18.         TIM_ClearFlag(TIM1, TIM_FLAG_Update);
  19.         // 使能更新中断
  20.         TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
  21.         NVIC_InitTypeDef NVIC_InitStructure;
  22.         NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
  23.         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  24.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;  // 抢占优先级
  25.         NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;  // 响应优先级
  26.         NVIC_Init(&NVIC_InitStructure);
  27.         // 开启TIM
  28.         TIM_Cmd(TIM1, ENABLE);
  29. }

  30. /*
  31. *  TIM3 中断函数
  32. */
  33. void TIM3_IRQHandler(void)
  34. {
  35.         if(TIM_GetITStatus(TIM3, TIM_IT_Update))
  36.         {
  37.                 gizTimerMs();  // 机智云计数
  38.                 // 清除标志位
  39.                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update);        
  40.         }
  41. }
复制代码

*Key.c (用于配置模式)
  1. #include "stm32f10x.h"
  2. #include "delay.h"
  3. #include "Server.h"
  4. #include "gizwits_protocol.h"
  5. // PA1作为按键输入
  6. // 2023年4月18日16:32:06

  7. /*
  8. *  按键初始化函数  下降沿触发 配置为上拉输入
  9. */
  10. void Key_Init(void)
  11. {
  12.         // RCC 使能时钟
  13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  14.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  15.         
  16.         // 配置GPIO
  17.         GPIO_InitTypeDef GPIO_InitStructure;
  18.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  19.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
  20.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  21.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  22.         
  23.         // 配置AFIO
  24.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);  // PA1
  25.         
  26.         // 配置EXTI
  27.         EXTI_InitTypeDef EXTI_InitStructure;
  28.         EXTI_InitStructure.EXTI_Line=EXTI_Line1;
  29.         EXTI_InitStructure.EXTI_LineCmd=ENABLE;
  30.         EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
  31.         EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;  // 下降沿触发
  32.         EXTI_Init(&EXTI_InitStructure);
  33.         
  34.         // 配置NVIC分组 只需配置一次
  35.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  36.         // 配置NVIC
  37.         NVIC_InitTypeDef NVIC_InitStructure;
  38.         NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;
  39.         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  40.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;  // 抢占优先级
  41.         NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;  // 响应优先级
  42.         NVIC_Init(&NVIC_InitStructure);
  43.         
  44. }

  45. /*
  46. *  EXTI 中断函数
  47. */
  48. void EXTI1_IRQHandler(void)
  49. {
  50.         if(EXTI_GetITStatus(EXTI_Line1))
  51.         {
  52.                 // 消抖
  53.                 Delay_ms(40);
  54.                 if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)
  55.                 {        
  56.                         Serve_Angle += 30;
  57.                 }
  58.                 while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0);
  59.                 if(Serve_Angle>180)
  60.                 {
  61.                         Serve_Angle = 0;
  62.                 }
  63.                 Server_SetAngle((float)Serve_Angle);
  64.                 // 清除标志位
  65.                 EXTI_ClearITPendingBit(EXTI_Line1);
  66.         }

  67. }

  68. // 机智云模式配置按钮 AirLink SoftAP Reset 三种模式
  69. void Key_WIFIModeInit(void)
  70. {
  71.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  72.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  73.         
  74.         GPIO_InitTypeDef GPIO_InitStructure;
  75.         // PB10 按下低电平 配置成上拉输入
  76.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  77.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
  78.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  79.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  80.         
  81.         // PB12 PB13 按下高电平 配置成下拉输入
  82.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
  83.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_14;
  84.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  85.         
  86.         // AFIO
  87.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource10);
  88.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);
  89.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
  90.         
  91.         // EXTI
  92.         // PB1 下降沿触发
  93.         EXTI_InitTypeDef EXTI_InitStructure;
  94.         EXTI_InitStructure.EXTI_Line=EXTI_Line10;
  95.         EXTI_InitStructure.EXTI_LineCmd=ENABLE;
  96.         EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
  97.         EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
  98.         EXTI_Init(&EXTI_InitStructure);
  99.         
  100.         // PB12 PB14 上升沿触发
  101.         EXTI_InitStructure.EXTI_Line=EXTI_Line12|EXTI_Line14;
  102.         EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
  103.         EXTI_Init(&EXTI_InitStructure);

  104.         // NVIC
  105.         NVIC_InitTypeDef NVIC_InitStructure;
  106.         NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
  107.         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  108.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;  // 抢占优先级
  109.         NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;  // 响应优先级
  110.         NVIC_Init(&NVIC_InitStructure);
  111. }

  112. /*
  113. *        EXTI通道10-15中断函数 PB10 PB12 PB14 分别对应WIFI模块工作的三种模式
  114. */
  115. void EXTI15_10_IRQHandler(void)
  116. {
  117.         if(EXTI_GetITStatus(EXTI_Line10))
  118.         {
  119.                 // 消抖
  120.                 Delay_ms(40);
  121.                 if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==0)
  122.                 {        
  123.                         gizwitsSetMode(WIFI_AIRLINK_MODE);
  124.                         GIZWITS_LOG("AirLink mode\r\n");
  125.                 }
  126.                 while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==0);
  127.                
  128.                 // clear
  129.                 EXTI_ClearITPendingBit(EXTI_Line10);
  130.         }
  131.         else if(EXTI_GetITStatus(EXTI_Line12))
  132.         {
  133.                 // 消抖
  134.                 Delay_ms(40);
  135.                 if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==1)
  136.                 {        
  137.                         gizwitsSetMode(WIFI_SOFTAP_MODE);
  138.                         GIZWITS_LOG("Soft AP mode\r\n");  
  139.                 }
  140.                 while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==1);
  141.                
  142.                 // clear
  143.                 EXTI_ClearITPendingBit(EXTI_Line12);
  144.         }
  145.         else if(EXTI_GetITStatus(EXTI_Line14))
  146.         {
  147.                 // 消抖
  148.                 Delay_ms(40);
  149.                 if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1)
  150.                 {        
  151.                         gizwitsSetMode(WIFI_RESET_MODE);
  152.                         GIZWITS_LOG("Reset mode\r\n");
  153.                 }
  154.                 while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1);
  155.                 // clear
  156.                 EXTI_ClearITPendingBit(EXTI_Line14);
  157.         }

  158. }
复制代码

*gizwits_product.c (注释掉Hal库的内容, 替换成ST库,完成User Handle部分内容)
  1. /**
  2. ****
  3. * @file         gizwits_product.c
  4. * @brief        Gizwits control protocol processing, and platform-related       hardware initialization
  5. * @author       Gizwits
  6. * @date         2017-07-19
  7. * @version      V03030000
  8. * @copyright    Gizwits
  9. *
  10. * @note         机智云.只为智能硬件而生
  11. *               Gizwits Smart Cloud  for Smart Products
  12. *               链接|增值ֵ|开放|中立|安全|自有|自由|生态
  13. *               www.gizwits.com
  14. *
  15. ****/

  16. #include <stdio.h>
  17. #include <string.h>
  18. // #include "hal_key.h"
  19. #include "gizwits_product.h"
  20. #include "common.h"
  21. #include "LED.h"
  22. #include "Server.h"
  23. #include "AD.h"
  24. static uint32_t timerMsCount;
  25. //static uint32_t timerMsCount;
  26. uint8_t aRxBuffer;

  27. /** User area the current device state structure*/
  28. dataPoint_t currentDataPoint;

  29. //extern TIM_HandleTypeDef htim2;
  30. //extern UART_HandleTypeDef huart1;
  31. //extern UART_HandleTypeDef huart2;

  32. /**@} */
  33. /**@name Gizwits User Interface
  34. * @{
  35. */

  36. /**
  37. * @brief Event handling interface

  38. * Description:

  39. * 1. Users can customize the changes in WiFi module status

  40. * 2. Users can add data points in the function of event processing logic, such as calling the relevant hardware peripherals operating interface

  41. * @param [in] info: event queue
  42. * @param [in] data: protocol data
  43. * @param [in] len: protocol data length
  44. * @return NULL
  45. * @ref gizwits_protocol.h
  46. */
  47. int8_t gizwitsEventProcess(eventInfo_t *info, uint8_t *gizdata, uint32_t len)
  48. {
  49.     uint8_t i = 0;
  50.     dataPoint_t *dataPointPtr = (dataPoint_t *)gizdata;
  51.     moduleStatusInfo_t *wifiData = (moduleStatusInfo_t *)gizdata;
  52.     protocolTime_t *ptime = (protocolTime_t *)gizdata;
  53.    
  54. #if MODULE_TYPE
  55.     gprsInfo_t *gprsInfoData = (gprsInfo_t *)gizdata;
  56. #else
  57.     moduleInfo_t *ptModuleInfo = (moduleInfo_t *)gizdata;
  58. #endif

  59.     if((NULL == info) || (NULL == gizdata))
  60.     {
  61.         return -1;
  62.     }

  63.     for(i=0; i<info->num; i++)
  64.     {
  65.         switch(info->event[i])
  66.         {


  67.         case EVENT_Angle:
  68.             currentDataPoint.valueAngle = dataPointPtr->valueAngle;
  69.             GIZWITS_LOG("Evt:EVENT_Angle %4f\n",currentDataPoint.valueAngle);
  70.             //user handle
  71.                         Serve_Angle=currentDataPoint.valueAngle;
  72.                         Server_SetAngle(currentDataPoint.valueAngle);  // 设置电机角度
  73.             break;


  74.         case WIFI_SOFTAP:
  75.             break;
  76.         case WIFI_AIRLINK:
  77.             break;
  78.         case WIFI_STATION:
  79.             break;
  80.         case WIFI_CON_ROUTER:

  81.             break;
  82.         case WIFI_DISCON_ROUTER:

  83.             break;
  84.         case WIFI_CON_M2M:

  85.             break;
  86.         case WIFI_DISCON_M2M:
  87.             break;
  88.         case WIFI_RSSI:
  89.             GIZWITS_LOG("RSSI %d\n", wifiData->rssi);
  90.             break;
  91.         case TRANSPARENT_DATA:
  92.             GIZWITS_LOG("TRANSPARENT_DATA \n");
  93.             //user handle , Fetch data from [data] , size is [len]
  94.             break;
  95.         case WIFI_NTP:
  96.             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);
  97.             break;
  98.         case MODULE_INFO:
  99.             GIZWITS_LOG("MODULE INFO ...\n");
  100. #if MODULE_TYPE
  101.             GIZWITS_LOG("GPRS MODULE ...\n");
  102.             //Format By gprsInfo_t
  103.             GIZWITS_LOG("moduleType : [%d] \n",gprsInfoData->Type);
  104. #else
  105.             GIZWITS_LOG("WIF MODULE ...\n");
  106.             //Format By moduleInfo_t
  107.             GIZWITS_LOG("moduleType : [%d] \n",ptModuleInfo->moduleType);
  108. #endif
  109.         break;
  110.         default:
  111.             break;
  112.         }
  113.     }

  114.     return 0;
  115. }

  116. /**
  117. * User data acquisition

  118. * 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

  119. * @param none
  120. * @return none
  121. */
  122. void userHandle(void)
  123. {
  124.         currentDataPoint.valueLED = LED_Info();//Add Sensor Data Collection
  125.     currentDataPoint.valueAD_Voltage = AD_Voltage;//Add Sensor Data Collection
  126. }

  127. /**
  128. * Data point initialization function

  129. * In the function to complete the initial user-related data
  130. * @param none
  131. * @return none
  132. * @note The developer can add a data point state initialization value within this function
  133. */
  134. void userInit(void)
  135. {
  136.     memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));
  137.    
  138.     /** Warning !!! DataPoint Variables Init , Must Within The Data Range **/
  139.     /*
  140.     currentDataPoint.valueLED = ;
  141.     currentDataPoint.valueAD_Voltage = ;
  142.     currentDataPoint.valueAngle = ;
  143.     */

  144. }


  145. /**
  146. * @brief Millisecond timing maintenance function, milliseconds increment, overflow to zero

  147. * @param none
  148. * @return none
  149. */
  150. void gizTimerMs(void)
  151. {
  152.     timerMsCount++;
  153. }

  154. /**
  155. * @brief Read millisecond count

  156. * @param none
  157. * @return millisecond count
  158. */
  159. uint32_t gizGetTimerCount(void)
  160. {
  161.     return timerMsCount;
  162. }

  163. /**
  164. * @brief MCU reset function

  165. * @param none
  166. * @return none
  167. */
  168. void mcuRestart(void)
  169. {
  170.     __set_FAULTMASK(1);
  171.     NVIC_SystemReset();
  172. }

  173. /**@} */

  174. #ifdef __GNUC__
  175.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
  176.      set to 'Yes') calls __io_putchar() */
  177.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  178. #else
  179.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  180. #endif /* __GNUC__ */
  181. /**
  182.   * @brief  Retargets the C library printf function to the USART.
  183.   * @param  None
  184.   * @retval None
  185.   */
  186. PUTCHAR_PROTOTYPE
  187. {
  188.   /* Place your implementation of fputc here */
  189.   /* e.g. write a character to the USART1 and Loop until the end of transmission */
  190. //  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
  191.         USART_SendData(USART1, (uint8_t)ch);
  192.         while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);
  193.         return ch;
  194. }

  195. ///**
  196. //  * @brief  Period elapsed callback in non blocking mode
  197. //  * @param  htim : TIM handle
  198. //  * @retval None
  199. //  */
  200. //void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  201. //{
  202. //        if(htim==&htim2)
  203. //        {
  204. //                        keyHandle();
  205. //                        gizTimerMs();
  206. //        }
  207. //}

  208. ///**
  209. //* @brief Timer TIM3 init function

  210. //* @param none
  211. //* @return none
  212. //*/
  213. //void timerInit(void)
  214. //{
  215. //        HAL_TIM_Base_Start_IT(&htim2);
  216. //}

  217. ///**
  218. //  * @brief  This function handles USART IDLE interrupt.
  219. //  */
  220. //void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)  
  221. //{  
  222. //    if(UartHandle->Instance == USART2)  
  223. //    {  
  224. //                                gizPutData((uint8_t *)&aRxBuffer, 1);

  225. //        HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);//开启下一次接收中断  
  226. //    }  
  227. //}  

  228. ///**
  229. //* @brief USART init function

  230. //* Serial communication between WiFi modules and device MCU
  231. //* @param none
  232. //* @return none
  233. //*/
  234. //void uartInit(void)
  235. //{
  236. //        HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);//开启下一次接收中断  
  237. //}

  238. /**
  239. * @brief Serial port write operation, send data to WiFi module
  240. *
  241. * @param buf      : buf address
  242. * @param len      : buf length
  243. *
  244. * @return : Return effective data length;-1,return failure
  245. */
  246. int32_t uartWrite(uint8_t *buf, uint32_t len)
  247. {
  248.         uint8_t crc[1] = {0x55};
  249.     uint32_t i = 0;
  250.         
  251.     if(NULL == buf)
  252.     {
  253.         return -1;
  254.     }

  255.     for(i=0; i<len; i++)
  256.     {
  257. //        HAL_UART_Transmit_IT(&huart2, (uint8_t *)&buf[i], 1);
  258. //                                while (huart2.gState != HAL_UART_STATE_READY);//Loop until the end of transmission

  259. //        if(i >=2 && buf[i] == 0xFF)
  260. //        {
  261. //                                                HAL_UART_Transmit_IT(&huart2, (uint8_t *)&crc, 1);
  262. //                                                while (huart2.gState != HAL_UART_STATE_READY);//Loop until the end of transmission
  263. //        }
  264.                 USART_SendData(USART2, (uint8_t)buf[i]);
  265.                 while(USART_GetFlagStatus(USART2, USART_FLAG_TXE)==RESET);
  266.                 if(i>=2 && buf[i] == 0xFF)
  267.                 {
  268.                         USART_SendData(USART2, crc[0]);
  269.                         while(USART_GetFlagStatus(USART2, USART_FLAG_TXE)==RESET);
  270.                 }
  271.     }

  272. #ifdef PROTOCOL_DEBUG
  273.     GIZWITS_LOG("MCU2WiFi[%4d:%4d]: ", gizGetTimerCount(), len);
  274.     for(i=0; i<len; i++)
  275.     {
  276.         GIZWITS_LOG("%02x ", buf[i]);

  277.         if(i >=2 && buf[i] == 0xFF)
  278.         {
  279.             GIZWITS_LOG("%02x ", 0x55);
  280.         }
  281.     }
  282.     GIZWITS_LOG("\n");
  283. #endif
  284.                
  285.                 return len;
  286. }  
复制代码

*gizwits_protocol.c (注释掉Hal库的代码)main.c
  1. #include "stm32f10x.h"
  2. #include "delay.h"
  3. #include "OLED.h"
  4. #include "key.h"
  5. #include "Server.h"
  6. #include "Timer.h"
  7. #include "Serial.h"
  8. #include "AD.h"
  9. #include "LED.h"
  10. #include "gizwits_protocol.h"
  11. #include "gizwits_product.h"

  12. /*
  13. *  单片机课设
  14. *  2023年4月18日16:06:37
  15. *  需求: 1. 上位机控制舵机旋转的角度(0-180°)
  16. *        2. 每5秒返回一次信息(传给上位机和OLED屏幕)
  17. *        3. 按下按键使舵机角度增加30°(若超过180°则回到0°)
  18. *        4. LED灯闪烁作为系统指示灯
  19. *        5. 光敏传感器 控制蜂鸣器报警
  20. *        6. 加入机智云物联网方案
  21. *  程序设计:
  22. *        1. 硬件: STM32F103c8t6、面包板、舵机、OLED屏幕
  23. *        2. 上位机与单片机的通信用USART1和DMA1(PA9 Tx, PA10 Rx)
  24. *        3. TIM1用来计时
  25. *        4. TIM2_CH1 用来输出PWM信号控制舵机旋转角度  PA0
  26. *                   5. B6、B7、B8、B9接OLED屏幕
  27. *        6. PA1作为按键输入
  28. */

  29. void Gitwits_Init(void)
  30. {
  31.         Timer_TIM3Init(10-1, 7200-1);  // 1ms
  32.         Serial_WIFI_Init(9600);  // 波特率9600
  33.         Serial_DebugInit();  // 串口初始化
  34.         userInit();  // 数据初始化
  35.         gizwitsInit();  // 机智云初始化
  36.         Key_WIFIModeInit();  // 模式选择按键初始化
  37. }

  38. int main(void)
  39. {
  40.         OLED_Init();
  41.         Gitwits_Init();
  42.         Key_Init();
  43.         Server_Init();
  44.         AD_Init();
  45.         LED_Init();
  46.         OLED_ShowString(1, 1, "Angle:");
  47.         OLED_ShowString(2, 1, "AD_Value:");
  48.         OLED_ShowString(3, 1, "Voltage:0.00V");
  49.         
  50.         while(1)
  51.         {
  52.                 gizwitsHandle((dataPoint_t *)¤tDataPoint);  // 机智云协议处理 必须
  53.                 OLED_ShowNum(1, 7, Serve_Angle, 3);
  54.                 OLED_ShowNum(2, 10, AD_Value, 4);
  55.                 AD_Voltage = (float)AD_Value*3.3/4096;
  56.                 OLED_ShowNum(3, 9, AD_Voltage, 1);
  57.                 OLED_ShowNum(3, 11, (uint16_t)(AD_Voltage * 100)% 100, 2);
  58.                 LED_Off();
  59.                 userHandle(); //数据上行 必须  上行的数据可在gizwits_product.c中修改
  60.         }
  61. }
复制代码

4)其他代码 (MCU实现的功能)

*LED.c
  1. #include "stm32f10x.h"
  2. #include "delay.h"

  3. /*
  4. *        初始化LED  PB10  低电平驱动
  5. */
  6. void LED_Init(void)
  7. {
  8.         // RCC使能时钟
  9.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  10.         
  11.         // 配置GPIO
  12.         GPIO_InitTypeDef GPIO_InitStructure;
  13.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  14.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
  15.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  16.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  17.         
  18.         GPIO_SetBits(GPIOB, GPIO_Pin_10);
  19. }

  20. /*
  21. *  LED灭
  22. */
  23. void LED_Off(void)
  24. {
  25.         GPIO_SetBits(GPIOB, GPIO_Pin_10);
  26. }

  27. /*
  28. *  LED亮
  29. */
  30. void LED_On(void)
  31. {
  32.         GPIO_ResetBits(GPIOB, GPIO_Pin_10);

  33. }

  34. uint8_t LED_Info(void)
  35. {
  36.         return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10);
  37. }
  38. #include "stm32f10x.h"
  39. #include "delay.h"

  40. /*
  41. *        初始化LED  PB10  低电平驱动
  42. */
  43. void LED_Init(void)
  44. {
  45.         // RCC使能时钟
  46.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  47.         
  48.         // 配置GPIO
  49.         GPIO_InitTypeDef GPIO_InitStructure;
  50.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  51.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
  52.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  53.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  54.         
  55.         GPIO_SetBits(GPIOB, GPIO_Pin_10);
  56. }

  57. /*
  58. *  LED灭
  59. */
  60. void LED_Off(void)
  61. {
  62.         GPIO_SetBits(GPIOB, GPIO_Pin_10);
  63. }

  64. /*
  65. *  LED亮
  66. */
  67. void LED_On(void)
  68. {
  69.         GPIO_ResetBits(GPIOB, GPIO_Pin_10);

  70. }

  71. uint8_t LED_Info(void)
  72. {
  73.         return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10);
  74. }
复制代码

*Server.c (舵机驱动)
  1. #include "stm32f10x.h"
  2. float Serve_Angle;
  3. // TIM2_CH1 用来输出PWM信号控制舵机旋转角度  PA0
  4. // 频率50Hz
  5. void Server_Init(void)
  6. {
  7.         // RCC使能时钟
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  9.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  10.         
  11.         // 配置GPIO
  12.         GPIO_InitTypeDef GPIO_InitStructure;
  13.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
  14.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
  15.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  16.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  17.         // 选择内部时钟作为TIM2的时钟
  18.         TIM_InternalClockConfig(TIM2);
  19.         
  20.         // 配置时基单元
  21.         TIM_TimeBaseInitTypeDef TimeBase_InitStructure;
  22.         TimeBase_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  23.         TimeBase_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
  24.         TimeBase_InitStructure.TIM_Period=20000-1;   // ARR
  25.         TimeBase_InitStructure.TIM_Prescaler=72-1;
  26.         TimeBase_InitStructure.TIM_RepetitionCounter=0;
  27.         TIM_TimeBaseInit(TIM2, &TimeBase_InitStructure);
  28.         
  29.         // 配置OC单元(输出比较单元 OutPut Compare)  OC1
  30.         TIM_OCInitTypeDef OC_InitStructure;
  31.         TIM_OCStructInit(&OC_InitStructure);
  32.         OC_InitStructure.TIM_OCMode=TIM_OCMode_PWM1;
  33.         OC_InitStructure.TIM_Pulse=0;  // CCR寄存器
  34.         OC_InitStructure.TIM_OCPolarity=TIM_OCPolarity_High; // 设置有效电平
  35.         OC_InitStructure.TIM_OutputState=TIM_OutputState_Enable;
  36.         TIM_OC1Init(TIM2, &OC_InitStructure);
  37.         
  38.         // 开启TIM
  39.         TIM_Cmd(TIM2, ENABLE);
  40. }

  41. /*
  42. *  设置OC1 CCR寄存器的值
  43. */
  44. void Server_Set_Compare1(uint16_t Compare)
  45. {
  46.         TIM_SetCompare1(TIM2, Compare);  
  47. }


  48. /*
  49.         设置舵机角度
  50.         因为舵机需要20ms的波长来驱动 可知频率为50Hz 若ARR设置为 20000-1 则PSC设置为72-1
  51.         又0.5ms~2.5ms对应舵机角度的0~180°
  52.         0.5ms 对应ARR为500  2.5ms 对应ARR为2500
  53.         对应角度的CCR应该设置为(Angle / 180 * 2000 + 500)
  54. */
  55. void Server_SetAngle(float Angle)
  56. {
  57.         Server_Set_Compare1(Angle / 180 * 2000 + 500);
  58. }
复制代码

*AD.c
  1. #include "stm32f10x.h"
  2. #include "MyDMA.h"
  3. #include "LED.h"
  4. uint16_t AD_Value;
  5. float AD_Voltage;
  6. /*
  7. *  初始化ADC
  8. */
  9. void AD_Init(void)
  10. {
  11.         // 初始化DMA通道1运输ADC1的数据
  12.         AD_MyDMA_Init();
  13.         // RCC使能时钟
  14.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  15.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  16.         RCC_ADCCLKConfig(RCC_PCLK2_Div6);  // 12MHz mm
  17.         // 配置GPIO口
  18.         GPIO_InitTypeDef GPIO_InitStructure;
  19.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  20.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  21.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  22.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  23.         // 选择规则通道
  24.         ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_55Cycles5);
  25.         
  26.         // 配置ADC转换器
  27.         ADC_InitTypeDef ADC_InitStructure;
  28.         ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  // 单次转换或者连续转换
  29.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  // 数据对齐模式
  30.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  // ADC模式, 单独还是交叉
  31.         ADC_InitStructure.ADC_NbrOfChannel = 1;  // 扫描的通道数
  32.         ADC_InitStructure.ADC_ScanConvMode = DISABLE;  // 扫描模式或者非扫描模式
  33.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 触发控制
  34.         ADC_Init(ADC1, &ADC_InitStructure);
  35.         
  36.         // 开启DMA转运
  37.         ADC_DMACmd(ADC1, ENABLE);
  38.         
  39.         // 开启模拟看门狗
  40.         ADC_AnalogWatchdogThresholdsConfig(ADC1, 0xFFF, 0x5DC);  // 设置看门狗阈值
  41.         ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_7); // 对通道7设置看门狗
  42.         ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleRegEnable);  // 使能单通道模拟看门狗
  43.         ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE);  // 开启模拟看门狗中断
  44.         
  45.         // 配置NVCI
  46.         NVIC_InitTypeDef NVIC_InitStructure;
  47.         NVIC_InitStructure.NVIC_IRQChannel=ADC1_2_IRQn;
  48.         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  49.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
  50.         NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
  51.         NVIC_Init(&NVIC_InitStructure);
  52.         // 开启ADC功能
  53.         ADC_Cmd(ADC1, ENABLE);
  54.         
  55.         // ADC校准
  56.         ADC_ResetCalibration(ADC1);
  57.         while(ADC_GetResetCalibrationStatus(ADC1) == SET);  // 已初始化为零
  58.         ADC_StartCalibration(ADC1);
  59.         while (ADC_GetCalibrationStatus(ADC1) == SET);
  60.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  61. }

  62. /*
  63. *  ADC中断函数
  64. */
  65. void ADC1_2_IRQHandler(void)
  66. {
  67.         if(ADC_GetITStatus(ADC1, ADC_IT_AWD)==SET)
  68.         {
  69.                 // 开启警报灯
  70.                 LED_On();
  71.                 // 清除中断标志
  72.                 ADC_ClearITPendingBit(ADC1, ADC_IT_AWD);
  73.         }

  74. }
复制代码

*MyDMA.c
  1. #include "stm32f10x.h"
  2. #include "Serial.h"
  3. #include "AD.h"
  4. #define TXBUFFERSIZE 11
  5. #define RXBUFFERSIZE 15

  6. /*
  7. *        ADC DMA初始化
  8. */
  9. void AD_MyDMA_Init(void)
  10. {
  11.         // RCC使能时钟
  12.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  13.         // 配置DMA
  14.         DMA_InitTypeDef DMA_InitStructure;
  15.         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // ADC的数据寄存器
  16.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  17.         // 地址非自增, ADC可以理解为上菜的桌子只有一个
  18.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  
  19.         DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AD_Value;  // 保存的地址
  20.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  21.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  // 这里要自增
  22.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  // 转运方向
  23.         DMA_InitStructure.DMA_BufferSize = 1;
  24.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  // 自动重装
  25.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;         // 硬件触发
  26.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  27.         DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  28.         // 开启DMA
  29.         DMA_Cmd(DMA1_Channel1, ENABLE);  // 通道1
  30. }
复制代码
将移植后的代码下载进单片机中,连接好硬件电路后,即可进入下一步接线示范 (仅供参考,根据自己的实际需求接)


说明:
  • A2、A3为USART的端口,分别接WIFI模块的TX、RX
  • WIFI模块出了TX、RX和GND,其余引脚工作时接高电平(手册解释有些引脚浮空也行,但我这块实测都得接高电平)
  • B10、B12、B14为选择WIFI模块工作模式的三个按键分别对应(RESET、SoftAP、AirLink)
  • A7为光敏传感器模拟信号输入口
  • A0为控制舵机PWM信号输出口
  • A1接按键,控制角度加30°
  • 这里USART1的A9、A10未接线,可接USB转TTL模块将调试信息打印到电脑的串口助手

5)设备连网
a. 准备工作
需要: 机智云APP,两台移动设备(手机,一台用来开热点,热点频率为2.4G)

b. 机智云APP下载

c. 用另外一台设备开启热点 (注意频段为2.4G)


d. 进入机智云连接设备




e. 输入热点密码,下一步


f. 选择乐鑫 (选择模块对应的模组) 继续点直到进入,这时候先别点,先按下B10的按键(SoftAP模式的按键),让模组进入SoftAP工作模式,然后点几蓝色字体



g. 点击XPG-GAgent-7067(漏了一步,在点击XPG前,手机要先连上热点)




注意:
  • 若找不到XPG开头的,则可将MCU与WIFI模组通信的串口的发送口,通过USB转TTL接到电脑上,用串口助手查看发送的信息是否正确(与实操02中的协议一致),若不一致则需进一步进行检查。

  • 还有一种情况,需接受调试串口的信息,看程序是否运行正常


h. 回到机智云调试APP,等待设备连接



若连接失败: 则检查热点质量,检查输入的热点密码是否正确

i. 可以看到设备在线,点进去后




j. 可以通过手机控制舵机的角度



五、APP生成
1)创建→ \rightarrow→移动应用→ \rightarrow→应用名称、应用包名随便填(应用包名最好英文)→ \rightarrow→关联应用,不关联



2)关联应用→ \rightarrow→选择产品 (图标壁纸可以根据喜好,自己上传资源)


3)构建应用→ \rightarrow→应用构建→ \rightarrow→构建测试版



4)构建成功后可以用手机下载


5)添加设备 (过程与在调试APP添加设备类似)

6)界面展示







您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表