一些命令:

F7 -- 编译

F8 -- 烧录

初识STM32

结构信息

首先,我们需要知道,计算机有:

  • CISC(复杂指令集)

  • RISC(精简指令集)

    这两种指令集架构,电脑多使用的X86架构使用的是复杂指令集【Intel、AMD公司】

    而手机、平板多使用的ARM架构使用的是精简指令集【华为、苹果、ST】

    而STM32就是ST公司基于ARM架构生产的单片机

STM32 就可以简单解释为:基于ARM架构的单片机

ARM架构优点:相比较更古老的51等单片机的架构,拥有 更低的功耗、更低的成本、更高的性能、且支持16/32位双指令集

内核分类:Cortex-A【重在性能】、Cortex-R【重在实时】、Cortex-M【重在低功耗】

STM32的内核就是Cortex-M【M3/M4/M7】

STM32:ST + M【MCU/MPU】+ 32位

MCU是单片机方向,MPU是Linux方向

本次使用的型号为:STM32F103ZET6【内核:Cortex-M3】

最小系统

最小系统即:保证MCU正常工作的最小电路组成单元

STM32也预留了一些引脚专门用于构建起这些电路单元

STM32F1系统架构

本单片机所采用的 Cortex-M3芯片及调试系统 是由ARM公司设计

而其他部分(外设、存储器、时钟和复位、I/O)则由其他芯片制造商(ST公司、APM公司等)设计开发

时钟系统

时钟参考图

先在此附带一张STM32F103的时钟图:

各时钟的区别

FCLK是提供给ARM的时钟。 HCLK 是提供给用于 ARM,存储器控制器,中断控制器,LCD 控制器,DMA 和 USB 主机模块的 AHB总线的时钟。 PCLK 是提供给用于外设如WDT,IIS,I2C,PWM 定时器,MMC/SD 接口,ADC,UART,GPIO,RTC 和SPI的 APB 总线的时钟。

  • 稳定性:外部振荡器是更加稳定的【精度更高】,所以我们一般均首选HSE、LSE

  • 功能性:HSE、HSI能够作为系统时钟,但优先选择HSE;

    并且经过分频之后,能够作为 AHB的时钟 和 APB的时钟【不同APB就对应地接到不同的外设】

  • 能否作为内部时钟【内核时钟】:HSE、HSI能够通过一系列选择、分频做到

  • 能够作为外设时钟:外设指的是在图中的存储器、DMA、ADC等

MCO

STM32对外部输出时钟信号的端口

在此处,由 PA8 引脚复用后得到该功能,时钟信号可以来源于图中的四个信号源

时钟系统简要分析

先看上图是很难理解的,我们先来分析如下STM32F103时钟树的简图:

高速部分
  • HSE:高速外部振荡器,外部接入,即:外部晶振实现的

  • HSI:高速内部振荡器,内部接入

  • PLL:锁相环

  • SYSCLK:系统时钟

  • AHB:高速高性能总线

  • HCLK:AHB的时钟

  • APB:高速外设总线

低速部分
  • LSI:内部低速振荡器,内部接入

  • LSE:外部低速振荡器,外部接入,即:外部晶振实现的

  • IWDG:独立看门狗

  • RTC:实时时钟外设(计时器)

HAL库驱动程序

见上图,在此不深究

STM32CubeMX时钟树图

实际运用中,此图最重要,通过看懂该图就可以实现通过 STM32CubeMx 视图界面对MCU时钟进行配置

系统结构

存储器划分

总体划分

功能划分

每一个Block的 具体功能和地址范围 参考开发板资料

STM32CubeIDE/STM32CubeMX使用

介绍

ST公司推出的代码编辑器STM32CubeIDE,集成了STM32CubeMx工具,含有视图操作界面,能更好地对指定的MCU进行操作。

①为什么不选择直接使用Keil?

因为使用ST公司推出的视图操作工具STM32CubeMx可以很方便地对MCU的GPIO、时钟等进行配置。

②如何才能MCU进行操作?

可以通过下载STM32CubeMx工具先对MCU进行操作之后,导出文件,再在Keil中进行代码编写,但是也可以直接使用STM32CubeIDE就能直接一站式服务全部解决。

③为什么需要STM32CubeMx工具来生成代码之后再来进行代码编写?

