当前位置: 首页 > article >正文

【STM32】F103ZET6开发板----笔记01

一、简述

1.1什么是STM32

STM32 是 STMicroelectronics(ST)的一系列 32 位微控制器,其基于 ARM架构 Cortex-M 系列的处理器内核设计。它们广泛应用于各种嵌入式系统,如物联网设备、汽车电子、工业自动化等领域。

ARM(Advanced RISC Machine)是一种低功耗、低成本、高性能的处理器架构。

“ST” 是指制造商 STMicroelectronics 的缩写。 “M” 表示其是基于 ARM 的 Cortex-M 系列核心。 “32” 则代表其为 32 位微控制器 (简称MCU)

STM32F103ZET6 ARM Cortex-M3系列(基础型, 主频: 72M(时钟的工作频率)), Z (144引脚), E (Flash 闪存 512K字节) , T( 封装性: LQFP), 6 (温度范围: -40 ~ 85)。

1.2 STM32最小系统

用最小的电路组成的可以工作的单片机叫做最小系统。

stm32f103zet6 最小系统有 5 部分组成(电源电路、时钟电路、boot 电路、下载/调试接口、复位电路)

电源供电: USB方式(USB, CH340 调试串口),最高5V电压

时钟电路: 内部时钟源(低速 LSI、高速 HSI)、外部时钟(低速 LSE 、高速 HSE)

boot 电路: 引导电路(BT1, BT0, 通过跳帽方式确定, 出厂默认即可)

下载/调试接口: ST下载器进行程序的下载(JTAG/SWD), CH340 USB串口调试

复位电路: RST按键

1.3固件库使用说明

对于MCU开发方式:汇编语言 C语言

stm32 单片机:(汇编+C语言)

实际开发编程过程中使用的方法:

  • 配置 MCU 中的某个功能模块的寄存器,进行操作

  • 使用 ST 官方提供的固件库驱动操作, 推荐使用 ST 官方提供了 STM32cubemx 软件,图形化配置与开发。

常用的固件库:

Standard Peripheral Library (SPL): ST Microelectronics 最初为其 STM32 微控制器系列发布的固件库。此库包含了一些方便的 C 函数,可以直接控制 STM32 的各种外设,通常称为标准库。

STM32Cube: ST Microelectronics 自 2015 年以来开始推广的一种新的固件库。
STM32Cube 包括一个嵌入式软件平台和一个独立的集成开发环境。嵌入式软件平台包括一个硬件抽象层(HAL),该层为 STM32 的各种外设提供通用的 API,并且还包含一些中间件组件(如 FreeRTOS,USB 库,TCP/IP 库等)。STM32Cube 的集成开发环境(STM32CubeIDE)则包含了代码生成器,它可以生成基于 STM32Cube HAL 的初始化代码。

LL (Low Layer) Drivers: LL 库是 STM32Cube 库的一部分,为高级用户提供了一个硬件抽象层的替代方案。LL 库提供了一组低级 API,可以让用户直接访问 STM32 外设的寄存器。这些 API 比 HAL 更加高效,但是需要更深入的硬件知识。

使用kill5和cubeMX软件

二、stm32启动

3.1系统架构

总线矩阵(Bus Matrix): 总线矩阵主要用于在多个主设备(如 CPU、DMA 等)和从设备(内存和外设)之间进行数据的路由和管理。通过 总线矩阵,主设备可以同时(并行)地访问从设备。

DMA 总线(DMA Bus): DMA,全称 Direct Memory Access,是一种让某些硬件子系统在内存和外设之间直接传输数据,而无需处理器参与的技术。在 STM32 中,DMA 总线主要用于 DMA 控制器和内存以及需要使用 DMA 服务的外设(如 USART、SPI、ADC 等)之间的数据传输。

ICode 总线(ICode Bus/IBus): ICode 总线是一个专门用于 CPU 从 Flash 内存中取指令的总线。这条总线专门优化了指令的取得,以提高 CPU 的 性能。专门用于从 Flash 内存或者其他指令存储器中获取指令,支持 CPU 以最优化的方式取指。该总线用于把指 令从存储器传输到处理器核心,以便执行,主要面向读操作。

DCode 总线(DCode Bus/DBus): DCode 总线是一个专门用于 CPU 访问数据的总线,可以从 Flash 内存或系统内存中读取数据。用于 CPU 核心的数据访问,包括对 Flash 内存和 RAM 的读写。使数据可以并行地(与指令访问操作并行)从存储器中读取或写入。

3.2存储器的架构

闪存:512KB 主存SRAM

程序存储器、数据存储器、寄存器和输入输出端口(外设)被组织在同一个 4GB 的线性地址空间内。可访问的存储器空间被分成 8 个主要块,每个块为 512MB。

3.3 stm32启动方式

跳帽:

BOOT0/BOOT1: 0 启动方式从 Flash 中启动

3.4启动文件过程

从汇编主程序开始中的复位处理(上电之后或按RST键进行的处理过程):

选择 SystemInit 系统初始化, 再调用 __main函数执行核心应用程序。

SystemInit 的主要目的是进行系统级别的初始化,包括配置内部硬件和设置系统的运行环境。

__main函数:

负责完成初始化 C 环境、设置堆栈、清零全局和静态变量等,并最终调用用户定义的 main 函数

四、stm32 系统时钟

4.1 系统时钟的时钟源

三种不同的时钟源可被用来驱动系统时钟(SYSCLK): HSI 振荡器时钟(高速系统内部时钟)、 HSE 振荡器 时钟(高速系统外部时钟)和 PLL 时钟(锁相环时钟)。

以上三种时钟都有以下 2 种二级时钟源:

  1. 40kHz 低速内部 RC (LSI),可以用于驱动独立看门狗和通过程序选择驱动 RTC。RTC 用于从停机/待机模式下自动唤醒系统。

  2. 32.768kHz 低速外部晶体也可用来通过程序选择驱动 RTC(RTC CLK)。

当不被使用时,任一个时钟源都可被独立地启动或关闭,由此优化系统功耗。

PLL 是 Phase-Locked Loop(相位锁定环)的简称,是一种控制系统的结构,常用于电子通信设备中。在微控制器和嵌入式系统中,PLL 被用作时钟系统的一部分,能够生成频率比输入时钟(通常是内部的低速时钟或者外部的 晶体振荡器提供的时钟)更高的时钟信号。

五、stm32 通用输入输出

STM32 Pin引脚 144个

通用输入输出 : GPIO(112个) , 分为A, B, C,D, E, F, G 七个组, 每一个组分16个索引。如GPIOE5 -> PE5

5.1 GPIO 框图

保护二极管: IO 引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入,当引脚电压高于 VDD_FT 时,上方的二极 管导通,当引脚电压低于 VSS 时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。

上拉、下拉电阻: 控制引脚默认状态的电压,开启上拉的时候引脚默认电压为高电平,开启下拉的时候引脚默认电压为低电平。

TTL 施密特/肖特基触发器: 基本原理是当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;IO 口信号经过 触发器后,模拟信号转化为 0 和 1 的数字信号。

P-MOS 管和 N-MOS 管: 信号由 P-MOS 管和 N-MOS 管,依据两个 MOS 管的工作方式,使得 GPIO 具有“推挽输出”和“开漏输出”的模 式。P-MOS 管高电平导通,低电平关闭; N-MOS 低电平导通,高电平关闭。

5.2 GPIO 的八种工作模式

输入四种: 浮空输入, 上拉输入、下拉输入, 模拟输入

输出四种: 推挽输出、开漏输出、复用推挽输出、复用开漏输出

5.2.1 浮空输入 GPIO_MODE_IN_FLOATING

浮空输入模式下,I/O 端口的电平信号直接进入输入数据寄存器。MCU 直接读取 I/O 口电平,I/O 的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的,低功耗。

5.2.2 上拉输入 GPIO_MODE_IPU(In Pull Up)

IO 内部接上拉电阻,此时如果 IO 口外部没有信号输入或者引脚悬空,IO 口默认为高电平。 如果 I/O 口输入低电平,那么引脚就为低电平,MCU 读取到的就是低电平。

应用场景:钳位电平、增强驱动能力、抗干扰。可以用来检测外部信号;例如按键等

5.2.3 下拉输入 GPIO_Mode_IPD(In Pull Down)

IO 内部接下拉电阻,此时如果 IO 口外部没有信号输入或者引脚悬空,IO 口默认为低电平 如果 I/O 口输入高电平,那么引脚就为高电平,MCU 读取到的就是高电平,可以用来检测外部信号; 例如按键等;

5.2.4 模拟输入 GPIO_MODE_AIN(Analog Input)

当 GPIO 引脚用于 ADC 采集电压的输入通道时,用作"模拟输入"功能,此时信号不经过施密特触发器,直接进入 ADC 模块,并且输入数据寄存器为空 ,CPU 不能在输入数据寄存器上读到引脚状态。 当 GPIO 用于模拟功能时,引脚的上、下拉电阻是不起作用的,这个时候即使配置了上拉或下拉模式,也不会影响 到模拟信号的输入输出。 除了 ADC 和 DAC 要将 IO 配置为模拟通道之外其他外设功能一律要配置为复用功能模式,应用 ADC 模拟输 入,或者低功耗下省电。

5.2.5 推挽输出 GPIO_Mode_Out_PP(out push—pull)

在推挽输出模式时,N-MOS 管和 P-MOS 管都工作,如果我们控制输出为 0,低电平,则 P-MOS 管关闭,N-MOS管导通,使输出低电平,I/O 端口的电平就是低电平,若控制输出为 1 高电平,则 P-MOS 管导通 N-MOS 管关闭,输出高电平,I/O 端口的电平就是高电平,外部上拉和下拉的作用是控制在没有输出时 IO 口电平,此时施密特触发器是打开的,即输入可用,通过输入数据寄存器 GPIOx_IDR 可读取 I/O 的实际状态。I/O 口的电平一定是输出的电平,一般应用在输出电平为 0 和 3.3 伏而且需要高速切换开关状态的场合。

5.2.6 开漏输出 GPIO_Mode_Out_OD(out open drain)

在开漏输出模式时,只有 N-MOS 管工作,如果我们控制输出为 0,低电平,则 P-MOS 管关闭,N-MOS 管导通, 使输出低电平,I/O 端口的电平就是低电平,若控制输出为 1 时,高电平,则 P-MOS 管和 N-MOS 管都关闭,输出指令就不会起到作用,此时 I/O 端口的电平就不会由输出的高电平决定,而是由 I/O 端口外部的上拉或者下拉决定。 如果没有上拉或者下拉 IO 口就处于悬空状态。并且此时施密特触发器是打开的,即输入可用,通过输入数据寄存器 GPIOx_IDR 可读取 I/O 的实际状态。I/O 口的电平不一定是输出的电平。一般应用在 I2C、SMBUS 通讯等需要"线与"功能的总线电路中。

5.2.7 复用推挽输出 GPIO_AF_PP(alternate function open push—pull)

GPIO 复用为其他外设(如 I2C),输出数据寄存器 GPIOx_ODR 无效;输出的高低电平的来源于其它外设,施密特 触发器打开,输入可用,通过输入数据寄存器可获取 I/O 实际状态,除了输出信号的来源改变,其他与推挽输出功 能相同。应用于片内外设功能(I2C 的 SCL,SDA)等

5.2.8 复用开漏输出 GPIO_AF_OD(alternate function open drain)

GPIO 复用为其他外设,输出数据寄存器 GPIOx_ODR 无效;输出的高低电平的来源于其它外设,施密特触发器打 开,输入可用,通过输入数据寄存器可获取 I/O 实际状态,除了输出信号的来源改变 其他与开漏输出功能相同。 应用于片内外设功能(TX1,MOSI,MISO.SCK.SS)等。

六、NVIC 中断

6.1 NVIC 介绍

NVIC(Nest Vector Interrupt Controller)嵌套中断向量控制器,作用是管理中断嵌套,核心任务是管理中断优先级。

特点:

  1. 68 个可屏蔽中断通道(不包含 16 个 Cortex-M3 的中断线)

  2. 16 个可编程的优先等级(使用了二进制 4 位中断优先级)

  3. 低延迟的异常和中断处理

  4. 电源管理控制

  5. 系统控制寄存器的实现

NVIC 给每个中断赋予抢占优先级和响应(子)优先级

关系如下:

  1. 拥有较高抢占优先级的中断可以打断抢占优先级较低的中断

  2. 若两个抢占优先级的中断同时挂起,则优先执行响应优先级较高的中断

  3. 若两个挂起的中断优先级都一致,则优先执行位于中断向量表中位置较高的中断

  4. 响应优先级不会造成中断嵌套,也就是说中断嵌套是由抢占优先级决定的

6.2 HAL中断API

void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
void HAL_NVIC_SetPriority(IRQn_Type IRQn,
uint32_t PreemptPriority,
uint32_t SubPriority);

HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_x);
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_x);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);

处理中断函数,需要自己依据中断线定义:

void 中断线_IRQHandler(void){ }

在main()函数下方定义即可。

6.2 示例
示例1: 按键点灯

GPIO配置:

static void MX_GPIO_Init(void)
{
 ?GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
?
 ?/* GPIO Ports Clock Enable */
 ?__HAL_RCC_GPIOE_CLK_ENABLE(); ?//D1 PE5,  PE3按键 Key1
?
 ?/*Configure GPIO pin Output Level */
 ?HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET); ?// 0
?
?
 ?/*Configure GPIO pin : PE5 */
 ?GPIO_InitStruct.Pin = GPIO_PIN_5;
 ?GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; ?// 推挽输出 P-MOS/N-MOS
 ?GPIO_InitStruct.Pull = GPIO_NOPULL;
 ?GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; ?// GPIO_SPEED_FREQ_LOW == MODE: 10  10MHz
 ?HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
?
?
    
    /* 配置GPIO pin: PE3 Key1 */
    GPIO_InitStruct.Pin = GPIO_PIN_3;
 ?GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
 ?GPIO_InitStruct.Pull = GPIO_NOPULL;
 ?GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 ?HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
?
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

main函数的设置中断优先级和开启中断

/* Configure the system clock */
 ?SystemClock_Config();
 ?/* USER CODE BEGIN SysInit */
 ?/* USER CODE END SysInit */
 ?/* Initialize all configured peripherals */
 ?MX_GPIO_Init();
 ?/* USER CODE BEGIN 2 */
 ? ?// 1. 设置中断的优先级 
    HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
    // 2. 开启中断
    HAL_NVIC_EnableIRQ(EXTI3_IRQn);
 ?/* USER CODE END 2 */

中断处理函数:

// 3. 定义中断处理程序
void EXTI3_IRQHandler(void){
 ?// 1) 定义变量 用于统计按下产生的中断次数
 ?static int n=0;
    // 2) 获取PE3中断状态: SET 1, RESET 0
    if( __HAL_GPIO_EXTI_GET_IT(GPIO_PIN_3) != GPIO_PIN_RESET){
        n++;
        // 3) 防止抖动
        //if( __HAL_GPIO_EXTI_GET_IT(GPIO_PIN_3) != GPIO_PIN_RESET && n >= 5){
         ? ?// 4) 处理中断产生的效果 PE5灯亮/灭
            if( HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_5) == GPIO_PIN_RESET){
                 HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);
            }else{
                 HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET);
            }
            
            n = 0;
        //}
        __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_3); // 清除中断状态
    }
    
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); ?// 继续请求GPIO E3的中断处理
}
示例2: 按键控制蜂鸣器

在示例1的基本之上, 将PF0使能并初始化,在main函数的while循环中:

// 2. 开启中断
    HAL_NVIC_EnableIRQ(EXTI3_IRQn);
 ?/* USER CODE END 2 */
 ?/* Infinite loop */
 ?/* USER CODE BEGIN WHILE */
 ?while (1)
  {
        // 当灯亮时,Beep响起来
 ? ?while( !HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_5) ){
         ? HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_RESET);
             HAL_Delay(2);
             HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_SET);
             HAL_Delay(2);
        }
 ? ?/* USER CODE BEGIN 3 */
  }

http://www.kler.cn/a/453008.html

相关文章:

  • Apache Doris 创始人:何为“现代化”的数据仓库?
  • 论文阅读 - 《Large Language Models Are Zero-Shot Time Series Forecasters》
  • 理解并使用 Linux 内核的字符设备
  • 【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
  • 【机器学习(九)】分类和回归任务-多层感知机(Multilayer Perceptron,MLP)算法-Sentosa_DSML社区版 (1)111
  • 16_HTML5 语义元素 --[HTML5 API 学习之旅]
  • 图像修复和编辑大一统 | 腾讯北大等联合提出BrushEdit:BrushNet进阶版来了
  • mysql的备份和还原
  • java 核心知识点——JVM
  • 时间轮在 Netty , Kafka 中的设计与实现
  • 云原生后端开发(一)
  • 数字逻辑(六)——下载Digital软件
  • 计算机视觉目标检测-1
  • ffmpeg: stream_loop报错 Error while filtering: Operation not permitted
  • 互联网视频云平台EasyDSS无人机推流直播技术如何助力野生动植物保护工作?
  • 榆能横山煤电厂及周边建筑物爆破振动和位移自动化监测
  • vue调试工具 Vue.jsDevtools
  • 第十六届“蓝桥杯”全国软件和信息技术专业人才大赛简介及资料大全
  • DevOps实战:用Kubernetes和Argo打造自动化CI/CD流程(2)
  • 设计模式从入门到精通之(二)抽象工厂模式
  • 方正畅享全媒体新闻采编系统screen存在SQL注入漏洞
  • 漏洞检测工具:Swagger UI敏感信息泄露
  • java日志框架:slf4j、jul(java.util.logging)、 log4j、 logback
  • Spire.PDF for .NET【页面设置】演示:重新排列 PDF 中的页面
  • git - 忽略文件权限变化的检查
  • uniapp 基于xgplayer(西瓜视频) + renderjs开发,实现APP视频播放