当前位置: 首页> 科技> 能源 > 上海四大公关公司_100个万能营销方案_中国营销传播网_文娱热搜榜

上海四大公关公司_100个万能营销方案_中国营销传播网_文娱热搜榜

时间:2025/7/11 18:25:54来源:https://blog.csdn.net/2401_86645122/article/details/147227182 浏览次数:0次
上海四大公关公司_100个万能营销方案_中国营销传播网_文娱热搜榜

第1章 STM32概述

1.1 关于ARM内核

1.1.1 ARM含义:

1.ARM(高级精简指令集机器)是Advanced RISC Machine Limited公司的简称,主要设计RISC(复杂指令集)处理器。一个程序中80%的代码实现只用到计算机中20%的指令。这20%的机器指令能实现80%的功能。这20%的指令就是常用指令。
RISC:加速常用指令,不常用指令用常用指令组合。
CISC:复杂指令集,具有大量的指令和寻址方式。

2.一类微处理器芯片或产品的通称,即采用ARM公司提供方案的处理器。

1.1.2 ARM内核

ARM内核 包括了寄存器组、指令集、总线、存储器映射规则、中断逻辑和调试组件等。
内核是由ARM公司设计并以销售方式授权给个芯片厂商使用的(ARM公司本身不做芯片)。 比如为高速度设计的Cortex A8、A9都是ARMv7a 架构;Cortex M3、M4是ARMv7m架构;前者是处理器(就是内核),后者是指令集的架构(也简称架构)。

先有架构,再有内核,一个架构可以衍生出多种内核

内核就是MCU内部中最核心的逻辑处理部分,MCU的CPU。所以内核也可以叫做处理器。

1.2 什么是STM32

就是ST(意法半导体集团)公司设计的一系列以ARM Cortex-M为核心的32位微控制器。

1.3 MCU命名规范


1.4 STM32开发方式

1.直接基于寄存器开发
优点:执行效率高 对硬件理解深入 更换其他芯片上手快
缺点:开发效率低 代码移植不方便
2.基于标准库开发
优点:相比于寄存器开发效率高 开发难度低 开发移植容易
缺点:屏蔽一些硬件信息,不利于新手学习知识 官方停止标准库更新,新的芯片不提供标准库
3.基于HAL库开发
优点:ST主推,支持力度大 开发工具持续更新 开发难度大大降低 移植容易
缺点:屏蔽几乎所有硬件信息,不利于新手学习知识,只学习HAL,学完之后基础知识不牢固

1.5 STM32最小系统板

STM32单片机能工作的最小外围电路叫最小系统板
最小系统板通常包括:STM32芯片、电源、时钟、调试和复位5部分组成

二 创建工程 

2.1 创建工程准备 

1)创建需要的目录

2)准备启动文件
STM32 程序需要启动文件,我们需要提前准备好。先去ST官网下载官方提供的外设标 准库,里面有提供标准的启动文件
标准库下载地址:STSW-STM32054 - STM32F10x标准外设库 - 意法半导体STMicroelectronicshttps://www.st.com.cn/zh/embedded-software/stsw-stm32054.html
3)创建目录放入启动文件和其他核心文件 为了方便管理,我们把启动文件放入专门目录中。在刚才创建的工程目录中创建一个目录:Start
去到我们刚才下载的标准外设库目录,找到我们需要的启动文件和其他核心文件copy 到Start目录。

拷贝完之后 

4)创建工程 
选择所需的芯片


2.2 工程配置

1)添加两个Project Group方便管理代码文件 
先删除默认的Source Group 1,再添加两个:Start(启动相关的文件),User(我们自 己写的代码)。
2)创建main.c
3)include path

4)编译器版本改为5 目前最新的Keil ARM用的是 Compiler version 6,与前面的core_cm3.c不兼容,所以需 要提前准备好Compiler version 5。
下载地址:https://developer.arm.com/downloads/view/ACOMP5 解压之后,把解压的后文件夹放入到Keil MDK的安装目录下 

