会不定时更新,内容根据我的课程记忆重点编辑~
介绍
MCU组成
CPU : 计算和控制(执行程序)
RAM: 运行内存 (处理运行过程中产生的中间变量 ,掉电丢失)
ROM:存储内存 (存储代码 掉电不丢失)
外设:I/O 串口 定时器 ADC DMA SPI 等
重要文件介绍
stm32f10x_it.h
stm32f10x_it.c 这两个文件存放中断服务函数
System_stm32f10x.h
System_stm32f10x.c 这两个文件用于系统时钟配置
系统时钟72mhz
Nop();执行时间是一个系统周期 T= 1/72mS
72个nop函数 t=72/72000000S=1/1000000S=1US
STM32单片机
一共分为GPIOA B C D E F G 7组
每组 有16个管脚 PX0--PX15
一共112个I/O
关于输入输出
高电平 3.3v 1
低电平 0v 0
什么是输入? 什么是输出?
输入:信号从单片机外部输入到单片机内部
输出:信号从单片机内部输出到单片机外部
GPIO
8种工作模式:
输入:
1.浮空输入 :既不接上拉电阻 也不接下拉电阻,空闲状态下,不具备高低电平驱动能力,直接输入的电压进行转换;
2.下拉输入 :接下拉电阻,空闲状态下,增加低电平的驱动能力;
3.上拉输入 :接上拉电阻,空闲状态下,增加高电平的驱动能力;
4 .模拟输入 :采集模拟量,检测模拟电压,数据传给ADC做转换;
输出:
1.通用开漏输出 :只能输出低电平 不能输出高电平,输出高电平 需要外部电路协助
2.通用推挽输出 :既可以输出低电平 又可以输出高电平
3 复用开漏输出 :来自片上外设控制
4 复用推挽输出 :来自片上外设控制-
寄存器
片上外设存储相应配置数据/状态数据/数据值等的空间。
寄存器分类:
配置寄存器:配置模式。
数据寄存器:保存发送的数据和接收的数据。
状态寄存器:保存当前设备工作状态
GPIO寄存器:
中断的概念
对于几乎所有的微控制器,中断都是一种常见的特性。中断一般是由硬件(如外设和外部输入引脚)产生的事件,它会引起程序流偏离正常的流程(如给外设提供服务),转去执行其他的流程。
CPU在正常执行程序的过程中,由于内部/外部事件的触发或程序的预先安排引起CPU暂停当前正在运行的程序,而转去执行中断服务子程序,待中断服务子程序执行完毕后,CPU继续执行原来的程序,这一过程称为中断;
中断的执行过程
1、外设发出中断请求
2、处理器暂停当前执行的任务,保护现场,将当前位置的PC地址压栈;
3、程序跳转到中断服务程序,执行中断服务程序;
4、恢复现场,将栈顶的值回送给PC;
5、跳转到被中断的位置开始执行下一个指令
中断服务函数:
相对于正常子函数,中断服务函数有以下需要注意的地方:
1、中断服务函数不能传入参数;
2、中断服务函数不能有返回值;
3、中断服务函数应该做到短小精悍,快入快出,禁止延时性的过程。
4、不要在中断函数中使用printf函数,会带来重入和性能问题。
中断重入:
就是在一个中断程序执行过程中又被另一个中断打断,转而又去执行另一个中断程序。
中断其实就是异常事件
中断的部分专业术语 – 了解
中断源:引起中断的原因,或者能够发出中断请求信号的来源统称为中断源
中断优先级:中断同时到来,谁先执行。数字越小,优先级越高。
中断响应:中断事件发生,Cortex-M3内核准备执行该事件,即为中断响应。
中断嵌套:可嵌套的内核 -- 中断可以被其他中断打断。(Cortex-M)
不可嵌套的内核 -- 不可以打断。
中断挂起:中断事件发生了,但是Cortex-M内核还没准备去执行。
中断服务函数: 中断发生后,要执行的程序。(固定格式)
中断通道:对于 Cortex-M 内核所支持的 240 个外部中断,使用了“中断通道”这个概念,因为尽管每个中断对应一个外围设备,但该外围设备通常具备若干个可以引起中断的中断源或中断事件[外围设备与中断源的关系为1对N]。而该设备的所有的中断都只能通过该指定的“中断通道”向内核申请中断。因此,关于中断优先级的概念都是针对“中断通道”的。当该中断通道的优先级确定后,也就确定了该外围设备的中断优先级,并且该设备所能产生的所有类型的中断,都享有相同的通道中断优先级。至于该设备本身产生的多个中断的执行顺序,则取决于用户的中断服务程序。
事实上stm32只用了4位优先级,分组时从优先级高位向低位方向分组。
中断使用的过程
1.中断优先级分组:整个工程只需要一次分组就可以,一般放在主函数的最开头。
NVIC_SetPriorityGrouping(组号);
2.配置中断通道的优先级。
NVIC_SetPriority(中断号,中断优先级);
3.使能中断通道。
NVIC_EnableIRQ(中断号);
中断触发事件
内部中断:由微控制器内部的特定事件触发,例如定时器溢出、串行通信完成等。
外部中断:由外部设备或者传感器触发,例如按键按下、传感器检测到特定条件等。
在STM32中,中断控制器(NVIC)负责管理和协调所有中断请求。
1.定时器中断:
定时器/计数器 是软件成面的,也就是通过代码来实现,我们可以通过定时器/计数器中断控制寄存器 TMOD 来设置一个时间(下面会讲到),设置这个时间的目的是在计算机执行程序的过程中,在除了 main()函数 中 while(1) 的无限循环下,在定时器中断处理函数(void Time0Handler() interrupt 1)中,也进行无限循环,只不过每次循环的时间我们都可以自己设定(通过TMOD);
2.外部中断:
来自外部,它是硬件中断,是硬件成面的中断,因此外部中断比定时器中断快(硬件肯定比软件快,比软件精准度更高);可以拥有多个中断源
外部中断我们可以简单的理解为,他就是某个引脚引起的,每次这个中断引脚受到了触发,外部中断程序就立马执行(计算机会放下手下的工作,去执行中断程序,处理完成后,再转战之前的程序),因此可以明白,只要硬件上接到了中断引脚就行,用来接收外部的信号,不管是震动传感器,光传感器,不管是什么都可以,只要是来自外部的信号,给予了该引脚,都可以使用外部中断。
https://blog.csdn.net/Super_Fisher_man/article/details/135544728
3.串口中断
由串口在通信过程中的接收或者发送数据触发的,只有一个中断源即串口通信
gpio以及中断断线
16根外部中断线 对应7个中断号
EXTI0线 ------EXTI0-------EXTI0_IRQn
EXTI1线 ------EXTI1 -------EXTI1_IRQn
EXTI2线 ------EXTI2 -------EXTI2_IRQn
EXTI3线 ------EXTI3 -------EXTI3_IRQn
EXTI4线 ------EXTI4-------EXTI4_IRQn
EXTI5--EXTI9 -------EXTI9_5 -------EXTI9_5_IRQn
EXTI10--EXTI15 -------EXTI15_10 -------EXTI15_10_IRQn
中断优先级
抢占优先级:抢占优先级高的中断可以打断抢占优先级低的中断
次级优先级:在抢占优先级相等的情况下,两个中断同时触发,次级优先级高的中断先执行,但是如果次级优先级低的中断正在执行,次级优先级高的中断不能打断次级优先级低的中断
中断 A 抢占优先级 3 次级优先级2
中断 B 抢占优先级 2 次级优先级3
中断B 正在执行 中断A触发了 ----中断B继续执行
中断A 正在执行 中断B触发了 ----中断B打断中断A 执行中断B
设置外部中断流程
- 设置GPIO口模式----浮空输入
- 开启gpio口复用时钟(AFIO)
- 设置中断线对应的GPIO引脚(PA0 映射到外部中断线0)
- 开启外部中断线
- 设置中断触发模式(上升沿or下降沿)
- 清除中断挂起位
- 设置中断优先级(抢占 次级)
- 使能中断
- 编写中断服务函数
系统定时器
定时器:定时 类似生活中的闹钟
STM32定时器
基本定时器:TIM6 TIM7 基本的定时器功能
通用定时器:TIM2-TIM5 输入捕获 输出比较PWM 编码器
高级定时器:TIM1 TIM8 刹车 死区
系统定时器:内核定时器 滴答定时器
定时器:精确延时
如何处理单片机内的精确定时和延时??
通过NOP()函数 构造一个1us延时函数
定时器来实现精确定时和延时
系统定时器是一个24位的向下计数器 每向下计数一次周期就是我们系统周期(72mhz)
SYSTICK_CONFIG(72000); 设置系统定时器的定时周期,也就是定时器的中断周期
1/72m*72000=1/1000
系统定时器每个周期要产生一次中断 当计数值由1变为0的时候 会发生中断
系统定时器的周期由什么决定?------------由重装载值决定
怎样算?系统定时器周期=重装载值*(1/72000000S)
定时器的组成
系统定时器---滴答定时器
重装载值:每次计数器减到0之后,再重新把重装载值赋给当前计数寄存器的值0-65535
预分频值:改变定时器的计数频率 0-65535
当前计数值:定时器计数器的实时值
T=(重装载值+1)*(预分频值+1)/72000000=6S
重装载值60000-1 预分频值7200-1
基本定时器
通用定时器
高级定时器
根据时钟树分析 ,TIM1-TIM8 内部时钟TIMXCLK 都是72mhz
补充:
基本定时器最大定时时长为多少? -- 1/(72M/65536)*65536 ≈ 60s
定时器中预分频寄存器和重装载寄存器拥有影子寄存器,但重装载寄存器的影子寄存器可以关闭。
更新事件:把预装载寄存器的值给实际寄存器。
定时器是用来干什么的
定时器最基本的功能就是定时处理事情。 比如定时发送USART数据、定时采集AD数据、定时检测IO口电位、还可以通过IO口输出波形等。 可以实现非常丰富的功能。
定时器实现固定周期中断的流程
- 开时钟 TIM1,TIM8(APB2) TIM2---TIM7 (APB1)
- 初始化定时器参数(重装载值,预分频值 计数模式)
- 开启中断源(更新中断)
- 设置中断优先级
- 使能定时器(cmd)
- 编写中断服务函数
- 判断中断标志位(执行相应的功能)
- 清除标志位
串口通信
学习项目中用到串口通信的外设:
空气质量检测仪
- KQM6600 (串口通信) ---空气质量检测(甲醛 CO2 有机气体)
- SU-03T (串口通信) ---语音识别 语音播报
- 数据上传 wifi esp8266(串口通信) ---数据上传云端
- 串口下载(串口通信)----下载程序 调试程序
- 蓝牙模块(串口转蓝牙)
单片机和手机的通信
一些常识概念:
通信:通过某种行为或者某种媒介进行信息交流与传递 spi iic 串口 can usb
通信方式 | 单工通信 | 设备只能发送或者接收,例如:广播电视 |
半双工通信 | 同一时刻,只能发送或则接收,例如:对讲机 | |
全双工通信 | 同一时刻,既能发送又能接收,例如:串口,手机 |
收发时机 | 同步通信 | 收发数据在同一个CLK(时钟信号)下 |
异步通信 | 收发数据不在同一个CLK(时钟信号)下 | |
数据传输方式 | 串行通信 | 一次传输1位的数据,1根数据线,1个GPIO口 |
并行通信 | 一次可以同时传输多位数据(传输速率更快,通信距离短) 一次16位数据,需要16根数据线,16个GPIO口 |
通信速率:
波特率bps(每秒钟发送的位数),进行通信的两个设备,波特率必须一样
常见的波特率:115200,9600 1200 4800 38400 57600
串口协议层:开始位(1)+数据位(8)+停止位(1)
开始位(1位)+数据位(8或者9)+校验位(可有可无)+停止位(0.5 1 1.5 2)
9600(波特率) n (无奇偶校验) 8 (8个数据位) 1(停止位)
串口通信的作用
一般:调试用,更多是和其它模块进行通信
语音模块 :通过串口给语音模块发送命令,播放音乐。
wifi模块:通过串口和模块就行数据交换
开发板串口下载程序
代码流程:
- 配置IO
- 开时钟
- 配置模式:TX------复用推挽输出 RX---浮空输入
上拉输入:没有外界信号的情况下,是高电平
下拉输入:没有外界信号时候,是低电平
浮空输入:没有外界信号的时候,电平是不确定的
3.初始化
- 配置串口
- 开时钟
- 配模式
- 初始化
- 使能串口
printf重定向:
原本的printf是将数据输出到屏幕上
在仿真里或实际开发板中使用printf,需要将printf进行重定向
自己写一个fputc函数,把数据从串口发送出去
使用printf要包含stdio.h头文件 keil中设置加入微库
根据外设实际要求去设置串口参数!!具体步骤都差不多
需要串口通信的外设
1).su-03t语音识别外设
会在其上通过网站“智能公元”来生成一个固件,将这个固件烧录到su-03t
- 人对SU-03T喊 室内温度
- su-03t收到语音之后,给单片机发送 AA 55 00 01 55 AA
- 单片机收到指令后 解析指令 然后把温度数据xx 放到 AA 55 01 xx 55 AA指令中 发给su-03t
- su-03t收到单片机指令后 播报温度相关的信息
- 开灯
- 人对SU-03T喊 开灯
- su-03t收到语音之后,给单片机发送 AA 55 00 04 55 AA
- 单片机收到指令后 解析指令 然后开灯
Su-03t驱动分析过程
- 找一个空闲串口 串口4
- 配置串口(根据su-03t的参数)
- 根据固件的设置内容去编写函数
用开发板下载su-03t步骤
- 把要烧写的固件放到桌面(固件路径不允许有中文)
- 找一个空程序(一定不要有串口1的驱动函数)下载到开发板上面
- 开发板上面的PA9接su-03t的B7
- 开发板上面的PA10接su-03t的B6
- 开发板上面的GND接su-03t的GND
- 打开下载固件的软件
2).Kqm6600传感器
传感器分为数字量传感器和模拟量传感器
- 确定通信方式--串口
- MCU找一个串口和通信 配置串口相关参数(从传感器手册获取)
- 传感器通信特点(传感器每隔1s向外主动传输8个字节的数据)
- 用串口中断去接收数据
3).wifi esp8266
ESP8266模组
开发:底层固化软件。
ESP8266是一款低成本WiFi微控制器,集成了TCP/IP协议栈,可用于嵌入式系统的网络连接。可以作为一个独立的系统运行,也可以接入到其他主处理器中,可以与外部MCU通信通过串口或SPI接口进行操作。
ESP8266芯片可以作为一个独立的系统运行,运行在客户端模式下;也可以作为一个虚拟AP与其他设备互相通信。芯片通过UART或SPI接口发送AT指令来连接WiFi并实现与远程服务器的通讯,同时支持透传模式,可以将芯片当作一个串口转换模块来使用。
AP就是传统有线网络中的无线交换机,也是组建小型无线局域网时最常用的设备。AP相当于一个连接有线网和无线网的桥梁,其主要作用是将各个无线网络客户端连接到一起,然后将无线网络接入以太网,从而达到网络无线覆盖的目的。
虚拟AP:用户可以在一个AP上创建不同的VAP来为不同的用户群体提供无线接入服务。
默认波特率:115200(模组资料中可见)
有3种模式:
STA模式:
功能:本地设备上传云平台服务器
- 先连上热点,使模块具备上网功能
- 连上服务器
- 进入透传模式
- 收发数据
AP模式
功能:手机或者电脑设置wifi参数
- 设置AP模式后
- 设置它本身散发热点的wifi账号密码
- 手机或电脑连接wifi模块生成的热点 ,组成一个局域网
- 手机和wifi模块就可以收发数据了
STA和AP
AT指令
命令 | 功能 | 备注 |
AT | 测试模块是否正常 | 基础指令 |
ATE1/ATE0 | 开启/关闭回显 | |
AT+CWMODE/AT+CWSAP_DEF | 设置AP模式及AP参数 | AT WIFI指令 |
AT +CWMODE=1/AT +CWJAP | 设置为Station 模式 | |
AT+CIPSTART | 建立TCP连接 | AT TCP指令 |
AT+CIPSEND | 发送数据 | |
AT+CIPMODE=1 | 开启透传传输 | |
+++ | 退出透传模式 |
注意:在stlink上发送数据时,命令里不能有空格,会出错
串口一和串口三实现透传,这里实现了联网后是客户机和服务器能互相发送消息
Wifi模块---------- 云端和设备之间通信的媒介桥梁
通过串口发送AT指令控制wifi模块
串口调试助手(电脑)实现对wifi模块(开发板)的控制
安信可:资源分类 | 安信可科技
云服务器:存储数据
阿里云 华为云 百度云 巴法云 有人云 移动云 腾讯云
1.这里采用阿里云平台,创建一个项目然后在手机上下载一个官方软件,软件数据和项目数据可以同步,通过设备模拟器调试输入数据,刷新后可以看到数据已更改.
2.此时引用mqtt通信协议来实现平台(服务器)和用户(客户机)之间的数据交流,至于为什么使用它,因为它代码量小,-----(可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议)
mqtt怎么用呢?
-
1.首先将它和云平台连接起来(界面版)
把这五个参数添加到mqtt.exe
这里有发布以及订阅,填写内容在下面这个界面找
2.然后添加mqtt库到项目中去,过程略
根据原理图,串口三连接wifi模块,分析代码:
通过串口3使能接收中断 进入空闲中断就会发送数据,先发送一次数据,如果在接收的数据里能找到ok(作为发送命令的条件)就发送另一条命令(AT指令,进入透传后在云平台的在线调试里找到发送具体命令的格式)
用代码实现连接mqtt
这里需要构造连接服务器的报文,连接服务器时,云端会发送2002(可以用于检查是否连接上了,没用上,不确定嘻嘻)
具体的有时间再写吧,就过一下思路.
DHT11温湿度传感器
概念
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。
数字量传感器:传感器内部有一个单片机,已经把传感器的数据进行了采集,并转换为数字量,可以以某种协议和外面的单片机进行通信,把数字量数据传递出来
模拟量传感器:以电阻 电流 电压的形式输出
特点:
单总线通信,单总线需要选择是输入(浮空)还是输出(通用推挽)
开始位是高位,一次传40位间隔2s
属于片上外设,不需要配置串口
通信过程
1.MCU发送起始信号 (1个不少于18ms 且不大于30ms 低电平)
2.从机(dht11)回复应答信号(先拉低83us 再拉高87us)
3.从 机给主机(MCU)回复40位数据
0----54us低电平 23-27us的高电平
1----54us低电平 68-74us的高电平
4.停止信号
开漏模式下 可以输出低电平 不能输出高电平
如果把电平拉高,相当于释放总线,此时CPU能获取总线的状态(这个管脚处于输入状态)
PWM实现无极调光
PWM:
脉冲宽度调制 ---占空比(占空比高电平所占整个周期的比例)
可以用于控制光的亮度
设置定时器PWM功能流程
- 设置GPIO口模式(复用推挽输出)
- 设置定时器的PWM的周期
- 设置定时器输出参数
- 使能重装载值预装载寄存器(非必须)
- 使能比较值预装载寄存器(非必须)
- 如果是高级定时器,必须加上pwm输出使能
- 使能定时器