小白江科大stm32笔记(自己复习用)

 P0        序言&感想

        如有差错,欢迎指出,正在学习,随时更新

        1.为什么Stm32初始化外设都需要先打开时钟——每个外设都有独立时钟,如果不打开时钟外设就不能用,原因就是为了低功耗节省用电,不用的外设可以不打开时钟

        2.初始化结构体和初始化库函数配合使用是标准库精髓所在,理解初始化结构体每个成员意义(函数经典成员:恢复缺省配置,初始化和结构体初始化)

P5        GPIO输出

        ·带FT的引脚可容忍5v电压

        ·所有的GPIO都是在APB2外设总线上

        ·每个GPIO总共有16个引脚,从0到15

        ·32是32位单片机,寄存器有32位,但只有16个端口,所以只有低16位有端口

下图为GPIO基本结构:  

dd538c4cf90b400580f7ae3a6e489e5d.png

        ·以下面GPIO电路图为例,左三为寄存器,中间为驱动器,右边为某一个端口的的IO口的引脚。同时,整体分为两个部分,上面是输入部分,下面是输出部分

GPIO8种工作模式

(PS:详细参考手册)

        1.浮空输入:不确定外部模块输出的默认状态或外部信号输出功率小(缺点:当引脚悬空时,没有默认电平,输入受噪声干扰,来回不断跳变)

        2.上拉输入:

        3.下拉输入:如果外部模块默认输出低电平,则配置下拉输入,上拉反之。一般默认高电平

        4.模拟输入:一般时候用不到

        5.开漏数入:高电平时呈现高阻态,没驱动能力

        6.推挽输入

        7.复用开漏输出

        8.复用推挽输出

P6        LED闪烁&LED流水灯&蜂鸣器

P13        TIM定时中断

        ·中断源:对于外部中断来说,可以是引脚发生了电平跳变;对于定时器来说,可以是定时的时间到了;对于串口通信来说,可以是接收到了数据。

        ·中断优先级:当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源。

        ·中断嵌套:(中断程序再次中断,二次中断现象)当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回。

8bda92f0cd8d4c10b7769e0dd9fc5f2c.png

        ·响应优先级和抢占优先级(我的理解是):当程序1运行完后,响应优先级高的即使没排队,也可以直接运行;当程序1正在运行时,可以不等程序1运行完,抢占优先级高的可以让程序1靠边,优先运行,优先值越小,优先级更高。

acd1003bff4b4140a39092c180843fab.png

AFIO

        ·AFIO主要完成两个任务:复用功能引脚重映射(就是最开始提到的引脚定义表,当想把默认复用功能换到重定义功能时,就是用AFIO来完成的,这也是AFIO的一大主要功能)、中断引脚选择。

EXTIx是外部中断对应的中断资源 

       ·工作原理: EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序。

        ·触发方式:(引脚电平的变化类型)上升沿/下降沿/双边沿/软件触发(程序执行代码就能触发中断)。

        ·支持的GPIO口(外部中断引脚):所有GPIO口都能触发中断,但相同的Pin不能同时触发中断(比如PA0和PB0不能同时使用,智能选一个作为中断引脚;所以如果有多个中断引脚要选择不同的pin引脚,比如PA0和PA1、PB3就可以)

        ·NVIC就是STM32用来管理中断,分配优先级的,其中断优先级共有16个等级

P14        定时器中断&定时器外部时钟

        ·操作步骤:

        (1)RCC时钟中断开始

        (2)选择内部时钟源

        (3)配置时机单元

        (4)配置输出中断控制,允许中断输出到NVIC

        (5)配置NVIC,并配置优先级 

        (6)运行控制-使能计数器

        (7)定时器中断函数

        ·中断输出:ITConfig

        ·TIM2~7是APB1的外设时钟

        ·选择内部时钟,则默认是使用内部函数,可以不配置

        ·计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)

                               = CK_PSC / (PSC + 1) / (ARR + 1)

         ·PSC(Prescaler,预分频器值):它用于对输入时钟(CK_PSC)进行分频。通过设置PSC的值,可以降低输入时钟的频率,其计算公式为经过预分频后的时钟CK_CNT = CK_PSC / (PSC + 1)。例如,如果输入时钟CK_PSC是100MHz,设置PSC为9,那么CK_CNT的频率就是100MHz / (9 + 1)=10MHz。


        ·ARR(Auto - Reload Register,自动重装载寄存器值):决定了计数器的计数上限。当计数器的值达到ARR所设定的值后,计数器会重新从0开始计数,并产生相应的溢出事件,这用于确定计数器的周期,从而影响溢出频率。例如,在定时器应用中,如果ARR设置为999,计数器从0开始计数,计到999后就会溢出重置。

        ·CK_CNT:这是经过预分频后的时钟信号用于驱动计数器计数的时钟频率。计数器在这个时钟的驱动下进行计数操作,每来一个 CK_CNT 时钟脉冲,计数器的值就会加1。
        ·CK_CNT_OV:这是计数器的溢出频率。当计数器计数到自动重装载值(由 ARR 决定)时就会产生溢出, CK_CNT_OV 表示这种溢出情况发生的频率,即单位时间内计数器溢出的次数。

P15        TIM输出比较

PWM

       · 频率 :f = 1 / Ts(周期的倒数就是频率);变换越快=频率越大(PWM的频率越快,它等效模拟的信号就越平稳,不过同时性能开销就越大;一般来说PWM的频率在几kHz到几十kHz之间。)

       · 占空比:q=Ton/Ts( Ton是高电平的时间,Ts是一个周期的时间。q就是高电平时间相对于整个周期时间的比例);占空比决定了PWM等效出的模拟电压的大小。一般用百分比表示。

        ·分辨率:占空比的变化步距;分辨率就是占空比变化的精细程度。即,占空比最小能以百分之多少的精度变化,它的值可以是1%、0.1%。分辨率的大小要看实际项目的需求定。如果既要高频率,又要高分辨率,就需要硬件电路要有足够的性能。要求不高的情况下,1%的分辨率就足够使用了。

P18        输入捕获模式测频率&PWMI模式测频率占空比                                                                 

        · PWM频率=更新频率=72M/(PSC+1)/(ARR+1),占空比=CCR/(ARR+1),所以通过ARR调节频率,会影响占空比,而通过PSC调节频率不影响

        ·TIM_PrescalerConfig:单独写入PSC的函数  

7a62caf17d9d439da6b12a6b6f66a94c.png

27ec71a9f41d4986b616e14528258760.png

        ·IC捕获的初始化:

        (1)RCC开启时钟,把GPIO和TIM的时钟打开

        (2)GPIO初始化,把GPIO配置成输入模式(上拉或浮空)

        (3)配置时机单元,让CNT计数器在内部时钟的驱动下自增运行

        (4)配置输入捕获单元

        (5)选择从模式的触发源

        (6)选择触发之后的操作

        ·TIM_SelectInputTrigger:选择输入触发源TRGI(对应上图第二个模块)

        ·TIM_SelectOutputTrigger:选择输出触发源TRGO(主模式的触发源)

        ·TIM_SelectSlaveMode:选择从模式

P19        编码器接口

4145f55ccf3d469ea24019ac3e806505.png

bafeca3432314f789660781b937372f1.png

P20        编码器测速接口

27ec71a9f41d4986b616e14528258760.png

        操作流程:

        1.RCC开启时钟,开启GPIO和定时器的时钟

        2.配置GPIO

        3.配置时机单元,预分频器选择不分频,自动重装一般最大给65535

        4.配置输入捕获单元,这里只有滤波器和极性两个有用

        5.配置编码器接口模式

        6.调用TIM_Cmd,启动定时器

        ·不需要定时器内部时钟配置,因为编码器接口会托管时钟,是一个带方向控制的外部时钟

        ·计数器模式也没用,也被托管

P21         ADC模数转换器

        ·ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁(具体解释:STM32主要是数字电路,数字电路只有高低电平,没有几v电压的概念,所以想读取电压值,就需要借助adc模数转换器来实现,adc读取引脚上的模拟电压转换为一个数据存在寄存器里,我们再把这个数据读取到变量里来就可以进行显示、判断、记录等操作了)

        ·数字到模拟的桥梁是DAC数字模拟转换器,使用DAC就可以将数字变量转换为模拟电压,PWM也是数字到模拟的桥梁,PWM实现的就是DAC的功能,同时PWM只有完全导通和完全断开两种状态,在这两种状态上都没有功率损耗,所以在直流电机调速这种大功率的应用场景使用PWM来等效模拟量是比DAC更好的选择并且PWM电路更加简单更加常用,所以PWM还是挤占了DAC很多的应用空间

基本结构:

b8195fec0f8a43cd9349795baa8cff5d.png

9ff2566ba4ac4e4aad058e590d3bf9a1.png45f3377de7ba43c2b93ff84579c869b4.png

四种转换模式:

        ·单次转换:每触发一次,转换结束就会停下来,下次转换就得再触发才能开始

        ·连续转换:一次转换完成后不会停下来,而是立刻开始下一轮的转换,并持续下去

        ·非扫描模式:只对存放在序列1的通道起作用。

        ·扫描模式:用到“菜单”列表,可以在菜单里点菜,每个菜单列表位置是通道几是可以任意指定的并且可以重复,然后初始化结构体有个通道数目的参数(表明用了几个通道)。

31fcf0de37fb4247b01e1cbbbbf8f0ae.png4f9720a876d64970b8a51df15e728578.png

27d969a6d6f34acd900baf404d1cc548.pngbee85bf125fd499abefacd5906e23152.png

        数据对齐

25072c59b1f24a2f802e482b94dc86bf.png

        ·STM32中的ADC是12位的,但是数据寄存器拥有16位,故存在数据对齐的问题。数据右对齐,即作为转换结果的12位数据向右靠,高位补0;数据左对齐,即作为转换结果的12位数据向左靠,低位补0。在使用时通常使用数据右对齐,这样在读取时直接读取寄存器即可。

AD转换时间

32a141220af84b08ae96406941db4c26.png

ADC校准

7506939af99342b7a7df5d63d899ffd8.png

(不需要理解,这个校准过程是固定的,只需要在ADC初始化的最后加几条代码就行了,至于如何计算如何校准,不需管)

P22        ADC单通道&ADC多通道

AD模块编程步骤:

        ·开启ADC和GPIO的时钟,设置ADC时钟

        ·GPIO初始化

        ·规则组通道配置

        ·ADC初始化

        ·ADC使能

        ·ADC校准

P23        DMA直接存储器存取

e47402759b6043bcbed97e780dd80216.png

15fa3033e01a4b16af5c6ce83796baa2.png

·DMA基本结构

d50574b5d8334e09aca1499fb58b7063.png

P24        DMA数据转运&DMA+AD多通道

P25        USART串口协议

02c9537343b54383bfece0a31e017d06.png        ·USART——TX是数据发送引脚,RX是数据接收引脚

        ·I2C——SCL是时钟,SDA是数据

        ·SPI——SCLK是时钟,MOSI是主机数据输出脚,MOSI是主机数据输入脚,CS是片选

        ·CAN——两个是差分数据脚

        ·USB——两个是差分数据脚

        ·全双工:通信双方能够同时进行双向通信

9b416b42f1d84cbe91a25a43b6e8f632.png

串口引脚分布:21ec67636e6543d28485ce3bc884e5a5.png

P27        串口发送&串口发送+接收

串口的几个重要的参数:

        ·波特率,串口通信的速率空闲,一般为高电平
        ·起始位,标志一个数据帧的开始,固定为低电平。当数据开始发送时,产生一个下降沿。(空闲–>起始位)
        ·数据位,发送数据帧,1为高电平,0为低电平。低位先行。比如 发送数据帧0x0F 在数据帧里就是低位线性 即 1111 0000
        ·校验位,用于数据验证,根据数据位的计算得来。有奇校验,偶校验和无校验。
        ·停止位,用于数据的间隔,固定为高电平。数据帧发送完成后,产生一个上升沿。(数据传输–>停止位)

串口发送编程步骤:

        1.开启GPIO和USAET时钟

        2.GPIO初始化,把TX配置成复用输出,RX配置成输入(查看引脚定义表RX在APB10,TX在APB9)

        3.配置USART初始化,使用结构体

        4.如果需要接收的功能,加上时钟

        TX要选复用推挽输出,RX要选浮空输入或上拉输入(串口波形空闲状态是高电平,所以不使用下拉输入)

其NVIC初始化:

d953a77b24044b36bb83223dac9a3b7c.png

串口发送程序的运行:

        1. 当串口发送数据时,会检测发送移位寄存器是不是有数据正在移位,如果没有移位,那么这个数据就会立刻转移到发送移位寄存器里。准备发送。

        2. 当数据移动到移位寄存器时,会产生一个TXE发送寄存器空标志位,该位描述如下。当TXE被置1,那么就可以在TDR写入下一个数据了。即发送下一个数据。

        3. 发送移位寄存器在发送器控制的控制下,向右移位,一位一位的把数据传输到TX引脚。

        4. 数据移位完成后,新的数据就会再次从TDR转移到发送移位寄存器里来,依次重复1-3的过程。通过读取TXE标志位来判断是否发送下一个数据。

串口助手数据模式:

        ·HEX模式/十六进制模式/二进制模式:以原始数据的形式显示

        ·文本模式/字符模式:以原始数据编码后的的形式显示

   \r\n 的效果是将光标移回当前行的开头,然后移动到下一行,这样下一行打印的内容就会从新的一行开始。

printf函数的移植方法

一、(printf只能有一个,重定向到串口1,串口2就没有用了)

        打开工程选项,把Use MicrLIB勾上

f3524467d9d84926bfbbf20eb6884085.png        fputc是printf函数的底层,printf打印的时候就是调用fputc一个个打印

二、多个串口想用printf—— 使用sprintf可以指定打印的位置

三、封装sprintf

        添加头文件#include <stdarg.h>

2b053c1cc68b4775a6c4d08cfbcbe774.png

没学过,不知道,会移植就行

UTF8中文不乱码的方法:

       1. 打开工程选项,C\C++,杂项控制栏写上--no-multibyte-chars

        2.串口助手编码方式要选UTF8

P28        USART数据包

        1ca045b2e5ce4250956c2f1b55dff3ad.png

优点:传输最直接,解析数据非常简单

03ba30a6f1144567b8bc10cb7881f1de.png优点:数据直观易理解,灵活

1a54fa729782492d9439aa337093d896.pngd543e1fee47a4240a25484a3332b32df.png

P29        串口收发HEX数据包&串口收发文本数据包

P30        FlyMcu串口&STLINK Utility

P31        I2C通信协议

基本结构:

7067d1d05b624d64a3716cf045a637ad.png6d24fa52dfc643319f10c791c049774e.png

        ·一个I2C总线只使用两条总线线路,一条双向串行数据线(SDA) , 一条串行时钟线 (SCL)。数据线即用来表示数据,时钟线用于数据收发同步

         ·处于空闲状态,时钟线和数据线都处于高电平状态,谁要放数据谁就掌握SCL(拉低SCL),然后改变SDA ,处于接收的设备需释放SDA发数据SCL低电平,读数据SCL高电平

        ·每个连接到总线的设备都有一个独立的地址, 主机可以利用这个地址进行不同设备之间的访问

        ·发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答。
        ·接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)(谁接收信息谁就要发应答位)

I2C时序基本单元:

58ec9b7e077d40ada0d16615b063ce2c.png68df65418be041db8962908668b72b52.png

I2C时序:

b497d22714f645a2ba7ca88492c7c196.pngc87e9120ecd647a78d49a18782d72426.png

        起始条件:指SCL高电平时,SDA从高电平切换到低电平。在I2C总线处于空闲状态时,SCL和SDA都处于高电平状态。当主机需要数据收发时,会首先产生一个起始条件——SCL保持高电平,然后把SDA拉低,产生一个下降沿。当从机捕获到这个SCL高电平,SDA下降沿信号时,就会进行自身的复位,等待主机的召唤。之后,主机需要将SCL拉低。这样做一方面是占用这个总线,另一方面也是为了方便这些基本单元的拼接。这样,除了起始和终止条件,每个时序单元的SCL都是以低电平开始,低电平结束。

        终止条件:SCL高电平期间,SDA从低电平切换到高电平。SCL先放开并回弹到高电平,SDA再放开并回弹高电平,产生一个上升沿。这个上升沿触发终止条件,同时终止条件之后,SCL和SDA都是高电平,回归到最初的平静状态。这个起始条件和终止条件就类似串口时序里的起始位和停止位。一个完整的数据帧总是以起始条件开始、终止条件结束。另外,起始和终止都是由主机产生的。因此,从机必须始终保持双手放开,不允许主动跳出来去碰总线。如果允许从机这样做,那么就会变成多主机模型,不在本节的讨论范围之内。这就是起始条件和终止条件的含义。

I2C的从机设备

        12C的完整时序,主要有指定地址写,当前地址读和指定地址读这3种。主机可以访问总线上的任何一个设备,我们需要为每个从设备分配一个唯一的设备地址。这些地址就像是每个设备的名字,主机通过发送这些地址来确定要与哪个设备通信(每个I2C设备在出厂时都会被分配一个7位的地址。例如,MPU6050的7位地址是1101 000,而AT24C02的7位地址是1010 000。不同型号的芯片地址是不同的,但相同型号的芯片地址是相同的。)

I2C的读写

        ·指定地址写:

        ·当前地址读:

        ·指定地址读:=指定地址写 + 当前地址读

P32        MPU6050简介

P33        软件I2C读取MPU6050

程序整体框架:

P34        I2C通信协议

P35        硬件I2C读写MPU6050

P36        SPI通信协议

SS ( Slave Select):从设备选择信号线,常称为片选信号线

SCK (Serial Clock):时钟信号线

MOSI (Master Output, Slave Input):主设备输出/从设备输入引脚。主机的数据从这条信号线输出, 从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。

MISO (Master Input,,Slave Output):主设备输入/从设备输出引脚。主机从这条信号线读入数据, 从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。

d73bd9937c4c4017b5dda19ab5957b6e.png

P37             W25Q64简介

c44fa9b621f84a4db47955e1600b25f7.png

P38        软件SPI读取W25Q64

P39        SPI通信外设

P40        硬件SPI读取W25Q64

P41        Unix时间戳

### 关于STM32的学习笔记与教程 #### STM32的特点及其适合初学者的原因 STM32具备诸多优点,在初学者阶段几乎能满足大部分需求。网络上丰富的开源资源进一步促进了自学者的成长和发展[^1]。 #### STM32的基础架构介绍 STM32基于ARM Cortex-M系列微控制器,具有高效的处理能力和低功耗特性。具体而言: - **内核**:采用32位Cortex-M4 CPU,能够达到最高168 MHz的工作频率,并且每兆赫兹仅消耗约230微安电流; - **特殊功能**:支持浮点运算以及数字信号处理器(DSP)指令集扩展,这使得杂算法实现更加简便高效[^3]; #### 开始学习STM32的方法论 对于想要深入理解并掌握STM32开发的人来说,可以从以下几个方面入手: - 阅读官方文档和技术手册来了解硬件细节和软件框架; - 利用在线平台上的免费课程视频进行理论知识补充; - 参加社区论坛交流经验技巧,解决遇到的实际问题; - 动手实践项目构建个人作品库积累实战经历。 ```python # 示例代码展示如何初始化GPIO端口配置(伪代码) def setup_gpio(): # 初始化GPIOA端口时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 # 设置PA0引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP # 推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz # 输出速度设置为50MHz GPIO_Init(GPIOA, &GPIO_InitStructure) # 应用上述参数完成初始化操作 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值