三 软件设计

3.1 点亮一个LED(基于寄存器)

我们只要让GPIOA的0口输出低电平就行了。代码需要按照 下面的步骤来实现。对于其中一些概念,大家先有个了解,后面的课程会细讲。
1)开启时钟
在STM32中,让IO口工作,必须先开启对应的时钟。所以需要先查找到开启时钟的 寄存器,然后通过该寄存器操作时钟的开启或关闭。我们要打开的是GPIOA的时钟。
我们需要知道RCC_APB2ENR这个寄存器的地址。如何查找呢?先知道RCC这个外设的基地址,然后加上这个寄存器的偏移地址就行了.
从上面可以看出来,RCC的基地址是0x4002 1000,APB2ENR的偏移量是0x18,所以 APB2ENR的地址值是0x4002 1000 + 0x18 有了地址,在这个地址写入一个数据,这个数据的二进制第2是1就行了。其他位暂时不管。我们写入4。这样就开启了GPIOA的时钟。
在代码中,我们需要把地址强转成指针才能给这个地址赋值。
*(uint32_t *)(0x40021000 + 0x18) = 4;

2)给IO口设置输出模式
在STM32中,如果要让IO口输出低电平或高电平,必须给要使用的IO设置为输出模式。
根据前面的思路,需要先找到GPIOA的基地址,再根据偏移地址找到要使用的寄存器的地址。GPIOA的基地址是0x4001 0800。
配置PA0口的输出模式的寄存器是GPIOA_CRL。
只需要让这个寄存器的最后4位是 0011,就是最大速度的推挽输出。
*(uint32_t *)(0x40010800 + 0x00) = 3;

3)给PA0口输出0
给指定PA0口输出0就可以点亮LED1了。用到的寄存器是ODR数据输出寄存器。

4)main.c

#include "stdint.h"
int main()
{//点亮一个LED(基于寄存器配置)//1.开启GPIO0的时钟*(uint32_t *)(0x40021000 + 0x18) = 4;             //0000 0004	​​​//2.给IO设置工作模式:输出*(uint32_t *)(0x40010800 + 0x00) = 3;//给对应的IO设置:1/0*(uint32_t *)((0x40010800 + 0x0c)) = 0xfffe;
}

3.2 编译工程

1)安装ST-LINK驱动
2)Keil中配置ST-LINK
3)下载程序

3.3 寄存器升级

3.3.1 进化1

在操作寄存器的时候,如果每次都查手册计算地址,是相当麻烦且无聊。ST公司早就 考虑到了这个问题,已经提前把每个外设寄存器的地址提前给我们用宏定义的方式给算好了, 我只需要直接使用即可。比如下面是定义的RCC各个寄存器地址。(stm32f10x.h中定义)

#define PERIPH_BASE           ((uint32_t)0x40000000) 
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)#define RCC_BASE              (AHBPERIPH_BASE + 0x1000)#define RCC                 ((RCC_TypeDef *) RCC_BASE)typedef struct{__IO uint32_t CR;__IO uint32_t CFGR;__IO uint32_t CIR;__IO uint32_t APB2RSTR;__IO uint32_t APB1RSTR;__IO uint32_t AHBENR;__IO uint32_t APB2ENR;__IO uint32_t APB1ENR;__IO uint32_t BDCR;__IO uint32_t CSR;} RCC_TypeDef;

这里还巧妙的运用了结构体中各个成员地址是连续的特征。CR寄存器是RCC第0个32 位寄存器,所以它相对于基地址的偏移是0。CFGR相对于基地址的偏移是4,… APB2ENR的相对于基地址的偏移是6*4=24=0x18,和我们前面查找手册的结果是一致的。

#include "stm32f10x.h"int main(void){RCC->APB2ENR = 4;GPIOA->CRL = 3;GPIOA->ODR = 0xfffe;while (1){}}

3.3.2 进化2(位操作)

