STM开发方式
基于寄存器--->程序员直接配置寄存器
基于标准库--->利用ST官方封装好的库函数
基于HAL库--->图形化界面
我目前主要学习基于标准库的,STM32库是由ST公司针对STM32提供的函数接口,即API(Application Program Interface),开发者可调用这些函数接口来配置STM32的寄存器,使开发人员得以脱离最底层的寄存器操作,有开发快速、易于阅读、维护成本低等优点。
51单片机:
在51单片机的程序开发中,我们直接配置51单片机的寄存器,控制芯片的工作方式,如中断、定时器等。配置的时候,我们常常要查阅寄存器表,看用到哪些配置位,为了配置某功能该置1还是置0。
CMSIS标准
以ST公司生产的STM32的Cortex-M3内核为例,内核是整个微控制器的CPU。该内核是ARM公司设计的一个处理器体系架构,ARM公司并不生产芯片,而是出售其芯片技术授权。ST公司或其他芯片生产厂商如TI,负责设计的是在内核之外的部件,被称为核外外设或片上外设、设备外设。如芯片内部的模数转换外设ADC、串口UART、定时器TIM等。内核与外设,类似PC上的CPU与主板、内存、显卡、硬盘的关系。
因为基于Cortex的某系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异,这些差异却导致软件在同内核、不同外设的芯片上移植困难。为了解决不同芯片厂商生产的Cortex微控制器软件的兼容性问题,ARM与芯片厂商建立了CMSIS标准(Cortex Microcontroller Software Interface Standard)。
CMSIS标准中最主要的是CMSIS核心层,它包括:内核函数层:其中包含用于访问内核寄存器的名称、地址定义,主要由ARM公司提供。
设备外设访问层:提供了片上的核外外设的地址和中断定义,主要由芯片生产商提供。可见CMSIS层位于硬件层与操作系统或用户层之间,提供了与芯片生产商无关的硬件抽象层,可以为接口外设、实时操作系统提供简单的处理器软件接口,屏蔽了硬件差异,这对软件的移植有极大的好处。STM32固件库就是按照CMSIS标准建立的。
点亮一个灯需要配置的东西
1开启时钟
注意 3.5版本的库在启动文件中调用了SystemInit(),所以不必在main()函数中再次调用。但如果 使用的是3.0版本的库则必须在main函数中调用SystemInit(),以设置系统时钟,因为在3.0版本的 启动代码中并没有调用SystemInit()函数。
2初始化结构体——GPIO_InitTypeDef类型
GPIO_Pin;/*指定将要进行配置的GPIO引脚*/
GPIO_Speed;/*指定GPIO引脚可输出的最高频率*/
GPIO_Mode;/*指定GPIO引脚将要配置成的工作状态
3初始化库函数——GPIO_Init()
这个函数有两个输入参数,分别为GPIO_TypeDef和GPIO_InitTypeDef型的指针,
其允许值为GPIOA……GPIOG和GPIO_InitTypeDef型指针变量。
抢占优先级和响应优先级
STM32的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高。抢占,是指打断其他中断的属性,即因为具有这个属性会出现嵌套中断(在执行中断服务函数A的过程中被中断B打断,执行完中断服务函数B再继续执行中断服务函数A),抢占属性由NVIC_IRQChannelPreemptionPriority的参数配置。而响应属性则应用在抢占属性相同的情况下,当两个中断向量的抢占优先级相同时,如果两个中断同时到达,则先处理响应优先级高的中断,响应属性由NVIC_IRQChannelSubPriority参数配置。
AFIO时钟
AFIO(alternate-function I/O),指GPIO端口的复用功能,GPIO除了用作普通的输入输出(主功能),还可以作为片上外设的复用输入输出,如串口、ADC,这些就是复用功能。大多数GPIO都有一个默认复用功能,有的GPIO还有重映射功能。重映射功能是指把原来属于A引脚的默认复用功能,转移到B引脚进行使用,前提是B引脚具有这个重映射功能。当把GPIO用作EXTI外部中断或使用重映射功能的时候,必须开启AFIO时钟,而在使用默认复用功能的时候,就不必开启AFIO时钟了。
NVIC的优先级组
在配置优先级的时候,还要注意一个很重要的问题,即中断种类的数量。NVIC只可以配置16种中断向量的优先级,也就是说,抢占优先级和响应优先级的数量由一个4位的数字来决定,把这个4位数字的位数分配成抢占优先级部分和响应优先级部分。有5组分配方式:
第0组:所有4位用来配置响应优先级。即16种中断向量具有都不相同的响应优先级。
第1组:最高1位用来配置抢占优先级,低3位用来配置响应优先级。表示有21=2种级别的抢占优先级(0级,1级),有23=8种响应优先级,即在16种中断向量之中,有8种中断,其抢占优先级都为0级,而它们的响应优先级分别为0~7,其余8种中断向量的抢占优先级则都为1级,响应优先级分别为0~7。
第2组:2位用来配置抢占优先级,2位用来配置响应优先级。即22=4种抢占优先级,22=4种响应优先级。
第3组:高3位用来配置抢占优先级,最低1位用来配置响应优先级。即有8种抢占优先级,2种响应优先级。
第4组:所有4位用来配置抢占优先级,即NVIC配置的24=16种中断向量都是只有抢占属性,没有响应属性。
要配置这些优先级组,可以采用库函数
NVIC_PriorityGroupConfig(),可输入的参数为NVIC_PriorityGroup_0~NVIC_PriorityGroup_4,分别为以上介绍的5
种分配组。
STM2单片机的所有I/O端口都可以配置为EXTI中断模式,用来捕捉外部信号,可以配置为下降沿中断、上升沿中断和上升下降沿中断这三种模式。它们以如图7-2所示方式连接到16个外部中断/事件线上。
EXTI外部中断
STM32的所有GPIO都引入到EXTI外部中断线上,使得所有的GPIO都能作为外部中断的输入源。
比如:PA0~PG0连接到EXTI0、PA1~PG1连接到EXTI1、……、PA15~PG15连接到EXTI15。这里大家要注意的是:PAx~PGx端口的中断事件都连接到了EXTIx,即同一时刻EXTIx只能响应一个端口的事件触发,不能够同一时间响应所有GPIO端口的事件,但可以分时复用。它可以配置为上升沿触发、下降沿触发或双边沿触发。EXTI最普通的应用就是接上一个按键,设置为下降沿触发,用中断来检测按键。
EXTI之按键中断实验
#include "stm32f10x.h" // Device header
uint16_t CountSensor_Count;
void CountSensor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line14;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_Init(&EXTI_InitStructure);//调用EXTI_Init()把EXTI初始化结构体的参数写入寄存器
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);//调用NVIC_Init()函数来向寄存器写入参数
}
uint16_t CountSensor_Get(void)
{
return CountSensor_Count;
}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line14)==SET) //检查是否产生了中断
{
CountSensor_Count++;
EXTI_ClearITPendingBit(EXTI_Line14); //清除中断标志位再退出中断服务函数
}
}
GPIO工作原理
STM32引脚说明
GPIO是通用输入/输出端口的简称,是STM32可控制的引脚。GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。
STM32F103ZET6芯片为144脚芯片,包括7个通用目的的输入/输出口(GPIO)组,分别为GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF、GPIOG,同时每组GPIO口组有16个GPIO口。通常简略称为PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15。
STM32的大部分引脚除了当GPIO使用之外,还可以复用位外设功能引脚(比如串口),这部分在【STM32】STM32端口复用和重映射(AFIO辅助功能时钟) 中有详细的介绍。
GPIO基本结构
每个GPIO内部都有这样的一个电路结构,这个结构在本文下面会具体介绍。
保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入。当引脚电压高于VDD时,上方的二极管导通;当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。但是尽管如此,还是不能直接外接大功率器件,须加大功率及隔离电路驱动,防止烧坏芯片或者外接器件无法正常工作。
P-MOS管和N-MOS管:由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式。这里的电路会在下面很详细地分析到。
TTL肖特基触发器:信号经过触发器后,模拟信号转化为0和1的数字信号。但是,当GPIO引脚作为ADC采集电压的输入通道时,用其“模拟输入”功能,此时信号不再经过触发器进行TTL电平转换。ADC外设要采集到的原始的模拟信号。
这里需要注意的是,在查看《STM32中文参考手册V10》中的GPIO的表格时,会看到有“FT”一列,这代表着这个GPIO口时兼容3.3V和5V的;如果没有标注“FT”,就代表着不兼容5V。
STM32的GPIO工作方式
GPIO支持4种输入模式(浮空输入、上拉输入、下拉输入、模拟输入)和4种输出模式(开漏输出、开漏复用输出、推挽输出、推挽复用输出)。同时,GPIO还支持三种最大翻转速度(2MHz、10MHz、50MHz)。
每个I/O口可以自由编程,但I/O口寄存器必须按32位字被访问。
GPIO_Mode_AIN 模拟输入
GPIO_Mode_IN_FLOATING 浮空输入
GPIO_Mode_IPD 下拉输入
GPIO_Mode_IPU 上拉输入
GPIO_Mode_Out_OD 开漏输出
GPIO_Mode_Out_PP 推挽输出
GPIO_Mode_AF_OD 复用开漏输出
GPIO_Mode_AF_PP 复用推挽输出
GPIO八种工作模式
浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。也就是说,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。
上拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在高电平;并且在I/O端口输入为低电平的时候,输入端的电平也还是低电平。
下拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在低电平;并且在I/O端口输入为高电平的时候,输入端的电平也还是高电平。
模拟输入模式下,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等等。
开漏输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。这里要注意N-MOS管,当设置输出的值为高电平的时候,N-MOS管处于关闭状态,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定;当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,I/O端口的电平不一定是输出的电平。
开漏复用输出模式,与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。
推挽输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。这里要注意P-MOS管和N-MOS管,当设置输出的值为高电平的时候,P-MOS管处于开启状态,N-MOS管处于关闭状态,此时I/O端口的电平就由P-MOS管决定:高电平;当设置输出的值为低电平的时候,P-MOS管处于关闭状态,N-MOS管处于开启状态,此时I/O端口的电平就由N-MOS管决定:低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,此时I/O端口的电平一定是输出的电平。
推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。
标签:优先级,端口,模式,NVIC,八种,GPIO,输入,EXTI
From: https://www.cnblogs.com/zhangyu520/p/17722151.html