从零开始的Stm32学习

从零开始的Stm32学习

HarderHeng Lv5

一、使用keil进行stm32开发

刚开始的入门软件是keil,所以这次也打算从keil入手,将keil学明白之后再尝试使用其他的软件和环境进行开发,同时也是使用库函数的方式进行开发。

使用keil中的pack installer安装自己要开发的板子的对应版本,然后在意法半导体官网去找相对应的软件包并解压。在官网的导航找到软件-》微控制器软件-》STM32微控制器软件-》标准外设软件库,然后选择适合自己的开发板的就可以。

这里我用的是stm32f401re开发板,所以要找stm32f4的软件包,软件包中有对应的启动文件以及库函数,库函数直接对底层硬件进行操作,所以可以提高开发的效率,但是也同样会占用更多的资源(库函数之于直接操作寄存器就好像是高级语言之于低级语言)。在keil中新建工程,并且在对应的文件夹下建立Libraries(存放库函数)、User(存放自己写的main函数)、Start(存放各种启动文件)。

启动文件详解:1. CMSIS标准中定义了内核函数层,和设备外设访问层,

二、片上外设详解

1、GPIO(通用输入输出)

image-20231016155952611

从IO引脚进入有两个保护二极管,用来防止电压过高或者电压过低。从IO口进入首先是驱动器,然后是寄存器。

上半部分的驱动器对应输入模式,信号输入首先会有一个上拉和下拉电阻,这里有三种模式可选分别是上拉和下拉和浮空。当输入端没有信号输入时,进入寄存器的高低电平就由此处控制。上拉默认为高电平的输入模式,下拉默认为低电平的输入模式。再向内有一个肖特基(施密特)触发器,是一个对输入信号进行整形的装置,当输入的信号高于一个上限时就向内输入高电平,低于下限则输入低电平,用这种方法可以减少数据的抖动。在施密特触发器前后分别接到了模拟输入和复用功能输入上,对应额外的功能。

下半部分的驱动器对应输入模式。可以用数据寄存器进行数据的输出,位设置清除寄存器可以单独操作输出寄存器的某一位但是不影响其他位,一整个数据寄存器控制所有的端口,所以不能直接对某一位进行操作,要使用按位与和按位或的操作,或者直接用位设置清除寄存器。也可以接到复用功能也就是其他片上外设上来获取额外的功能。两个mos管P_MOS,N_MOS可以配置推挽(push_pull)和开漏(open_drain)或者关闭。

GPIO的八种工作模式

1)模拟输入 GPIO_Mode_AIN 输入模式直接接入模拟输入

2)浮空输入 GPIO_Mode_IN_FLOATING 上下拉电阻选择浮空输入模式,容易被干扰

3)下拉输入 GPIO_Mode_IPD 上下拉电阻选择下拉输入模式,默认电平为低,可以用于检测由低到高的电平变化

4)上拉输入 GPIO_Mode_IPU 上下拉电阻选择上拉输入模式,默认电平为高,可以用于检测由高到低的电平变化

5)开漏输出 GPIO_Mode_OUT_OD ** 上P_MOS不工作,只有下面的N_MOS在工作,可以输出低电平,不能直接输出高电平,要靠外面的上拉电阻。适合用作通讯协议的模式,不会强行输出高电平。可以同时输入输出。**

6)推挽输出 GPIO_Mode_OUT_PP P_MOS和N_MOS都在工作,可以直接输出高低电平,是一种强推输出模式,具有强大的驱动能力可以同时输入输出

7)复用开漏输出 GPIO_Mode_AF_OD GPIO此时连接到片上外设受片上外设控制

8)复用推挽输出 GPIO_Mode_AF_PP GPIO此时连接到片上外设受片上外设控制

2、NVIC(嵌套向量中断控制器)

NVIC是一个内核外设,也就是在芯片内部,但是不同厂家也会对NVIC的功能进行裁切,但是多数情况下的NVIC是差不多的,关于NVIC的定义一般放在misc.cmisc.h里面。NVIC是用来控制系统异常和外部中断的。

使用NVIC
  • 首先使能外设某个中断,这个具体由每个外设的相关中断使能位控制。
  • 然后要使能NVIC的中断,配置NVIC中断优先级,设置优先级分配组,一共有四位作为优先级,可以将四位分别分配给响应优先级和抢占优先级,使得两种优先级都有一定的范围。
  • 接下来使用NVIC的初始化结构体为开启的外设中断通道分配响应优先级和抢占优先级,(响应优先级是中断同时发生时响应优先级高的可以产生中断,抢占优先级是在进行一个中断时另一个抢占优先级高的能够中断抢占优先级低的事件),然后使用初始化函数初始化NVIC。
  • 配置好NVIC和外设的中断之后,接下来要编写中断函数,当外设的中断事件触发时,就可以跳转到自己写的中断函数中。

3、USART

4、I2C

5、TIM定时器

定时器有三种,分别是基本定时器,通用定时器,高级定时器。

image-20231113132948740