其实在上面的代码中还有一些问题。在STM32中一个寄存器是32位的,我们在编写 代码的时候只是需要给某位或某几位赋值。由于STM32不支持位寻址,所以在前面的操作 中,我们其实是修改了所有位。这是非常不合理的,也许其他位在其他地方有赋值,我们重新赋值势必会覆盖了其他值,带来的后果也是很严重的。

#include "stm32f10x.h"int main(void){RCC->APB2ENR |= 4;GPIOA->CRL |= 1;GPIOA->CRL |= 2;GPIOA->CRL &= ~4;GPIOA->CRL &= ~8;GPIOA->ODR &= ~1;}

3.3.3 进化3(移位操作)

#include "stm32f10x.h"int main(void){/* 开启GPIOA的时钟 第2位置1*/RCC->APB2ENR |= 0x1 << 2;/* GPIOA_CRL的最后4位置 0011 */GPIOA->CRL &= ~(0x1 << 3);GPIOA->CRL &= ~(0x1 << 2);GPIOA->CRL |= 0x1 << 1;GPIOA->CRL |= 0x1 << 0/* GPIOA_ODR的第0位置0 */GPIOA->ODR &= ~(0x1 << 0);
}

3.3.4 进化4(使用定义好的移位后的操作)

在上次的进化中,我们是给寄存器“或等”和“与等”了一些值,这些值都是通过相应 的“移位”操作得到的。比如要操作第2位,就需要把0x1左移2位得到。我们需要查找手 册才能知道要移位几。也是很不方便。 其实ST公司也把我们需要的移位后的值给提前计算好了,用宏定义的方式供我们使用。 比如前面的开启时钟,已经定义了好了这个值。正好就是1<<2 #define RCC_APB2ENR_IOPAEN ((uint32_t)0x00000004) 利用ST公司提前预定义的这些值,可以进一步进化代码为下面的形式。

#include "stm32f10x.h"int main(void){RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;GPIOA->CRL &= ~GPIO_CRL_CNF0_1;GPIOA->CRL &= ~GPIO_CRL_CNF0_0;GPIOA->CRL |= GPIO_CRL_MODE0_1;GPIOA->CRL |= GPIO_CRL_MODE0_0;GPIOA->ODR &= ~GPIO_ODR_ODR0;}

四 GPIO外设

4.1 GPIO概述

GPIO(General-purpose input/output),通用型输入输出。简单理解就是我们可以控制输入输出的STM32引脚,统称为GPIO。
GPIO 存在的意义就是用程序控制或读取他们的输出或输入。

4.1.1 GPIO 总体说明

STM32 有多组GPIO,比如STM32F103ZET6共有7组GPIO端口, 他们分别是GPIOx(x从A-G),每组控制16个引脚,共有112个GPIO引脚。具体一个 其他STM32芯片有多少组GPIO,可以去查看他们的对应的数据手册。 每个引脚的电平是0-3.3V,部分引脚最高可以兼容到5V。

4.1.2 GPIO 的主要特点

(1)不同型号,IO口的数量可能不一样。
(2)快速翻转。最快可以达到每2个时钟周期翻转一次。(STM32F1系列最快可以 达到50MHz的翻转速度)。
(3)每个IO都可以作为外部中断。
(4)支持8种工作模式

4.1.3 GPIO 的 8 种工作模式

GPIO 端口的每个位(引脚)可以由软件分别配置成8种模式,当然对同一个引脚同一 时间只能处于某一种模式中。
(1)输入浮空(Input floating)
(2)输入上拉(Input pull-up)
(3)输入下拉(Input-pull-down)
(4)模拟输入(Analog)
(5)通用开漏输出(Output open-drain)
(6)通用推挽式输出(Output push-pull)
(7)推挽式复用功能(Alternate function push-pull)
(8)开漏复用功能(Alternate function open-drain)
每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问。
输出模式下可以控制端口输出高电平低电平,用于驱动LED,蜂鸣器等,如果是大功 率器件(比如电机),还需要加上驱动器(小电流控制大电流)。
输入模式下可以读取端口的高低电平,用于读取外接按键,外接模拟信号的输入,ADC 电压采集,模拟通信协议接受数据等。