STM32单片机相比起51单片机,内部结构复杂很多,因此直接对底层寄存器编码,相对复杂,这个需要我们了解芯片手册,对于复杂项目,这些操作可能需要反复编写,因此出现了标准库的方式,对寄存器操作进行了封装,操作相对简单。随着项目复杂度提升,又出现了封装更厉害的一种库HAL,而这个需要借助STM32CubeMx工具来生成代码。

常用快捷键

快捷键

快捷键说明

Ctrl+/

注释行/取消注释行

Ctrl+D

删除行

Ctrl+Shift+F

格式化代码

Alt+/

代码补全

Alt+←/→

前一个/后一个页面

F3

跳转到声明处

Ctrl+F

文件内内搜索

Ctrl+H

项目内搜索

F11

启动调试

F5

单步跳入(调试时)

F6

单步跳过(调试时)

F7

单步返回(调试时)

F8

继续运行(调试时)

项目结构

GCC环境下STM32 的启动除了需要 startup_xxxx.s 文件,还需要上述的链接文件: .ld 后缀文件

烧录过程

Release与Debug区别:
1. 在开发阶段为了减少编译优化造成的一系列问题, 我们往往将编译器优化等级设置为最低. 正式发布版一般来说会将优化等级进行提升.即Debug中低优化, Release中高优化.
2. 在嵌入式开发过程中我们还需要进行大量的硬件测试, 算法验证等. 有些测试并不需要包含在正式的发布程序中. 即Debug中需要包含测试程序, Release中不需要.
3. 再者有时中间会临时制作一版用于客户现场测试等等, 这时候相当于我们需要维护的版本已经不止一个. 即Debug/Release/Release_R1/_R2/_R3...

生成项目文件

stm6

生成给芯片烧录用的文件【Release版本: 项目文件夹 > Release文件夹 > 项目名.elf

默认情况下,通过STM32CubeIDE编译后生成的是elf文件

当然,也可以设置同时也生成hex文件

烧录文件到芯片

下载接口选择

JTAG接口:支持仿真调试、下载,占用I/O口过多【使用的DAP调试器默认就使用10pin来连接JTAG接口】

SWD接口:支持仿真调试、下载,推荐【只用练四根线】

串口接口:不支持调试,仅支持下载【USART1支持下载;USART2不支持下载,仅支持通信】

接口调试原理

对于STM32来说:

① 复位之后的 默认模式 选择的是 JATG调试接口模式,如果不想每次默认都是如此可以通过更改对应引 脚的连接情况来改变。

②STM32引脚类型有:电源引脚、晶振引脚、复位引脚、下载引脚、BOOT引脚、GPIO引脚,其中 下载引脚 就是上述我们所讨论的 JTAG 或 SWD 所对应的引脚模式

烧录 or Debug

烧录

Debug

ATK-XISP

DAP + MDK-ARM

(也可用ST官方的工具 STM32CubeProgrammer进行烧录 )

功能设计

整个模块中各硬件之间所使用的通信协议:

  • 与TFTLCD显示模块:USART协议

  • 与ESP8266通信模块:IIC协议

控制模块

控制方式分为三种:远程app控制、红外遥控控制、按键控制

其中前两种控制方式占主导,能提供所有功能的控制,按键控制仅用于开关机、reset等系统级功能

大致通信逻辑图如下:

远程app控制

使用机智云平台在云端平台上构建起一套功能响应逻辑,在ESP8266上烧写GAgent固件从而建立起固定的通信方式,以返回实体系统端的操作控制请求。

wifi模块采用的配网方式:airlink

烧录GAgent固件与机智云平台进行通信,这里给出两篇文章来给出参考:ESP8266-01S接入机智云物联网平台_esp8266机智云配网-CSDN博客官方串口烧写说明【在此处推荐使用MCU烧写方式(combine固件烧写)】

这个地方也算是一个大坑了,如果第一次经历烧写此芯片,那估计得多倒腾几天了,一般来说是需要购买专门的烧写器的,因为读了ESP8266的使用文档之后就会知道:两种模式的转换需要有一个接口接地的操作才能上电同步,即才能进入烧写模式,不然一直都会处于平常的运行模式,导致烧写失败。

以及一定要记得把IO_0接地。。。。

烧写完成之后可以通过 机智云串口调试助手 模拟MCU来进行验证 该模块和机智云服务器的通信是否OK

如下图所示时,则代表已经配网成功:

如果配网失败,可以参考这篇文章进行检查:使用最新版机智云demo-APP进行配网

之后再在代码中对GAgent模块的通信进行控制,经历:打开AirLink连接模式 -->手机app搜索到设备 --> 连接成功 ,即可开始通过手机app进行控制

并且在机智云网站的后台中能够看得到手机app端的操作日志:

红外控制

使用 红外遥控器集成于开发板上的红外接收器

按键控制

使用 单片机上的物理按键 ,主要用于设备的启动关机及重启

显示模块

主要用于显示展示目前设备的各种状态信息,内容是面向用户端的

LCD显示

注意:LCD在此项目中仅用于显示,不用于触控

用于显示基本信息:晾晒状态(电机状态)、晾晒日志、环境温度、衣物湿度、是否开启托管模式

app显示

用于显示控制信息:晾晒控制(电机正反转)、是否开启托管模式、环境温度、衣物湿度

机械模块

在此项目中,做简化处理,只需要步进电机能有两种状态:正转、反转 即可

准备资料

硬件

主控:STM32F103ZET6

wifi模块:ESP8266

烧写了机智云官方的GAgent固件(而非原厂AT固件)

温湿度传感器:DHT11

已运行例程

光敏传感器

已运行例程

红外遥控

已运行例程

显示模块:2.8寸TFTLCD电阻触摸屏

已运行例程

在此项目中仅作为显示屏幕使用,不作为触摸操作屏幕使用

电机:五线四相步进电机(uln2003驱动)

工程搭建

按照以下模板构建起一个keil工程文件,主要包括:

  • startup:启动文件

  • User:存放HAL库用户配置文件、main.c、stm32f1xx_it.c、以及我们编写的其他应用程序

  • Drivers:存放与硬件相关的驱动层文件

    其中,Drivers/SYSTEM文件夹中内容尤为重要:

    是用来快速构建工程的:
    1,delay文件夹:存放延时相关的驱动代码,支持在os下面使用。
    2,sys文件夹:存放系统相关驱动代码,包括系统时钟初始化,IO口配置,中断管理等三部分内容。
    3,usart文件夹:存放串口相关代码,支持printf,方便调试。
  • Readme:一些工程的说明

参数配置

系统时钟配置

1、使用 STM32CubeMx 配置好各个参数后就可以不用管以下操作了

2、外设时钟使能和失能

关于 系统时钟初始化函数 HAL_RCC_OscConfig()HAL_RCC_ClockConfig()HAL_RCCEx_PeriphCLKConfig() 的调用工作,我们无需在意,因为其实就是STM32CubeMx在视图窗口中根据我们的配置之后就自动完成好了。

而在正点原子官方给出的例程中,则是直接将上述系统时钟初始化函数所做的工作都集中在一个叫做 sys_stm32_clock_init() 的函数中,如果运用正点原子的官方例程进行移植,要注意这一点。

模块核心代码分析

GAgent通信模块

配置处理

有一些配置操作需要完成

  • 配置入网

  • 恢复出厂配置

由该函数int32_t gizwitsSetMode(uint8_t mode)来进行配置

传入参数:mode,支持三种配置模式:

  • WIFI_RESET_MODE:恢复出厂配置

  • WIFI_SOFTAP_MODE:进入softap配置模式

  • WIFI_AIRLINK_MODE:进入airlink配置模式

    【详情见gizwits_protocol.h文件的 枚举变量WIFI_MODE_TYPE_T

    可根据产品的定义实现不同的配置操作,如按键触发进入某特定配置模式

下行处理

完成传感器驱动的开发之后,在Gizwits目录下的gizwits_product.c文件中的gizwitsEventProcess()函数中处理相应事件即可。

轮询事件队列,并每次在switch语句中,根据事件info的类型来指定处理事件的函数

传入参数:eventInfo_t info、uint8_t data,、uint32_t len

  • eventInfo_t:指向事件队列结构体的指针,事件队列结构体包含num、event[ ]

  • data:指向自己在机智云平台定义的数据点结构体 dataPoint_t 的指针

  • len:协议传输的数据长度(不使用)

上行处理

首先仍然是需要先完成传感器驱动开发,然后在Gizwits目录下的gizwits_product.c文件中的userHandle()函数中实现传感器数据的采集,用户只需并将采集到的数值赋值给对应用户区的设备状态结构体数据位即可

注意:userHandle()被while循环调用,执行速度较快,需要针对不同的需求,是可以调整数据点数据的采集周期和接口实现位置的,预防由于传感器数据采集过快引发的不必要的问题。且不建议在userHandle()中调用延时函数来降低执行频率。

故在此处:最好是不在该函数里进行传感器数据的采集,而是在其他位置进行采集

工程

数据定义

gizwits_protocol.h

自定义数据点结构体

/** User Area Device State Structure */
typedef struct {
    bool valueLED0;//可写
    bool valueLED1;//可写
    uint32_t valuedegree;//可写
    bool valuecareMODE;//只读【其实应该是可写的,后期可改,现在只是先做一个壳子】
    uint32_t valuelight;//只读
    uint32_t valuehumidity;//只读
} dataPoint_t;

事件枚举类型

/** Event enumeration */
typedef enum
{
    WIFI_SOFTAP = 0x00,                               ///< WiFi SOFTAP configuration event
    WIFI_AIRLINK,                                     ///< WiFi module AIRLINK configuration event
    WIFI_STATION,                                     ///< WiFi module STATION configuration event
    WIFI_OPEN_BINDING,                                ///< The WiFi module opens the binding event
    WIFI_CLOSE_BINDING,                               ///< The WiFi module closes the binding event
    WIFI_CON_ROUTER,                                  ///< The WiFi module is connected to a routing event
    WIFI_DISCON_ROUTER,                    ///< The WiFi module has been disconnected from the routing event
    WIFI_CON_M2M,                                     ///< The WiFi module has a server M2M event
    WIFI_DISCON_M2M,                    ///< The WiFi module has been disconnected from the server M2M event
    WIFI_OPEN_TESTMODE,                               ///< The WiFi module turns on the test mode event
    WIFI_CLOSE_TESTMODE,                              ///< The WiFi module turns off the test mode event
    WIFI_CON_APP,                                     ///< The WiFi module connects to the APP event
    WIFI_DISCON_APP,                                  ///< The WiFi module disconnects the APP event
    WIFI_RSSI,                                        ///< WiFi module RSSI event
    WIFI_NTP,                                         ///< Network time event
    MODULE_INFO,                                      ///< Module information event
    TRANSPARENT_DATA,                                 ///< Transparency events
    EVENT_LED0, //LED0
    EVENT_LED1, //LED1
    EVENT_degree, //晾衣架展开程度:1/4、1/2、3/4、1, 每1/4电机转动90度
    EVENT_TYPE_MAX             ///< Enumerate the number of members to calculate (user accidentally deleted)
} EVENT_TYPE_T;

工程测试

使用正点原子串口调试助手,对程序进行调试

资源

数量

说明

电源指示灯

1 个

蓝色

电源开关

1 个

控制整个板子供电

LED

2 个

红色(DS0);绿色(DS1);

复位按键

1 个

用于 MCU&LCD 的复位

功能按键

3 个

KEY0、KEY1、KEY_UP(具备唤醒功能)

红外接收头

1 个

用于红外接收,配备红外遥控器

光敏传感器

1 个

用于感应环境光照强度

数字温湿度传感器接口

1 个

支持 DS18B20、DHT11 等数字温湿度传感器

ATK 模块接口

1 个

可以接 NRF24L01 等无线模块

LCD 接口

1 个

支持正点原子 2.8/3.5/4.3/7 寸等多种 TFTLCD 模块

USB 转串口

1 个

用于 USB 转 TTL 串口通信

USB 从机接口

1 个

用于 USB SLAVE(从机)通信

CAN/USB 选择接口

1 个

用于选择 PA11/PA12 做 CAN 还是 USB 通信

JTAG/SWD 调试口

1 个

用于仿真调试、下载代码等

5V 电源输入/输出口

1 组

用于 5V 电源接入/对外提供 5V 电压

引出 IO

110

除 RTC 晶振占用的 2 个 IO 口外,其他 IO 口全引出

一键下载电路

1 个

方便使用串口下载代码

启动模式选择配置接口

1 个

用于设置 STM32 启动模式

托管模式、延时、与云端通信、步进电机、红外控制、按键扫描、光敏传感器、温湿度传感器、蜂鸣器、LED

联网绑定解绑、红外遥控控制、WIFI模块、手机APP控制、托管模式、云端日志