一、启动文件配置
二、GPIO使用
2.1基本步骤
1.配置GPIO,所以RCC开启APB2时钟
2.GPIO初始化(结构体)
3.给GPIO引脚设置高/低电平(WriteBit)
2.2Led循环点亮(GPIO输出)
1.RCC开启APB2时钟。
RCC_APB2PeriphClockCmd
2.GPIO_init初始化GPIO。参数是结构体,GPIO_PIN1 | GPIO_PIN2可以同时初始化。
3.GPIO输出
GPIO_ResetBits给gpio端口设为低电平(led点亮)
GPIO_SetBits给gpio端口设为高电平(熄灭)
GPIO_WriteBit,第三个参数决定
5、添加延时函数
6、循环点亮
2.3按键控制两个led(GPIO输入)
Led:
1.RCC开启GPIO所在的APB2时钟
2.GPIO初始化,默认设置为高电平
3.写函数分别控制GPIO对应引脚的高/低电平,为之后按键控制做准备
按键:
1.RCC开启APB2时钟
2.GPIO初始化
3.GPIO读取输入信息,按键按下时读取为0
GPIO_ReadInputDataBit,代表输入寄存器的某个端口的值
0代表按下,防抖,如果不松开按键一直循环,松开按键后,跳出循环,再防抖,修改变量KeyNum的值代表按下pin_1对应的按键了。
GPIO_ReadInputData,代表整个输入寄存器。
4.反转
GPIO_ReadOutputDataBit,输入的是什么,输出什么,输出0时,设为高电平灯灭。
三、显示屏(OLED)
3.1调试方法
1.串口调试
2.显示屏调试
3.keil调试
3.2显示屏调试(OLED)
参数:行,列,值,(长度)
采用IIC或SPI协议。这里采用IIC,IIC有两个引脚SCL,SDA
1.RCC打开APB2时钟
2.GPIO初始化,要注意SCL和SDA对应GPIO引脚都要初始化,这里是pin8和pin9,且因为IIC协议有上拉电阻,所以是开漏输出
3.引脚配置,默认SCL和SDA两个引脚都配置为高电平
4.最后通过导入OLED.h显示
四、EXTI中断
4.1stm32中断
中断方法有很多,EXTI,TIM,ADC,USART,IIC
NVIC用来决定优先级。
4.2中断基本步骤
1.RCC开启GPIO和AFIO对应的APB2的时钟,EXTI和NVIC默认是开着的
2.GPIO初始化(结构体)
3.AFIO配置,用来选择哪个GPIO,GPIO的哪个引脚发生中断,用GPIO_EXTILineConfig(GPIO中断线引脚)
4.EXTI中断配置,EXTI初始化——EXTI_Init函数(结构体)
5.NVIC优先级组配置和初始化,通过对优先级分组来决定优先级,使用NVIC_PriorityGroupConfig,之后进行NVIC初始化——NVIC_Init
4.3具体步骤
1.RCC时钟配置,主要GPIO和AFIO。EXIT和NVIC是一直打开时钟的,不需要配置
2.GPIO配置初始化,上拉输入
3.AFIO配置
第二个是选择中断引脚
第一个是重映射,先不用
4.EXTI配置
Mode选中断模式,还有个事件模式
Triggle分为上升沿触发(从低电平到高电平),下降沿触发(从高电平到低电平触发,选这个)和上升下降沿触发
5.NVIC配置
先分组,这里分到组2,也可以选其他组,然后NVIC初始化。
6.中断配置好了,接下来让cpu从主程序跳到中断程序,中断函数的名字固定的
先判断中断标志位是不是pin14,如果是,执行中断程序,最后中断标志位清空,否则一直循环中断程序。
挡光片遮挡后,led灯会触发中断,灯灭
五、TIM定时中断
5.1基本步骤
1.TIM1和TIM8是高级定时器,TIM2-5是通用定时器,TIM6和TIM7是基本定时器。这个芯片只有TIM1-4,这里用的是TIM2通用定时器。所以RCC打开TIM2对应的APB1(低速外设)时钟。
2.TIM配置内部时钟/ETR外部时钟/ITRX其他定时器/TIx捕获通道,这里使用内部时钟,内部时钟使用TIM_InternalClockConfig。
(RCC掌管外设时钟,TIM定时器是外设)
3.时基单元初始化(结构体),TIM_TimeBaseInit
4.中断输出控制,定时器很多地方都需要申请中断,使用TIM_ITConfig
5.配置NVIC,有中断就有优先级,优先级+初始化
6.运行控制,放最后定时器运行,TIM_Cmd
5.2具体步骤
1.配置GPIO时钟
2.配置RCC内部时钟/ETR外部时钟/ITRX其他定时器/TIx捕获通道
3.配置内部时钟模式/外部时钟模式2/外部时钟模式1/编码器模式
4.配置时基单元和运行控制(放最后)
5.配置中断输出控制
6.配置NVIC
7.计数
六、TIM输出比较
6.1TIM输出比较与PWM
PWM(Pulse Width Modulation),即脉冲宽度调制,是一种模拟电路数字控制技术。它通过改变脉冲信号的占空比(即脉冲宽度与周期的比值)来等效地获得所需的模拟量(电压或电流)输出。
6.2呼吸灯实现的基本步骤
1.因为要用到GPIO和TIM,所以RCC需要打开APB2和APB1的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
2.GPIO初始化(led灯)
3.开启TIM2内部时钟
4.时基单元初始化
5.输出比较(oc)单元初始化TIM_OC1Init
6.运行控制
7.修改占空比,TIM_SetCompare1函数可以设置CCR的值(1是因为OC1通道1)
6.3具体步骤
1.RCC开启GPIO和TIM时钟
2.配置时基单元
3.配置输出比较单元
IIM_OCInitTypedef结构体有很多属性,有一些高级定时器用的,我们不用配置,所以需要给这些初始化,用TIM_OCStructInit,然后把需要的配置。
注:这里初始化是TIM_OC1Init,用于初始化定时器的输出比较通道1。每个定时器的输出比较总共有4个通道
4.配置GPIO,复用推挽输出
我们在GPIO,PA0引脚,所以输出比较单元用的TIM_OC1Init。这里配置PA0。
5.运行控制(TIM_Cmd)
6.参数计算
7.呼吸灯
当CCR大的时候亮,小的时候暗,所以要实现呼吸灯,需要不断改变CCR的值,用TIM_SetComparel函数可以设置CCR的值,主循环中让它逐渐增大,然后逐渐减少。
8.拓展——重映射
6.4舵机控制
和呼吸灯步骤一样,只需要修改通道和占空比即可,分别是OC2Init()和TIM_SetCompare2(TIM2, Compare)。呼吸灯是TIM_SetCompare1。
七、输入捕获
7.1测频率基本步骤
1.RCC开启GPIO和TIM的时钟
2.GPIO初始化,配置成输入模式
3.时基单元初始化
4.输入捕获单元初始化
5.配置触发源,这里使用FI1PF1触发源
6.配置从模式Reset
7.运行控制
7.2具体步骤
1.RCC开启GPIO和TIM的时钟
2.GPIO初始化,配置成输入模式
3.时基单元初始化
4.输入捕获单元初始化
这是只测频率,所以使用ICInit即可,ICSelection选择直联通道。
5.配置触发源,这里使用FI1PF1触发源
6.配置从模式Reset
7.运行控制
7.3测频率和占空比
把TIM_ICInit函数换成TIM_PWMIConfig函数,这个函数能同时初始化两个通道。这里通道1是直联和上升沿,默认配置通道2是交叉和下降沿,与通道1正好相反。
八、USART串口通信协议
8.1常见通信协议
半双工:A能给B发数据,B也能给A发数据,但是不能同时发。
全双工:A能给B发数据,B也能给A发数据,而且能同时发。
同步:通信双方有一个共同的时钟信号,通讯中通常双方会统一规定在时钟信号的上升沿或下降沿对数据线进行采样。
异步:数据传输速度匹配依赖于通信双方有自己独立的系统时钟,大家约定好通信的速度。异步通信不需要同步信号,但是并不是说通信的过程不同步。
8.2串口通信方式
两个设备之间发送端和接收端交叉连接。
因为两个设备可能要不同的电平,中间可以加电平转化芯片,本芯片采用TTL电平——3.3V
设备1给设备2发送数据:假设设备1每一秒发送一次高电平(3.3V)或低电平(0V),设备2就必须每一秒接受一次,如果时间不一样,可能重复或错过。
这个每秒发送一次数据就叫波特率。如果发送的高电平,则接受到1,如果是低电平,则接受到0。
8.3串口发送+接收数据基本步骤
1.RCC开启USART1和GPIO时钟
2.GPIO初始化,TX配置成复用输出,RX配置成输入
3.USART初始化
4.如果只发送,直接开启USART即可。如果还要接收数据,则需要配置中断。
5.中断输出控制(发送+接收)
6.NVIC(发送+接收)
8.4具体步骤
1.RCC开启USART1和GPIO时钟
2.GPIO初始化,TX配置成复用输出,RX配置成输入
3.USART初始化
4.运行控制USART
5.上面已经可以发送了,现在发送数据
发送之后到TDR,需要等待一段时间,等TDR的数据传到移位寄存器后,再发送下一次数据,如果不等待,可能造成数据覆盖。标志状态为reset时一直循环等待
6.如果还要接收数据,需要中断,并且串口初始化时,需要把接收数据的模式加上
九、I2C
9.1串口通信缺点
如果只有两个设备通信,设置一组串口
设备1 —— 设备2
如果有三个设备需要通信,则每个设备都需要设置两组串口
设备1——设备2
设备1——设备3
设备2——设备3
如果更多设备需要通信,则需要设置更多串口,线路连接更加复杂。为此,设计了一种总线通信方式,包含多种协议,如I2C,SPI,CAN等
9.2 I2C通信方式
I2C(又叫IIC),意思是芯片与芯片之间的通信。采用一主多从的方式,例如把单片机作为主机,其他设备做为从机。
串口通信使用发送线TX和接收线RX进行通信,而IIC使用时钟线SCL和数据线SDA通信。
SCL:————————————
SDA:————————————
设备:主 从 从 从 ....
9.3 I2C发送数据
起始位为0时,代表单片机给从设备写数据
起始位为1时,代表单片机从从设备读数据
空闲状态:SCL和SDA都保持高电平
起始状态:SDA先切换为低电平,SCL后切换为低电平。(起始位为0时,代表单片机给从设备写数据,所以SDA变成低电平)
发送数据:根据要发送的数据,把SDL先切换为高电平1或低电平0,之后SCL切换为高电平。发送一个1或0后,SCL再切换为低电平。
通过发送数据,就可以发送设备地址。
设备地址有7位,每个从设备都有自己的设备地址,假设一个从设备的设备地址为1010000
两个线的高低电平如下
发送完设备地址后,需要发送读/写位,写置0,读置1。
之后,从设备发送应答信号,若从机接收到之前的命令,则回复0。
之后发送寄存器地址,寄存器地址有8位,假设主设备要和从设备MPU6080通信,需要在从设备中找一片区域从放之后发送的数据,这片区域的地址就是寄存器地址。如果从设备收到,则再次应答。
找到从设备,找到寄存器地址后,就可以发送数据(8位),从设备接收到应答。
终止状态:先SDA切换为高电平,后把SCL也切换为高电平。
9.4 软件IIC发送数据的代码
1.把IIC的两根线分别接到GPIOB下pin10和pin11引脚,用软件实现,所以使用GPIO即可
RCC开启APB2下的GPIOB时钟,且初始化,注意需要把输出模式配置成开漏输出。
如果是推挽输出,当一个从设备发送0,一个从设备发送1时,有可能短路。所以需要换成开漏输出,这样只能输出0,要想输出1,只能在IIC总线上接一个电源和上拉电阻(防止短路)。
2.为了方便控制后续的SDA和SCL的高低电平,可以封装几个函数,然后配置初始状态,终止状态和发送数据,发送数据以高位优先。
3.主机接收数据
4.发送和接收应答
5.主函数调试
6.IIC总结
到这说明硬件接线和这6个时序是正确的,通过IIC已经把单片机和从设备MPU6050联系起来了。接下来完成指定寄存器地址,写入数据,读取数据。
7.新建MPU6050的.h和.c文件,这个文件基于IIC文件,所以需要先引入头文件,然后对MPU6050完成指定地址写操作如下
分别对应下图的起始状态,发送设备地址(0xD0)包含了写位,收到应答,发送寄存器地址,收到应答,发送数据,收到应答,停止位。正好一一对应
8.指定地址读操作如下
十、SPI
1.SPI简介
SPI通信也是一主多从的模式,一个主设备,多个从设备。
为了实现SPI,需要四条线,分别是SCLK,MOSI,MISO,SS。通过共享这四条线,实现全双工的数据传输(同时发送或接收数据)。
这四条线的作用分别如下:
SS:片选信号线,从多个从设备中选出目标设备,确保只有选定的从设备与主设备通信。
SCLK:时钟信号线,用于同步数据传输,时钟信号的频率决定数据传输的速率。
MOSI:发送信号线,将数据从主设备传输到目标从设备
MISO:接收信号线,目标从设备将数据返回给主设备
2.准备数据
假设目标从设备是93C46(EEPROM存储器)
首先,设置片选信号线。根据93C46的数据手册,SS在高电平时有效。(大部分是低电平有效,但是93C46是高电平有效,不同设备需要查看各自的数据手册)
然后,主设备给从设备写数据。假设在从设备的0x01处的地址写入0000 1111这一个字节的数据,根据数据手册
先发送起始位1,然后发送写操作01,然后再发送要写入的地址(因为要写入0x01处的地址且规定地址是7位,所以发送000 0001),最后发送数据(0000 1111)。
3.发送数据的方法
准备好数据后,我们知道要发送这些数据
1 01 000 0001 0000 1111,但是怎么发送呢?
这需要SS,SCLK和MOSI共同实现。
首先,把主设备与从设备的SS设置为高电平,代表选中了93C46从设备。
然后,拉高SCLK的电平,也就是时钟信号的上升沿时,看MOSI(发送信号线)是高电平还是低电平,此时若是高电平,则发送1,此时若是低电平,则发送0。
如上图圈一所在剪头,此时SCLK处于上升沿,发送MOSI所在高电平1。最终结果如下
4.读取数据方法
首先,主设备需要向目标从设备发送读取指令
起始位:1
读操作:10
要读取的数据的地址:7位(假设0x01=000 0001)
这样就可以收到数据。
同样,需要用到SS,SCLK和MISO
SS高电平,当SCLK上升沿时,MISO为高电平,则读取1,MISO为低电平,则读取0。
5.代码实现