4.2 GPIO 工作模式

4.2.1 GPIO 每位的具体电路结构

4.2.2 每种模式详解 

4.2.2.1 输出模式 

输出流程(设置输出的时候可以读引脚状态)
驱动0能力强(让外部电流直接灌入接地Vss)
驱动1能力弱(VDD驱动电流小)
(1)输出缓冲器被激活。
(2)推挽模式:输出寄存器上的 1 将激活P-MOS,输出高电平。0 将激活N MOS,输出低电平。推挽实际就是描述MOS管输出高低电平的一个动作 输入高电平VDD将电流推出去 输入低电平将外面的电流挽回至Vss
(3)开漏模式:PMOS永远关闭。 输出寄存器上的 0 激活N-MOS,而输出寄存器上的1 将端口置于高阻状态(浮空),所以外部必须要接上拉电阻。
开漏模式作用1:(如果直接输出5V可能会烧毁外部的芯片,所以需要通过上拉电阻。输出低电平时可以直接将N-MOS导通即可)

开漏模式作用2:支持几个GPIO控制一个输入(一个高电平一个低电平会直接导通,烧毁MOS管)

设置为开漏输出,只要有其中一个输出低电平则输出低电平,都关闭时,由上拉电阻输出高电平


(4)施密特触发输入被激活。
(5)弱上拉和下拉电阻被禁止。
(6)出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器。
(7)在开漏模式时,对输入数据寄存器的读访问可得到I/O状态。
(8)在推挽模式时,对输出数据寄存器的读访问得到最后一次写的值。
总结
推挽输出和开漏输出的选择
使用推挽
1.驱动能力需求高的场合
2.高速信号传输
3.无需共用信号线的场合
使用开漏
1.多个设备共用信号线
2.不同电压系统之间的接口
3.需要外部上拉电阻来确定逻辑高电平场合

4.2.2.2 复用输出模式

(1)在开漏或推挽式配置中,输出缓冲器被打开。
(2)内置外设的信号驱动输出缓冲器(复用功能输出)。
(3)施密特触发输入被激活。
(4)弱上拉和下拉电阻被禁止。
(5)在每个APB2时钟周期,出现在I/O脚上的数据被采样到输入数据寄存器。
(6)开漏模式时,读输入数据寄存器时可得到I/O口状态。
(7)在推挽模式时,读输出数据寄存器时可得到最后一次写的值。

4.2.2.3 输入模式

(1)2个保护二极管的作用是保护我们的芯片不会由于电压过高或过低而烧毁。 VDD是接电源(3.3V),VSS接地(0V)。如果IO引脚的输入电压高于VDD的值到 一定程度,上方保护二极管导通,则引脚电压被拉低到VDD。如果IO引脚的输入电压(负电压)低于VSS到一定程度,则下方保护二极管导通,电压被拉高到VSS。结点电压被嵌在Vss到Vdd之间。
(2)2个开关控制引脚没有输入的时候是上拉下拉还是浮空。当上面的开关闭合的时候,输入被拉高到高电平。当下面的开关闭合的时候,输入被拉低到低电平。如果两个都不闭合,输入就是悬空状态。两个同时闭合,就是费电了,不会这么做的。
(3)施密特(图中翻译成肖特基触发器应该是翻译错误,英文版手册是TTL Schmitt trigger)触发器是包含正反馈的比较器电路。可以对信号进行波形整形。
(4)从施密特触发起出来的数据,进入到输入数据寄存器中,我们就可以从中读取数据了。

 4.2.2.4 模拟输入模式

当配置为模拟输入时:
(1)输出部分被禁止。
(2)禁止施密特触发输入,实现了每个模拟I/O引脚上的零消耗。施密特触发输出值 被强置为0。 (3)弱上拉和下拉电阻被禁止。
(4)读取输入数据寄存器时数值永远为0。

4.3 与 GPIO 相关的7个寄存器

每个GPI/O端口有7个相关的:
2个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)。
2个32位数据寄存器(GPIOx_IDR和GPIOx_ODR)。
1个32位置位/复位寄存器(GPIOx_BSRR)。
1个16位复位寄存器(GPIOx_BRR)。
1个32位锁定寄存器(GPIOx_LCKR)

4.3.1 GPIOx_CRL(端口配置低寄存器

上拉/下拉需要格外配置ODR寄存器(PxODR=0:下拉 =1:上拉)

4.3.2 GPIOx_CRH(端口配置高寄存器)

GPIOx_CRH(Port configuration register high)。
该寄存器配置的是每个端口的 8-15引脚,配置方式和低位寄存器完全一样。

4.3.3 GPIOx_IDR(端口输入数据寄存器)

保留位始终读为0。剩下的分别对应每个引脚的输入值(只读)。 

4.3.4 GPIOx_ODR(端口输出数据寄存器)

4.3.5 GPIOx_BSRR(端口位设置/清除寄存器)

(1)高16位是用清除对应的数据输出寄存器的位(0-15)的值:设置为0不影响, 设置为1会清除ODR对应的位的值(置为0)。
(2)低16位是用设置对应的数据输出寄存器的位(0-15)的值:设置为0不影响, 设置为1会设置ODR对应的位的值(置为1)。

4.3.6 GPIOx_BRR(端口位清除寄存器)

这个寄存器具有了GPIOx_BSRR一半的功能:清除。 

4.3.7 GPIOx_LCKR(端口配置锁定寄存器) 

该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置。 每个锁定位锁定控制寄存器(CRL,CRH)中相应的4个位(CNF2位和MODE2位)。 第16位用来激活锁定寄存器,必须按照规定的时序来操作才行: 写1 -> 写0 -> 写1 -> 读0 -> 读1。 对0-15 位: 0:不锁定对应端口的配置。 1:锁定对应端口的配置 

五 总体架构和时钟系统

5.1 STM32总体架构

3个被动单元
内部SRAM:存储程序执行时用到的变量(相当于电脑的运存)
内部闪存存储器(Flash):1.存储下载的程序  2.程序执行时用到的常量
AHB(高速系统总线)到APBx(外设总线,APB2高速 APB1低速)的桥
    桥1,通过APB2总线连接到APB2上的外设。高速外设最高72MHz。
    桥2,通过APB1总线连接到APB1上的外设。高速外设最高36MHz。

4个驱动(主动)单元(主动的访问三个被动单元)
Cortex-M3内核DCode总线(D-BUS):通过外部的DCode总线连接到总线矩阵然后与闪存存储器的数据接口相连接,实现Flash常量加载和调试访问。
Cortex-M3内核系统总线(S-bus):通过外部System总线连接到总线矩阵
通用DMAx(Direct Memory Access):通过DMA总线,连接到总线矩阵。作用就是降低CPU负担,不通过CPU实现内存和外设之间的数据传输。

其他单元
Cortex-M3内核Icode总线:通过外部Icode总线连接到Flash,实现指令的读取。
FSMC(Flexible Static Memory Controller):用来扩展SRAM,Flash,连接LCD屏幕。

5.2 时钟系统

5.2.1 时钟树

在STM32中有3种不同的时钟源用来驱动系统时钟(SYSCLK):
(1)HSI振荡器时钟(High Speed Internal oscillator,高速内部时钟)
(2)HSE振荡器时钟(High Speed External(Oscillator / Clock),高速外部时钟)
(3)PLL时钟(Phase Locked Loop 锁相环/倍频器) 还有2种2级时钟:
(4)LSI时钟(Low Speed Internal,低速内部时钟)
(5)LSE时钟(Low Speed External oscillator,低速外部时钟)。
为什么提供这么多的时钟?节能!高速设备接高速时钟,低速设备接低速时钟,可以最 大程度的达到节能效果。详见下图时钟树

5.2.2 各个时钟介绍

1)HSE时钟
高速外部时钟是由外部时钟源提供,目前几乎所有的STM32单片机的设计都是在外部 接一个8MHz的晶振,经过PLL倍频(9倍频)后得到一个72MHz的系统时钟。我们系统 默认就是这个时钟。这个在启动文件可以看到。

2)HSI时钟
HSI 时钟信号由内部8MHz的RC振荡器产生,可直接作为系统时钟或在2分频后作为 PLL 输入。HSI RC振荡器能够在不需要任何外部器件的条件下提供系统时钟。它的启动时 间比HSE晶体振荡器短。然而,即使在校准之后它的时钟频率精度仍较差。

3)PLL时钟
内部PLL用来倍频HSI RC的输出时钟或HSE晶体输出时钟。PLL的设置必须在其被 激活前完成。一旦PLL被激活,这些参数就不能被改动。如果PLL中断在时钟中断寄存器 里被允许,当PLL准备就绪时,可产生中断申请。 PLL 时钟一般都是对外部的8MHz的时钟信号经过9倍频后,得到72MHz的时钟频率, 这是STM32F1系列允许的最高时钟频率

4)LSE时钟
LSE 晶体是一个32.768kHz的低速外部晶体或陶瓷谐振器。它为实时时钟或者其他定时 功能提供一个低功耗且精确的时钟源。 LSE 是不能驱动系统时钟的

5)LSI 时钟
LSI RC 担当一个低功耗时钟源的角色,它可以在停机和待机模式下保持运行,为独立 看门狗和自动唤醒单元提供时钟。LSI时钟频率大约40kHz(在30kHz和60kHz之间)。 LSI 也是不能驱动系统时钟的

六 HAL库入门

6.1 HAL 介绍

1)为什么要学习HAL库开发
到目前我们已经学会1种开发SMT32程序的姿势:基于寄存器开发。 寄存器开发效率比较低,在工作中如果想快速开发还是要会用到HAL库开发。 HAL库是目前ST主力推广的开发方式,所以你如果还要用ST的芯片,会使用HAL 库开发是势在必行的。而且最最关键的是,使用HAL开发有诸多的好处。 目前,HAL库已经支持STM32全线产品。
2)什么是HAL库
HAL库的全称是Hardware Abstraction Layer,翻译成硬件抽象层。HAL库是ST为STM32 最新推出的抽象层嵌入式软件,可以更好的确保跨STM32产品的最大可移植性。该库提供 了一整套一致的中间件组件,如RTOS,USB,TCP/IP和图形等。 HAL库是基于一个非限制性的BSD许可协议(Berkeley Software Distribution)而发布 的开源代码。 ST制作的中间件堆栈(USB主机和设备库,STemWin)带有允许轻松重用 的许可模式,只要是在ST公司的MCU 芯片上使用,库中的中间件(USB 主机/设备 库,STemWin)协议栈即被允许随便修改,并可以反复使用。至于基于其它著名的开源解决方 案商的中间件(FreeRTOS,FatFs,LwIP和PolarSSL)也都具有友好的用户许可条款。
3)CMSIS和HAL库的关系
CMSIS(Cortex Microcontroller Software Interface Standard)是 Cortex-M 处理器系列的 与供应商无关的硬件抽象层。它是ARM公司制定的一个标准。它可以为处理器和外设实现 一致且简单的软件接口,从而简化软件的重用、缩短微控制器新开发人员的学习过程,并缩 短新设备的上市时间。简单来说,就是ARM公司制定标准,芯片厂商按照此标准编写相应 的程序,实现统一的接口,方便开发人员的使用

关键字:上海四大公关公司_100个万能营销方案_中国营销传播网_文娱热搜榜

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: