stm32的学习(江科协)

系统结构:
在这里插入图片描述

Flash是掉电还能保存数据,就像硬盘一样,而SRAM掉电失去数据,用作内存,通过AHB总线分成APB2 和 APB1时钟总线 APB2速度高一点,挂载比较高级的外设
**stm32 的启动过程:**
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/38cb9a27cc1349e291ecee9f44212f22.png)

```c
Reset_Handler PROC
这一行声明了一个名为Reset_Handler的过程。这是处理器在复位事件后执行的入口点。

EXPORT Reset_Handler [WEAK]
这一行将Reset_Handler导出,使其可以被其他模块引用,并且标记为弱符号。这意味着如果其他模块提供了Reset_Handler的定义,那么会覆盖这个弱定义;如果没有其他定义,则使用这个弱定义。

IMPORT __main
这一行声明了一个外部符号__main,告诉汇编器__main是在其他地方定义的,需要被导入以供使用。

IMPORT SystemInit
这一行声明了一个外部符号SystemInit,通常是由系统初始化代码(如启动代码或硬件抽象层)提供的函数。

LDR R0, =SystemInit
这一行将SystemInit函数的地址加载到寄存器R0中。LDR指令用于将立即值(在这里是一个地址)加载到寄存器中。

BLX R0
这一指令跳转到R0寄存器中保存的地址(即SystemInit函数的地址),并且链接(将返回地址保存到链接寄存器中)。BLX指令执行带链接的跳转,并且根据需要更改处理器状态(从ARM状态到Thumb状态或反之)。

LDR R0, =__main
这一行将__main函数的地址加载到寄存器R0中。

BX R0
这一指令跳转到R0寄存器中保存的地址(即__main函数的地址)。BX指令执行跳转,并根据需要更改处理器状态。

ENDP
这一行标记了Reset_Handler过程的结束。
```
关于system_init() 就是配置了时钟寄存器,关闭时钟中断,设置中断向量表地址(向量表的起始地址是根据你选择启动的方式,微控制器会从这个地址读取中断向量表,以确定各个中断和异常的处理程序。但是跟下面那个不一样)
[stm32启动流程](https://blog.csdn.net/weixin_52959840/article/details/128649750?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522172446711216800182744828%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=172446711216800182744828&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-128649750-null-null.142%5Ev100%5Epc_search_result_base1&utm_term=SCB-%3EVTOR%20=%20FLASH_BASE%20%7C%20VECT_TAB_OFFSET;&spm=1018.2226.3001.4187)
[_main  main](https://blog.csdn.net/u013318019/article/details/136995428?ops_request_misc=&request_id=&biz_id=102&utm_term=%E6%A0%87%E5%87%86%E5%BA%93_main%28%29%E5%9C%A8%E5%93%AA&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-136995428.142%5Ev100%5Epc_search_result_base1&spm=1018.2226.3001.4187)
```c
void SystemInit (void)

//函数声明,定义了 SystemInit 函数,返回类型为 void,无参数。
RCC->CR |= (uint32_t)0x00000001;

//设置 RCC (Reset and Clock Control) 寄存器中的 HSION 位,启用内部高速振荡器 (HSI)。
#ifndef STM32F10X_CL

//条件编译指令,根据不同的 STM32 系列芯片来选择编译不同的代码。
RCC->CFGR &= (uint32_t)0xF8FF0000;

//清除 RCC 配置寄存器中的 SW、HPRE、PPRE1、PPRE2、ADCPRE 和 MCO 位,重置这些配置为默认状态。
#else

//如果定义了 STM32F10X_CL,执行以下代码。
RCC->CFGR &= (uint32_t)0xF0FF0000;

//对于 STM32F10X_CL 型号,清除 RCC 配置寄存器中的不同位。
#endif /* STM32F10X_CL */
RCC->CIR = 0x009F0000;

//清除 RCC 中的所有中断,并设置寄存器 CIR 以禁用所有时钟中断。
SetSysClock();

//调用 SetSysClock 函数配置系统时钟频率及其预分频器。
#ifdef VECT_TAB_SRAM

//如果定义了 VECT_TAB_SRAM,执行以下代码。
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;

//设置中断向量表的基地址为 SRAM,并设置偏移量。
#else

//否则,执行以下代码。
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;

//设置中断向量表的基地址为 FLASH,并设置偏移量。
#endif

//条件编译结束。

```

通过startup.s保存了reset_handle(复位中断)

GPIO
在这里插入图片描述
vdd是3.3vss是0v,最右侧的保护二极管是为当I/O引脚输入过高或过低时,会击穿保护二极管,使输入电压降低,从而保护内部的GPIO
在这里插入图片描述这一部分是可以通过程序配置成上拉输入,下拉输入,浮空输入,通过控制开关,作用是为了给输入提供一个默认电平,上拉是高电平,下拉是低电平,浮空是不确定的,在这里插入图片描述
施密特触发器是对电压进行整形,模拟输入是接ADC的,需要没有整形过的电压,复用功能输入,是给别的外设需要读取数据的
在这里插入图片描述

输出部分
在这里插入图片描述
以往对寄存器进行某一位的操作,需要将寄存器数据读取出来,然后与或者或,GPIO口可以通过设置未设置(清除)寄存器来实现对一位进行操作。

	GPIO_SetBits(GPIOC,GPIO_Pin_13);
	GPIO_ResetBits(GPIOC,GPIO_Pin_13);

ps:这个寄存器是针对GPIO的,通常包含16个引脚,不是一个引脚对应一个寄存器

PMOS 是给输出提高高电平,NMOS是给输出提供低电平,推挽模式下:PMOS 和 NMOS 都有效,1,0决定谁导通,既可以输出高电平,也可以输出低电平,开漏模式是PMOS无效,NMOS有效,此时为1,PMOS NMOS都无效,相当于高阻状态,输出相当于断开,可以外接5v高电平,实现5v输出。
在这里插入图片描述
具体可以看这个视频
问题:当GPIO的某个引脚被设置为输出模式,读取这个引脚的高低电平,此时是由谁决定的,是输入模式一直开着吗,能一直读取数据。
施密特触发输入被激活,弱上拉和下拉电阻被禁止,出现在I/O引脚上的数据在在每个APB2时钟被采样到输入数据寄存器,在开漏模式时,对输入数据寄存器的读即可得到I/O状态,在推挽模式时,对输入数据寄存器的读访问的得到最后一次写的值。
输入数据寄存器的读操作
在开漏模式下:

由于开漏模式时输出寄存器上的1使端口处于高阻态,输入数据寄存器的值反映了实际的I/O端口状态。读取输入数据寄存器将得到实际的电平状态(高或低)。
在推挽模式下:

推挽模式使得I/O端口能够输出高电平或低电平。在这种模式下,输入数据寄存器的读取并不反映实际的电平状态,而是返回上次写入的值。这是因为在推挽模式下,I/O端口的电平状态是由输出寄存器控制的,而不是端口本身的电平状态。因此,读取输入数据寄存器实际上是读取上次写入的值,而不是当前端口的电平
也就是推挽模式是可以确定的,但是开漏模式是不确定的,需要去读取输入数据寄存器

NVIC
抢占优先级和响应优先级
在这里插入图片描述
外部中断:
在这里插入图片描述
在这里插入图片描述
外部中断的配置:
配置AFIO确定是哪个GPIO来使用对应的中断线(就是每个gpio都有16根线,但是同时只能有一个gpio起作用)
在这里插入图片描述
配置EXTI,确定是上升沿还是下降沿是否屏蔽中断以及其他的一些作用
在这里插入图片描述
最后一个就是NVIC,使能中断并且配置好抢占优先级和响应优先级
在这里插入图片描述
TIM定时器中断
在这里插入图片描述
在这里插入图片描述
基本定时器
在这里插入图片描述
分频数=预分频器+1 自动重装载寄存器保存目标值
在这里插入图片描述
主模式触发DAC介绍: 就是定时器到达目标时间后,会产生中断UI和触发事件U(与中断无关),将U与DAC的触发电路相连,配置好定时器,就会自动触发DAC,无需CPU主动控制,不需要触发中断
在这里插入图片描述
上图带有阴影的都是带有缓冲寄存器,比如自动重装载寄存器,更改数据并不会立刻生效,只有等当前周期结束才会生效。下图就是为啥设置缓冲寄存器的原因。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这个主要注意的是,在计数过程中,更改PSC,输出的时钟周期并不会立刻更改,是等到当前这一轮的计数完成后才将预分配缓冲器的数更改,也就是说,分不分频是看预分配缓冲器的数。
在这里插入图片描述
因为计数器实在达到目标值的下一个周期溢出,所以需要ARR+1
时钟配置介绍

TIM 输出比较:
在这里插入图片描述
在这里插入图片描述
惯性系统就是没有电时不会立刻停止。
在这里插入图片描述
最左边是CNT和CCR的结果输出 CC1P决定极性是否反转,比如ref置高电平为正转,通过CC1P反转,就会反转
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
复用推挽输出:TIM输出比较的pwm波形是通过GPIO输出的,需要将gpio配置成复用推挽输出,来实现。
在这里插入图片描述
也可以采用重映射功能
在这里插入图片描述

查看数据手册来看看应该学则哪种重映射方式
但有个问题,你重映射的端口恰好是调试端口,就是GPIO的功能是调试端口,需要解除调试端口的功能。
在这里插入图片描述
通过这样解除。
在这里插入图片描述
我记得当时我驱动pwm,直接定时器中断,进中断置为1,出中断置为0.

TIM输入捕获
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
PWMI模式
可以看到ch1的输入可以通过TI1FP1输入给比较1寄存器,也可以通过TI1FP2输入给比较2寄存器
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
TI1FP1使用主从触发模式,会直接将CNT计数器清零。
在这里插入图片描述
在这里插入图片描述
上面那个对应下面
在这里插入图片描述
编码器接口:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ADC模数转换模块:
在这里插入图片描述
在这里插入图片描述
逐次逼近型ADC的工作原理:
最左侧是输入通道选择,通过地址译码和锁存来选择对哪一路通道进行模数转换,逐次逼近就是二分查找,正好对应从高位到低位开始置1,

在这里插入图片描述
在这里插入图片描述

转换模式: 单次转换和连续转换,扫描模式和非扫描模式
单次转换:是指开启ADC以后会一直进行模数转换
扫描模式:开启后会扫描多个通道

DMA
在这里插入图片描述
在这里插入图片描述
传输计数器是向下计数。

串口通信
在这里插入图片描述
USART和UART的区别:既可以有UART的功能,也可以多接一根时钟线来实现同步通信
UART和USART
异步通信需要双方约定好采样频率。
在这里插入图片描述

在这里插入图片描述
串口通信先发送低位数据。
在这里插入图片描述
TDR 和RDR在外表现是同一个DR,只不过一个是只写一个是只读,根据你的行为来决定具体是哪个寄存器。
在这里插入图片描述
在这里插入图片描述
如何确保你接受数据时,每次采集数据都在数据的正中间。
将波特率周期分为1/16,检测到下降沿后分析前七位,0多1少,认为开始接收数据,才是数据采样正好在周期的一半
在这里插入图片描述
IIC通信:
在这里插入图片描述
在这里插入图片描述
IIC有个设置,针对SDA,就是SDA有的时候是主机发送,有的时候是从机发送,可能会发生主机SDA置高电平,从机SCL置低电平,此时会发生短路,所以规定SDA和SCL配置成开漏输出模式,开漏输出模式,输出低电平是正常的,输出高电平相当于高阻态,这样高电平由外置弱上拉电阻产生。
在这里插入图片描述
串口是低位先性,I2C是高位先行。
在这里插入图片描述
IIC怎么传输数据: 在scl低电平时先将sda置成你想要发送的高低位,然后将scl置成高电平,从机就会读取数据,就是相当于scl高电平时,sda不允许发生数据的跳变,不然就是iic开始和停止命令了。
在这里插入图片描述
在这里插入图片描述
当前地址指针解释
就是他把从机的所有寄存器做成了一个线性的,每次写入一个数据,当前地址指针就会自动加1,这是需要注意的点。
读数据也是指针自动加1。
如何控制从机发送数据,主机接收到一个字节数据给应答信号,从机会继续发送,不给应答信号,从机会取消发送。

对于指定读或写是在设备地址之后加一个读写位,因为设备地址就7位,第八位用来指定主机读或者写的。

正确的操作顺序是关键。通常,I2C通信开始时,主设备会发送设备地址,接着发送要访问的寄存器地址,然后才是数据。如果顺序不正确,设备可能会误解主设备的意图(当然这也是看各个厂家的规定,这是MPU6050的规定)
在这里插入图片描述
在这里插入图片描述
硬件iic
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
SPI通信:
在这里插入图片描述
IIC是半双工 ,iic有速率限制(怎么来的速率限制,因为他是复用开漏输出,外置高电平的升压作用较慢,就相当于慢慢的拉高电平,如果频率过快,还没有拉到高电压就置低电平,此时通信就会出现问题)。
SPI就没有通信速率限制,取决于外挂芯片。
在这里插入图片描述
在这里插入图片描述
上面那条线为SPI 下面那条线为IIC,因为IIC是输入输出在一根线上,如果用的推挽输出,然后接收方也恰好输出低电平,此时电路直接短路。
在这里插入图片描述
移位寄存器的具体工作流程
他这个发送接收一定是同时发生的,你如果只想发送,就不需要管接受的数据就行。

在这里插入图片描述
模式0实在ss下降沿将数据放进去,然后sck上升沿读取,下降沿放入。
其实说是下降沿上升沿读取放入,只要在下一个边沿来临之前完成自己这个边沿的任务就行
比如下降沿放入,只要在上升沿之前放入就行
在这里插入图片描述
W25Q64
在这里插入图片描述
在这里插入图片描述
最小擦除单元:
最小是按扇区 4096个字节 4kb
一个块是64kb
一页是256Byte
最多写入一个页的数据是因为写入数据时,FLASH写入数据较慢,芯片会将数据存放在一个256字节的数据缓冲区,等这次spi时序过去后再将数据写入spi
还有在写的时候不能跨页写入,但能跨页读出
写之前必须擦除。
可以查看芯片是否处于忙状态通过BUSY寄存器
在这里插入图片描述

硬件SPI
在这里插入图片描述
SPI也是高位先行。
在这里插入图片描述
具体原理 数据先写入发送缓冲器,如果移位寄存器没有数据,立刻写入,然后发生交换,等交换完成后,将数据移到接收缓冲区,发送缓冲区的值继续给移位寄存器。

在这里插入图片描述
具体时序:
在这里插入图片描述
在这里插入图片描述
区别就是只有接收完数据时,才会将数据放入发送缓冲器,这样就会导致数据传输之间存在时间间隔
TXE 数据寄存器发送寄存器没有数据会置1
RXNE 接收缓冲寄存器有数据会置1

BKP备份寄存器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
灰色区域是后备区域,可以使用VBAT供电,PRL是重装载寄存器,DIV其实也是计数器,这个分频器的原理就是DIV记到多少数,产生一次脉冲,PRL再进行重装载。因为计数值包括0,所以写入多少数代表count+1分频。
ALR相当于闹钟,你设置一个数,当cnt记到该值时,会产生Alarm信号,此时可以用来退出待机模式。
在这里插入图片描述
在这里插入图片描述

RTC 与BKP的关系:
因为如果每次复位都要初始化rtc,这样就不能实现掉电rtc数据不丢失,用bkp的数据来判断,有数据就不需要初始化。

PWR电源控制:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以睡眠模式关闭的时钟是HCLK 下面的那个八分频的是systick,所以你关闭cpu时钟不会影响systick时钟。

在这里插入图片描述
在这里插入图片描述
这是一个问题:你最开始是HSE 72兆hz,你退出停止模式后HSI才8兆
在这里插入图片描述
睡眠模式和停止模式唤醒后都是接着运行,只有待机模式是从头运行。
看门狗:
在这里插入图片描述
窗口看门狗喂狗的事件在一个区间范围内,过早过晚都会触发重置。
在这里插入图片描述
虽然它也有重装载寄存器,但是必须在键寄存器的控制下才能重载,也就是喂狗操作,不像定时器会自动重装。
在这里插入图片描述
在这里插入图片描述
独立看门狗
在这里插入图片描述
先一步一步分析:
WDGA是一个标志位,启动看门狗就置1 ,然后呢CR寄存器的T6位,T6-T0 都是 1111111 减到 1000000 再减 变成01111111T6变成0,此时下面那一路就导通,相当于超时没有复位,所以说他的时间只有五位计数
上面那一路是当你写入CR寄存器时,就相当于喂狗操作时,会判断CR和CFR的值,如果CR>CFR上面那一路就会导通。
在这里插入图片描述
在这里插入图片描述
stm32的内部Flash闪存
在这里插入图片描述
在这里插入图片描述
启动程序代码就是BOOTloader
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值