GPIO:
STM32的(64引脚的)IO口一共有3个,分别是PA、PB、PC.
STM32的IO端口可以由软件配置成8种模式:
1,输入浮空
2,输入上拉
3,输入下拉
4,模拟输入
5,开漏输出
6,推挽输出
7,推挽复用功能
8,开漏复用功能
STM32的每个IO端口都有7个寄存器来控制。他们分别是:配置模式的2个32位的端口配置寄存器CRL和CRH;2个32位的数据寄存器IDR和ODR;1个32位的置位/复位寄存器BSRR;一个16位的复位寄存器BRR;1个32位的锁存寄存器LCKR;我们常用的IO端口寄存器只有4个:CRL、CRH、IDR、ODR。
注意(在配置STM32外设的时候,任何时候都要先使能该外设的时钟!APB2ENR是APB2总线上的外设时钟使能寄存器)
1.CRL和CRH寄存器-->控制IO口输出还是输入。
STM32的CRL控制着每个IO端口(A~G)的低8位的模式(例如PA0-PA7)。每个IO端口的位占用CRL的4个位,高两位为CNF,低两位为MODE。这里我们可以记住几个常用的配置,比如0X4表示模拟输入模式(ADC用)、0X3表示推挽输出模式(做输出口用,50M速率)、0X8表示上/下拉输入模式(做输入口用)、0XB表示复用输出(使用IO口的第二功能,50M速率)。
STM32的CRH控制着每个IO端口(A~G)的高8位的模式(例如PA8-PA15)。每个IO端口的位占用CRH的4个位,高两位为CNF,低两位为MODE。
2.IDR寄存器和ODR寄存器--》读取引脚输入的内容(是高电平还是低电平)以及控制你输出的内容(是高电平还是低电平)
IDR是一个端口输入数据寄存器,只用了低16位。该寄存器为只读寄存器,并且只能以16位的形式读出。读出的值为对应IO口的状态。
ODR是一个端口输出数据寄存器,也只用了低16位。该寄存器虽然为可读写,但是从该寄存器读出来的数据都是0。只有写是有效的。其作用就是控制端口的输出。
3. BSRR 端口位设置/清除寄存器和BRR端口复位寄存器
BSRR这个寄存器我用了一些,别的也不会。就感觉超级好用。用起来很方便。比如你端口配置好了。想PA5输出“1”。就GPIOA->BSRR |=(1<<5);5是对应的哦。输出“0”,一样的。
GPIO->BSRR |=(1<<(5+16));为什么加16,你明白的。
而BRR与BSRR操作一样。
使用ODR操作PC端口,由于主程序和中断同时有对IO口的操作(主程序设置PC3,中断设置PC6),使用的是ODR进行设置,这样的话会出现意想不到的情况。在线调试观察GPIO寄存器的值二者都是对的,实际输出不正确。如果不用ODR,全部改用BRR和BSRR来实现IO口的设置,则不会出现这个问题,一切正确。
参考手册说明BRR和BSRR的时候,发现有几句话(在GPIO那一章里):
“每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这样,在读和更改访问之间产生IRQ时不会发生危险。”
“当对GPIOx_ODR的个别位编程时,软件不需要禁止中断:在单次APB2写操作里,可以只更改一个或多个位。这是通过对“置位/复位寄存器”(GPIOx_BSRR,复位是 GPIOx_BRR)中想要更改的位写’1’来实现的。没被选择的位将不被更改。”
最终结论就是如果中断中要对IO口设置,最好使用BSRR和BRR操作,而不要用ODR.
关键字:STM32 GPIO
引用地址:
STM32学习之GPIO详解
推荐阅读最新更新时间:2024-03-16 16:17
stm32之TIM-高级定时器应用实例一(详细)
硬件:stm32f103c8t6 开发工具:Keil uVision4 下载调试工具:ARM仿真器 如果第一次接触定时器,可以先看基本定时器。本篇内容较多,如果想直接动手操作,可以跳到后面的实验代码。 stm32标准库对定时器外设建立了4个初始化结构体,定时器分为基本定时器、通用定时器、高级定时器,针对不用的定时器要使用不同初始化结构体。下面是4个初始化结构体的适用分类: TIM_TimeBaseInitTypeDef (基本定时器、通用定时器、高级定时器) TIM_OCInitTypeDef (通用定时器、高级定时器) TIM_ICInitTypeDef (通用定时器、高级定时器
[单片机]
IAR FOR STM8 学习笔记 固件库 GPIO
经过一番挣扎,还是决定使用官方的固件库了。。 从网上下一个STM8S的固件库,记得是FOR IAR的。 找到里面的IAR模板就可以开始用了。 这些都是直接写好的库函数,可以直接调用,但首先得先读懂,先了解些必备知识。 STM8的寄存器的地址 在STM8中,与某个外围设备有关的寄存器在地址上都是顺序排列的;比如与GPIO有关的寄存器有ODR、IDR、DDR、CR1、CR2,与PA口有关的这五个寄存器就被安排在了0x00 5000~0x00 5004这5个地址空间中,它们有一个0x005000的基地址,分别偏移0,1,2,3,4。 ”stm8s.h 中与GPIO有关的定义,以及固件库中访问外围设备寄存器的方法
[单片机]
基于STM32的MDK程序启动
;//HeapSize(inBytes) 0x0-0xFFFFFFFF:8 ;// Heap_SizeEQU0x00000020;//定义堆空间大小 AREAHEAP,NOINIT,READWRITE,ALIGN=3;//定义一个数据段,8字节对齐 __heap_base Heap_MemSPACEHeap_Size;//保留Heap_Size的堆空间 __heap_limit;//标号,代表堆末尾地址,后面有用 PRESERVE8;//指示编译器8字节对齐 THUMB;//指示编译器为THUMB指令 ;VectorTableMappedtoAddress0atReset AREARESET,DATA,READONLY;//
[单片机]
STM32初学笔记3之外部中断
学习的第三部分,我选择了外部中断,因为个人觉得除了时序问题,我们应用的最多的就要数中断了,当然还有一个定时器还没学,呵呵,只能往后放一下了。当然,我不打算花太多时间去搞GPIO,所以就自己看了一下手册,能用就行了。 反正学习这些东西还是根据个人的习惯吧,我学习主要也就是参考ST给的示例程序,反正还是很有用的。今天花了差不多两个小时的时间根据EXTI的示例程序自己编写了一个程序,最后在ALIENTEK上面运行成功,下面将示例代码展示如下: 笔者将跟硬件平台有关的配置放在一个板级支持包的源文件里面,具体请查看: 板级支持包的应用 一文。 一、GPIO的配置 二、嵌入向量中断控制器配置 三、中断服务程序 说
[单片机]
STM32输出比较模式输出不动频率的脉冲
//以下为TIM配置程序 void TIM1_PWM_INIT(void) //TIM1配置PWM输出参数 { u32 temp_fre,temp_duty; TempC = 60; //设置频率初始值 TempD = 4; //设置初始占空比1 / 2 temp_fre = (1000000 / TempC) - 1; temp_duty = ((temp_fre + 1) / TempD); TIM_TimeBaseStructure.TIM_Prescaler = 72; TIM_TimeBaseStructure.TIM_CounterMode
[单片机]
stm32跑马灯——寄存器和位操作
寄存器版: GPIO基础: 每组io口有7个寄存器。也就是7个寄存器,一共可以控制一组GPIO的16个IO口。 硬件连接: 例如: 由上图1可知:要使用到LED0和LED1,他们的IO口分别为PB5和PE5 由上图2可知:要使用到LED0和LED1,他们的IO口分别为PA8和PD2 GPIO的输出模式为推挽输出。 代码: 使能IO口时钟:配置寄存器RCC APB2ENR. 初始化IO口模式:配置寄存器GPIOx CRH/CRL 操作IO口,输出高低电平:配置寄存器GPIOX_ODR或者BSRR/BRR. 这里采用上图1的的原理图: led.h: #ifndef __LED_H //避免重复引用 #d
[单片机]
聊聊一个STM32中断处理问题
先看一段代码: while(1) { if(EXTI_Sign==1) { HAL_Delay(Period); HAL_NVIC_EnableIRQ(EXTI2_3_IRQn); HAL_NVIC_EnableIRQ(EXTI2_3_IRQn); EXTI_Sign=0; 。。。。。。 } } 有人使用STM32G0系列的芯片开发产品,有段功能测试验证代码如上所示,相同的函数必须调用2次才能正常运行,调用2次倒也罢了,关键是必须!颇为纳闷。 这里开启了PA3的外部中断功能,上下沿均可触发。PA3接收外来报警信号,类似于烟感报警器。报警信号是一串脉冲信号,报警信号过来时存在多次
[单片机]
SPI接口说明及原理
1简介 SPI:Serial Peripheral Interface,是串行外设接口。 SPI是由摩托罗拉于 1985 年前后开发,是一种适用于短距离、设备到设备通信的同步串行接口。 从那时起,这种接口就已成为许多半导体制造商,特别是微控制器(MCU)和微处理器(MPU)采用的事实标准。 2SPI接口 SPI总线是一种4线总线,通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以。 MOSI:Master Output Slave Input,主设备数据输出,从设备数据输入; MISO:Master Input Slave Output,主设备数据输入,从设备数据输出; SCLK:Serial Clock,时
[单片机]