基本定时器的基本单元就是时基单元,由预分频器、计数器和自动重装寄存器构成,预分频器负责将内部时钟进行分频,自动重装寄存器中存着需要计时的次数,计数器会向上计数,到达自动重装寄存器的数值时重新装填,并且触发触发NVIC的中断,或者跳转到更新事件。可以开启主模式触发DAC,在主模式下计数器触发不会触发中断,会直接触发映射到TRGO然后直接输出DAC。

image-20231113133125832

通用定时器的核心还是时基单元,和基本定时器是一样的。通用定时器和高级定时器支持向下计数和中央对齐模式。通用定时器支持外部时钟驱动,从外部时钟进入的信号经过极性选择、边缘检测和预分频器还有滤波,可以直接作为时基单元的时钟,这一路叫做外部时钟模式2。另外的TRGI触发输入当做时钟,叫做外部时钟模式1。外部时钟可以直接接入TRGI;其他的定时器的TRGO输出也可以接入TRGI,作为定时器的级联;也可以从CH1引脚的边沿触发作为输入,类似于输入捕获。

下半部分是输入捕获和输出比较的电路,这两个功能共用一套寄存器,所以同时只能使用其中一种功能。

image-20231113194330817

高级定时器的计数器后面还有一个重复次数计数器,计数器满多少个周期后产生输出,也就是一个输出分频器。相比于通用定时器,在下面的输出比较模块多了DTG功能,输出多了一个口可以生成PWM的互补波形,用来驱动三相无刷电机。下面还有一个刹车输入,外部引脚产生刹车信号或者外部时钟失效是,就会产生刹车信号自动切断电机的信号。

预分频控制寄存器不会直接控制分频系数,预分频控制寄存器有一个缓冲寄存器,这才是真正起作用的寄存器。改变预分频控制寄存器后,在下一个周期时才会更改缓冲寄存器的值来改变分频系数。自动重装寄存器也有缓冲寄存器,效果是一样的。影子寄存器的作用就是保证数据的更改在同一个周期后更新,防止发生错误。

计数器的计数频率就是输入的时钟频率/(分频系数+1),计数器溢出的频率(中断更新频率)就是计数频率/(自动重装寄存器+1)

定时器的输出可以进入中断输出控制。

(1)使用TIM定时器

image-20231113220608188

要使用定时器就要打通从左到右的全流程。首先时钟的输入源,RCC内部时钟或者ITR其他定时器或者TI的输入捕获通道,通过外部时钟可以选择两个外部时钟模式,ETR引脚的配置需要额外配置一下。配置好输入源之后,可以开始配置时基单元的两个寄存器,然后要配置中断输出控制和NVIC两个东西。最后还要手动启动一下运行控制。

(2)输出比较功能Outp Compare

输出比较功能可以用来输出PWM信号。使用输入捕获和输出比较寄存器,将CNT计数器里面的数字和CCR捕获比较寄存器进行对比,然后如果大于或者小于就翻转输出的电平。

调整时基单元的输入,预分频器PSC,ARR自动重装器,可以调整PWM的周期和频率,然后CCR的值和ARR值的比值就是占空比。

image-20231114175347871

输出模式控制器有八种模式。

  • 冻结, REF保持原状态
  • 匹配时置有效电平,CNT=CCR时,REF置有效电平(高电平)
  • 匹配值置无效电平,CNT=CCR时,REF置无效电平(低电平)
  • 匹配时电平翻转,CNT=CCR时,REF电平翻转,输出的波形占空比始终为50%
  • 强制有效电平,CNT和CCR无效,REF强制为高电平
  • 强制无效电平,CNT和CCR无效,REF强制为低电平
  • PWM模式1,向上计数:CNT<CCR时置REF为有效电平,CNT>=CCR时置REF为无效电平,向下计数同理。
  • PWM模式2,向上计数:CNT<CCR时置REF为无效电平,CNT>=CCR时置REF为有效电平,向下计数同理。

在输出信号后再经过CC1P,这里还可以进行一次极性翻转。最后信号会通向GPIO口。

对于高级定时器,有两个互补的PWM输出端口,用来驱动外面的推挽电路。

IMG_1117

这两个互补的端口会分别导通正极和负极,在外面产生一个PWM波形,最高电压就是推挽电路的正极电压。在这两个端口前面还有一个死区生成器,在两个端口切换电平是提供一段时间的死区防止上两个端口接通时间比较接近导致的短路。

要使用PWM首先需要配置TIM定时器,然后配置输出比较这一块所有的寄存器,就可以使用PWM了。

6、RCC时钟树

image-20231113201719527

时钟源有四个,分别是内部外部高速低速。外部的是石英震荡器,内部的是RC振荡器,外部时钟更稳定,更常用。

  • HSI高速内部时钟 8MHz

  • HSE高速外部时钟 4-16MHz

  • LSE低速外部时钟 32.768kHZ

  • LSI低速内部时钟 40kHz

  • PLLMUL是锁相环,外部高速时钟会经过锁相环倍频,然后进入预分频器。

  • CSS用来检测外部时钟是否正常,如果出了问题会自动切换到内部时钟

  • 进入预分频器后,旁路可能会有倍频器来输出72MHz到TIM定时器。

    使用外设时钟控制,就可以将外设时钟使能与进时钟输出,也就是启动时钟。

stm32上电后先进行Systeminit,先开启内部高速时钟HSI,然后初始化HSE开始使用HSE作为时钟,然后通过AHB预分频器进行分频

三、通信协议

1、I2C协议

同步半双工,带数据应答,支持总线挂载多设备,两条总线:SCL(时序总线)SDA(数据总线)

硬件I2C:STM32如果有I2C硬件模块可以直接使用,查手册找一下I2C挂载在何处,然后初始化I2C的各种属性。直接往数据寄存器中写入值发送然后直接从数据寄存器中读取数据。

软件I2C:可以使用软件函数的方式模拟I2C协议,初始化GPIO口,将一个口的输出作为SCL另一个作为SDA,然后根据I2C的时序特点在不同的时序阶段将数据放在SDA总线上,定时上拉和上拉SCL。

所有设备的SCL和SDA都接在一起,挂载在同一条总线上,SCL由主设备进行控制,SDA可以由主设备释放给从设备使用。设备的SCL和SDA都需要使用开漏输出模式加上拉电阻。在一主多从模式中也可以使用推挽输出模式,但是在多主多从有可能会造成多个主设备短路,所以在任何情况下都需要使用开漏输出模式

时序特点

1)基本时序单元

  • 产生起始条件:SCL高电平期间,SDA从高电平切换到低电平

  • 产生终止条件:SCL高电平期间,SDA从低电平切换到高电平

  • 产生起始条件和终止条件都是由主机决定的。

  • 主机发送数据:SCL低电平期间将一位数据放到SDA上后,主机将SCL提到高电平,此时SDA不允许有变化,从而让从机接收数据,高位先行。

  • 主机接收数据:主机释放SDA将控制权交给从机,主机控制SCL,在低电平期间从机发送数据,在高电平期间主机接收数据

  • 发送应答:在主机接收完一个字节后,在下一个时钟发送一位数据,数据0表示应答

  • 接收应答:在主机发送给从机一个字节后,在下一个时钟发送一位数据给主机,主机此时要接受这个数据,数据0表示应答,数据1表示非应答

2)通信时序

  • 指定地址写:对于指定设备的指定寄存器写入数据。

​ 第一个数据帧,七位地址一位读写位(0写1读),紧跟着就是应答位,从机此时应该给主机接受应答。第二个数据帧,可以是设备的内部寄存器地址,紧跟着应答位。接下来的帧就可以发送要写入的数据,每写入一个字节,设备的内部寄存器地址指针就会自动递增

​ 再往后主机可以产生终止条件。

  • 指定地址读:对指定设备的指定寄存器写入数据。

​ 第一个数据帧,七位地址**+一位读写位(此时写入),然后从机数据应答,第二个数据帧,指定设备的内部寄存器地址,然后从机应答,此时重新产生起始条件,第三个数据帧指定七位地址+**一个读写位(此时读入),第四个数据帧就是从机返回给主机的数据。每读取一个字节,设备内部寄存器地址的指针会自动递增。

​ 最后主机产生终止条件。

10bit地址读写

如果是10bit的从机地址,需要两个字节确定从机地址,第一个字节为11110 XX X,前面的11110是IIC协议中保留的特殊地址指令,后面XX是从机地址的前两位,(剩下的八位要在下一个字节中给出),最后一位依然是读写位。在第一个字节后前两位地址满足的从机都需要进行ACK应答。

主设备指定地址写,确定从机地址之后就可以接着发送其他数据进行写入。

主设备指定地址读,确定从机地址之后,接着发送寄存器地址,然后重新发送第一个字节重复起始信号并且改成读。

2、USART协议

异步全双工,点对点通信,两个引脚TX和RX,分别用来发送数据和接收数据,点对点发送数据也就是TX接RX,RX接TX。

波特率是串口通信的速率。

时序特点:

空闲状态是高电平,每个时序单元的起始位是低电平来表示开始传输一个数据帧,停止位是一个高电平,也就是重新回到空闲状态。数据帧低位先行。在停止位之前,数据帧之后,可以选择性的添加一个校验位。

轮询模式:

3、PWM输出信号

PWM是一种模拟信号,在具有惯性的系统中,对PWM进行调制,就可以等效的获得的模拟量。PWM频率=1/T,占空比=Ton/T也就是每个周期中高电平的时间比上周期的时间,占空比决定模拟输出的电压。分辨率占空比变化步距,就是占空比的变化程度。

  • Title: 从零开始的Stm32学习
  • Author: HarderHeng
  • Created at : 2024-01-20 18:16:19
  • Updated at : 2024-11-05 21:18:40
  • Link: https://harderheng.life/2024/01/20/从零开始的Stm32学习/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments