请问GPIO的默认电平在哪儿?是参考手册的复位电平吗? - STM32 - 意法半导体STM32/STM8技术社区
后使用快捷导航没有帐号?
查看: 5238|回复: 6
请问GPIO的默认电平在哪儿?是参考手册的复位电平吗?
在线时间81 小时
该用户从未签到主题帖子精华
高级会员, 积分 819, 距离下一级还需 181 积分
LED& &配置了上拉&&,配置完默认是亮的
KEY上面那个wakeup配置了下拉,另外三个配置上拉,
为什么这么配置啊,反过来配置行不
网上查了一下,
上拉表示引脚内部接了一个电阻,然后接高电平
所以灯亮了
可是我给LED配置下拉也会默认亮的,
我查到资料说GPIO有默认电平。。。
请问一下,应该怎么解释呢?
QQ图片13.jpg (12.33 KB, 下载次数: 0)
22:43 上传
            
      
在线时间43 小时
该用户从未签到主题帖子精华
高级会员, 积分 609, 距离下一级还需 391 积分
STM32关键初始化后默认是低电平。其次,你回去好好复习下电路基础知识。你图上的LED要点亮还是熄灭,只是跟你LED0标号的地方是高电平还是低电平决定的。
在线时间286 小时
ST金币2882
该用户从未签到主题帖子精华
金牌会员, 积分 4786, 距离下一级还需 214 积分
MCU在复位后GPIO的状态一般为高阻态,电平高低由外部电路决定
在对GPIO初始化后其状态即确定
            
      
在线时间81 小时
该用户从未签到主题帖子精华
高级会员, 积分 819, 距离下一级还需 181 积分
MCU在复位后GPIO的状态一般为高阻态,电平高低由外部电路决定
在对GPIO初始化后其状态即确定 ...
谢谢回复,我是跨行业的,之前没接触过电路,只是会C,
请问一下,我发的图是否可以看出来?
在线时间862 小时
ST金币2344
该用户从未签到主题帖子精华
配置完后,将IO设置书输出高。
            
      
在线时间5 小时
该用户从未签到主题帖子精华
初级会员, 积分 99, 距离下一级还需 101 积分
默认初始化的电平为0
在线时间3 小时
该用户从未签到主题帖子精华
初级会员, 积分 65, 距离下一级还需 135 积分
复位默认低电平吧
            
      
STM32粉丝勋章Ⅳ
狂欢节专属(智多星)
STM32粉丝勋章Ⅱ
狂欢节专属(研讨会问答)
站长推荐 /2
Tel: 3-8064
备案号: 苏ICP备号-2
|||意法半导体STM32/STM8技术社区
Powered bySTM32学习笔记之GPIO口的使用
STM32 Cotex-M3 GPIO口简介与配置
一、GPIO口简介
GPIO口输入输出模式&
1.1 一般来说STM32的输入输出管脚有以下8种配置方式:
浮空输入_IN_FLOATING&&&&——浮空输入,可以做KEY识别
带上拉输入_IPU&&&&&&&&&
——IO内部上拉电阻输入&&
带下拉输入_IPD&&&&&&&&&
——IO内部下拉电阻输入
模拟输入_AIN&&&&&&&&&&&
——应用ADC模拟输入,或者低功耗下省电
开漏输出_OUT_OD&&&&&
&&&——IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。
&&&&&&&&&&&&&&&&&&&&&&&&&&
当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO
&&&&&&&&&&&&&&&&&&&&&&&&&&&口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的
&&&&&&&&&&&&&&&&&&&&&&&&&&
IO双向功能。
⑥ 推挽输出_OUT_PP
&&&&&&——IO输出0-接GND,
IO输出1 -接VCC,读输入值是未知的。
&& 复用输出
⑦ 复用功能的推挽输出_AF_PP
&&——片内外设功能(I2C的SCL,SDA)
⑧ 复用功能的开漏输出_AF_OD&
——片内外设功能(TX1,MOSI,MISO,SCK,SS)
2、输入输出模式详解
一般我们平时用的最多的也就是推挽输出、开漏输出、上拉输入,介绍如下:
2.1推挽输出:
&&&&&&&&&&&&&&&&&&&
可以输出高,低电平,连接数字器件;
推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由IC的电源低定。
推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。
2.2开漏输出:
&& 输出端相当于三极管的集电极。
要得到高电平状态需要上拉电阻才行。 适合于做电流型的驱动,其吸收电流的能力相对强(一般20mA以内)
开漏形式的电路有以下几个特点:
利用外部电路的驱动能力,减少IC内部的驱动。当IC内部MOSFET导通时,驱动电流是从外部的VCC流经R pull-up
,MOSFET到GND。IC内部仅需很小的栅极驱动电流。
一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。(上拉电阻的阻值决定了逻辑电平转换的沿的速度
。阻值越大,速度越低功耗越小,所以负载电阻的选择要兼顾功耗和速度。)
OPEN-DRAIN提供了灵活的输出方式,但是也有其弱点,就是带来上升沿的延时。因为上升沿是通过外接上拉无源电阻对负载充电,所以当电阻选择小时延时就小,但功耗大;反之延时大功耗小。所以如果对延时有要求,则建议用下降沿输出。
4、可以将多个开漏输出的Pin,连接到一条线上。通过一只上拉电阻,在不增加任何器件的情况下,形成“与逻辑”关系。这也是I2C,SMBus等总线判断总线占用状态的原理。
补充:什么是“线与”?:
在一个结点(线)上, 连接一个上拉电阻到电源 VCC 或 VDD 和 n 个 NPN 或 NMOS
晶体管的集电极 C 或漏极 D, 这些晶体管的发射极 E 或源极 S 都接到地线上, 只要有一个晶体管饱和,
这个结点(线)就被拉到地线电平上。 因为这些晶体管的基极注入电流(NPN)或栅极加上高电平(NMOS), 晶体管就会饱和,
所以这些基极或栅极对这个结点(线)的关系是或非 NOR 逻辑。 如果这个结点后面加一个反相器, 就是或 OR 逻辑。
其实可以简单的理解为:在所有引脚连在一起时,外接一上拉电阻,如果有一个引脚输出为逻辑0,相当于接地,与之并联的回路“相当于被一根导线短路”,所以外电路逻辑电平便为0,只有都为高电平时,与的结果才为逻辑1。
2.3浮空输入 :对于浮空输入,一直没找到很权威的解释,只好从以下图中去理解了。
2.4& 上拉输入/下拉输入/模拟输入:这几个概念很好理解,从字面便能轻易读懂。
复用开漏输出、复用推挽输出:可以理解为GPIO口被用作第二功能时的配置情况(即并非作为通用IO口使用)
二、GPIO口配置
1、根据具体应用配置为输入或输出
① 作为普通GPIO输入:
根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时不要使能该引脚对应的所有复用功能模块。
② 作为普通GPIO输出:
根据需要配置该引脚为推挽输出或开漏输出,同时不要使能该引脚对应的所有复用功能模块。
③ 作为普通模拟输入:
配置该引脚为模拟输入模式,同时不要使能该引脚对应的所有复用功能模块。
④ 作为内置外设的输入:
根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时使能该引脚对应的某个复用功能模块。
⑤ 作为内置外设的输出:
根据需要配置该引脚为复用推挽输出或复用开漏输出,同时使能该引脚对应的所有复用功能模块。
2、输出模式下,配置速度
I/O口输出模式下,有3种输出速度可选(2MHz、10MHz和50MHz),这个速度是指I/O口驱动电路的响应速度而不是输出信号的速度,输出信号的速度与程序有关(芯片内部在I/O口的输出部分安排了多个响应速度不同的输出驱动电路,用户可以根据自己的需要选择合适的驱动电路)。通过选择速度来选择不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。高频的驱动电路,噪声也高,当不需要高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI性能。当然如果要输出较高频率的信号,但却选用了较低频率的驱动模块,很可能会得到失真的输出信号。关键是GPIO的引脚速度跟应用匹配。
2.1&&&&&对于串口,假如最大波特率只需115.2k,那么用2M的GPIO的引脚速就够
了,既省电也噪声小。
2.2&&&&对于I2C接口,假如使用400k波特率,若想把余量留大些,那么用2M的
GPIO的引脚速度或许不够,这时可以选用10M的GPIO引脚速度。
对于SPI接口,假如使用18M或9M波特率,用10M的GPIO的引脚速度显然不够了,需要选用50M的GPIO的引脚速度。
3、GPIO口初始化
①使能GPIO口的时钟 ②配置模式设置(8种模式)
&&&
STM32的GPIO的时钟统一挂接在APB2上,具体的使能寄存器为RCC_APB2ENR该寄存器的第2位到第8位分别控制GPIOx(x=A,B,C,D,E,F,G)端口的时钟使能。
如打开PORTA时钟&
RCC-&APB2ENR|=1&&2;&&&
//使能PORTA时钟
如果把端口配置成复用输出功能,则还需开始复用端口时钟,并进行相应配置。
4、GPIO配置寄存器
GPIO口配置是通过配置寄存器来进行的,每个GPIO 端口有:
两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)分别控制每个端口的高八位和低八位。如果IO口是0-7号的话,则写CRL寄存器;如果IO口是8-15号的话,则写CRH寄存器。
两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR)一个是只读作输入数据寄存器,一个是只写作输出寄存器。
一个32位置位/复位寄存器(GPIOx_BSRR)。
一个16位复位寄存器(GPIOx_BRR)。
一个32位锁定寄存器(GPIOx_LCKR)。
常用的IO端口寄存器只有四个:CRH,CRL,IDR,ODR。
&数据手册中列出的每个I/O端口的特定硬件特征。
GPIO端口的每个位可以由软件分别配置成多种模式。每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)。
另外,STM32的每个端口使用前都要将其时钟使能,STM32的GPIO的时钟统一挂接在APB2上,具体的使能寄存器为RCC_APB2ENR,该寄存器的第2位到第8位分别控制GPIOx(x=A,B,C,D,E,F,G)端口的时钟使能,当外设时钟没有启用时,程序不能读出外设寄存器的数值,如打开PORTA时钟:&
RCC-&APB2ENR|=1&&2;&&&
//使能PORTA时钟
总结一下GPIO功能:
1、通用I/O(GPIO):最基本的功能,可以驱动LED、可以产生PWM、可以驱动蜂鸣器等等;
2、单独的位设置或位清除:方便软体作业,程序简单。端口配置好以后只需GPIO_SetBits(GPIOx,
GPIO_Pin_x)就可以实现对GPIOx的pinx位为高电平;
3、所有端口都有外部中断能力:端口必须配置成输入模式,所有端口都有外部中断能力;
4、复用功能(AF):复用功能的端口兼有IO功能等。复位期间和刚复位后,复用功能未开启,I/O
端口被配置成浮空输入模式。
5、 软件重新映射I/O复用功能:为了使不同器件封装的外设I/O
功能的数量达到最优,可以把一些复用功能重新映射到其他一些脚上。这可以通过软件配置相应的寄存器来完成。这时,复用功能就不再映射到它们的原始引脚上了。
GPIO锁定机制:当在一个端口位上执行了所定(LOCK)程序,在下一次复位之前,将不能再更改端口位的配置。
5、GPIO寄存器详解
参见《STM32F10X中文手册》
三、GPIO输出实验
这里利用ST固件库,就不需要自己对照配置寄存器写代码,直接利用库函数,非常方便。
4个LED接在GPIOF管脚6、7、8、9,为推挽输出
#include "stm32f10x.h"
#include "led.h"
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
void Delay(u32 d_time);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
int main(void)
LED_Init();&&&&&
&&&&&&&&&&&&&&&&&
GPIO_SetBits(GPIOF,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);
&&&&&&&&&&&&&&&&&
Delay(3000000);
&&&&&&&&&&&&&&&&&
GPIO_ResetBits(GPIOF,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);
&&&&&&&&&&&&&&&&&
Delay(3000000);
void Delay(u32 d_time)
for(;d_time&0;d_time--);
#ifndef __LED_H
#define __LED_H&&
void LED_Init(void);
&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#include "led.h"
//LED IO初始化
void LED_Init(void)
GPIO_InitTypeDef &GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_ResetBits(GPIOF,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。你的浏览器禁用了JavaScript, 请开启后刷新浏览器获得更好的体验!
问题已解决,果然还是要屎劲的看文档啊!!
stm32F407的hal库中定时器tim的从模式:复位模式,
以下问题的解决办法是加入下面一句话:
__HAL_TIM_URS_ENABLE(&htim3);
这句话的意思是将TIMx_CR1寄存器里的URS位置位,
TIMx_CR1寄存器里的URS位可以选择update event的触发源。0就是所有相关源,1就是仅限于溢出。
相关函数的说明如下:
Set the Update Request Source (URS) bit of the TIMx_CR1 register
__HANDLE__: TIM handle.
When the USR bit of the TIMx_CR1 register is set, only counter
overflow/underflow generates an update interrupt or DMA request (if
* @retval None
#define __HAL_TIM_URS_ENABLE(__HANDLE__) \
((__HANDLE__)-&Instance-&CR1|= (TIM_CR1_URS))
当然有使能就有失能函数
Reset the Update Request Source (URS) bit of the TIMx_CR1 register
__HANDLE__: TIM handle.
When the USR bit of the TIMx_CR1 register is reset, any of the
following events generate an update interrupt or DMA request (if
– Counter overflow/underflow
– Setting the UG bit
– Update generation through the slave mode controller
* @retval None
#define __HAL_TIM_URS_DISABLE(__HANDLE__) \
((__HANDLE__)-&Instance-&CR1&=~(TIM_CR1_URS))
使用的时候这样用:
MX_TIM3_Init();
__HAL_TIM_URS_ENABLE(&htim3);
HAL_TIM_Base_Start_IT(&htim3);
RESET模式应该怎么配置,我配置了下,然后程序中
使用了一个IO口作为输出一个高低电平的脉冲,间隔时间为100ms
定时器我设置跟新时间是1s
我的想法是将这个IO电平连接到定时器的触发源端口,设置上升沿触发,导致RESET定时器
我在HAL_TIM_PeriodElapsedCallback函数中开启一个IO口指示led灯
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_6);
如果led以1s的状态闪烁了,则说明定时器UPdate了
当我接到IO脉冲口的时候,按道理上来应该是100ms产生了一个上升沿导致定时器一直复位,不会产生更新事件,即,不会导致led亮
但是,实际的情况是:
连接好电路后,led不停的以100ms闪烁,
我理解是定时器确实复位了,但是同时导致了UPdate事件的发生,HAL_TIM_PeriodElapsedCallback这个函数就被调用,哎
问题来了,我应该怎么判断这个事更新事件还是溢出事件导致的?
或者右其他更好的办法或者设置
究其原因还是自己对stm32不熟悉
等最终解决问题才发现正点在哪
以下列出TIM的Reset模式的配置和相关程序供以后参考!
至于其他两个IO口配置为上拉,M模式
在main.c文件中添加:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
/* NOTE : This function Should not be modified, when the callback is needed,
the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_6);
当系统定时器溢出的时候IO6的led灯会闪烁
同时在main()函数中TIM初始化结束后添加
__HAL_TIM_URS_ENABLE(&htim3);
//下面这句是我随后又一次修改的,为了不上电就产生一次中断
__HAL_TIM_CLEAR_FLAG(&htim3,TIM_FLAG_UPDATE);
HAL_TIM_Base_Start_IT(&htim3);
上面的意思,是开启定时器中断,第一句是只开启溢出中断
紧接着在while()里添加
HAL_Delay(200);
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_7);
意思是让IO7口产生一个200ms的脉冲波形....
ok,程序结束,可以测试了.
当不用连接线连接IO7口和定时器的触发端口PA6的时候,
定时器会计时到1s产生一次溢出,导致IO6口的led闪烁
此时如果连接PA6口和IO6口,使IO6口的200ms的脉冲触发定时器的reset功能
这样定时器在200ms就会复位,此时上面也失能了更新中断功能,所以不会导致中断发生,即led不会闪烁
定时器中又发现一个问题
MX_TIM3_Init();
HAL_TIM_Base_Start_IT(&htim3);
初始化之后
开启前的时候装载了一次预设值,这样开机就自动产生了一个UPdate中断
这是我的实验现象发现的,不知道是我实验的问题还是定时器这样写就是有类似的问题.
为了,开机不直接进入update中断,那么就需要在开启之前清理一次中断标志位
MX_TIM3_Init();
__HAL_TIM_CLEAR_FLAG(&htim3,TIM_FLAG_UPDATE);
HAL_TIM_Base_Start_IT(&htim3);
这样做之后,实验的结果才是我们想要的....
如果我理解有误,请指出
我遇到的问题是进了中断,出不来,求指教;
PA6 有什么作用?程序没有体现PA6的设置啊
要回复问题请先或
浏览: 4453
关注: 3 人Cade's Blog
STM32 学习三 GPIO操作
一、基础知识
GPIO寄存器
32位配置寄存器:GPIOx_CRL32位配置寄存器:GPIOx_CRH32位数据寄存器:GPIOx_IDR32位数据寄存器:GPIOx_ODR32位置位/复位寄存器:GPIOx_BSRR16位复位寄存器:GPIOx_BRR32位锁定寄存器:GPIOx_LCKR工作模式:
输入浮空输入上拉输入下拉模拟输入开漏输出推挽式输出推挽式复用功能开漏复用功能
每个I/O端口位可以自由编程,而I/O端口寄存器必须按32位字被访问,不允许半字或字节访问。
GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问,这样,在读和更改访问之间产生IRQ时不会发生危险。
每个I/O端口位的基本结构:
端口位配置表:
输出模式位:
端口配置低寄存器CRL:
端口配置高寄存器CRH:
端口输入数据寄存器IDR:
端口输出数据寄存器:ODR
锁定寄存器:GPIOx_LCKR
锁定寄存器位置
端口位设置寄存器:GPIOx_BSRR
端口位复位寄存器:GPIOx_BRR
二、编程测试
在GPIOA.0 .1引脚输出高电平:
#include "stm32f10x_map.h"
int main()
//GPIOA-&CRL
控制0-7引脚
//GPIOA-&CRH
控制8-15引脚 工作模式
//1.设置GPIOA引脚工作模式:
//GPIO共16个引脚,让
//GPIOA.0 GPIOA.1
//用推挽式输出、速度50Mhz
GPIOA-&CRL=0x33;
//2.在相应的引脚输出一个电平
GPIOA-&ODR=0x00;
GPIOA-&ODR=0x3;
return(1);
程序执行结果:
通过第8引脚输入,控制第0引脚输出
#include "stm32f10x_map.h"
int main()
推挽输出 50M
GPIOA-&CRL = 0x03;
GPIOA-&CRH = 0x04;
//CNF0=01 MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01
// PA.0=PA.8
if((GPIOA-&IDR & 0x0100)==0x0100) //如果第8位为1
GPIOA-&ODR = 0x01;
GPIOA-&ODR = 0x00;
return(1);
}程序仿真结果:
点击8脚,发现0脚跟着改变。
通过高8位控制低8位引脚:方法1
#include "stm32f10x_map.h"
int main()
推挽输出 50M
PA.8-15 输入
GPIOA-&CRL = 0x;
GPIOA-&CRH = 0x;
//CNF0=01 MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01
PA.0=PA.8...
if((GPIOA-&IDR & 0x0100)==0x0100)
GPIOA-&ODR = GPIOA-&ODR | 0x01; else GPIOA-&ODR = GPIOA-&ODR & (~0x01);
if((GPIOA-&IDR & 0x0200)==0x0200)
GPIOA-&ODR = GPIOA-&ODR | 0x02; else GPIOA-&ODR = GPIOA-&ODR & (~0x02);
if((GPIOA-&IDR & 0x0400)==0x0400)
GPIOA-&ODR = GPIOA-&ODR | 0x04; else GPIOA-&ODR = GPIOA-&ODR & (~0x04);
if((GPIOA-&IDR & 0x0800)==0x0800)
GPIOA-&ODR = GPIOA-&ODR | 0x08; else GPIOA-&ODR = GPIOA-&ODR & (~0x08);
if((GPIOA-&IDR & 0x1000)==0x1000)
GPIOA-&ODR = GPIOA-&ODR | 0x10; else GPIOA-&ODR = GPIOA-&ODR & (~0x10);
if((GPIOA-&IDR & 0x2000)==0x2000)
GPIOA-&ODR = GPIOA-&ODR | 0x20; else GPIOA-&ODR = GPIOA-&ODR & (~0x20);
if((GPIOA-&IDR & 0x4000)==0x4000)
GPIOA-&ODR = GPIOA-&ODR | 0x40; else GPIOA-&ODR = GPIOA-&ODR & (~0x40);
if((GPIOA-&IDR & 0x8000)==0x8000)
GPIOA-&ODR = GPIOA-&ODR | 0x80; else GPIOA-&ODR = GPIOA-&ODR & (~0x80);
return(1);
输出结果:
通过高8位控制低8位引脚:方法2 通过端口位设置/复位寄存器
#include "stm32f10x_map.h"
int main()
推挽输出 50M
PA.8-15 输入
GPIOA-&CRL = 0x;
GPIOA-&CRH = 0x;
//CNF0=01 MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01
PA.0=PA.8...
if((GPIOA-&IDR & 0x0100)==0x0100)
GPIOA-&BSRR = 0x01;
else GPIOA-&BRR = 0x01;
if((GPIOA-&IDR & 0x0200)==0x0200)
GPIOA-&BSRR = 0x02; else GPIOA-&BRR = 0x02;
if((GPIOA-&IDR & 0x0400)==0x0400)
GPIOA-&BSRR = 0x04; else GPIOA-&BRR = 0x04;
if((GPIOA-&IDR & 0x0800)==0x0800)
GPIOA-&BSRR = 0x08; else GPIOA-&BRR = 0x08;
if((GPIOA-&IDR & 0x1000)==0x1000)
GPIOA-&BSRR = 0x10; else GPIOA-&BRR = 0x10;
if((GPIOA-&IDR & 0x2000)==0x2000)
GPIOA-&BSRR = 0x20; else GPIOA-&BRR = 0x20;
if((GPIOA-&IDR & 0x4000)==0x4000)
GPIOA-&BSRR = 0x40; else GPIOA-&BRR = 0x40;
if((GPIOA-&IDR & 0x8000)==0x8000)
GPIOA-&BSRR = 0x80; else GPIOA-&BRR = 0x80;
return(1);
通过高8位控制低8位引脚:方法3 定义宏
#include "stm32f10x_map.h"
#define PA0
GPIOA-&BRR
#define PA1
GPIOA-&BSRR
int main()
推挽输出 50M
PA.8-15 输入
GPIOA-&CRL = 0x;
GPIOA-&CRH = 0x;
//CNF0=01 MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01
PA.0=PA.8...
if((GPIOA-&IDR & 0x0100)==0x0100)
PA1 = 0x01; else PA0 = 0x01;
if((GPIOA-&IDR & 0x0200)==0x0200)
PA1 = 0x02; else PA0 = 0x02;
if((GPIOA-&IDR & 0x0400)==0x0400)
PA1 = 0x04; else PA0 = 0x04;
if((GPIOA-&IDR & 0x0800)==0x0800)
PA1 = 0x08; else PA0 = 0x08;
if((GPIOA-&IDR & 0x1000)==0x1000)
PA1 = 0x10; else PA0 = 0x10;
if((GPIOA-&IDR & 0x2000)==0x2000)
PA1 = 0x20; else PA0 = 0x20;
if((GPIOA-&IDR & 0x4000)==0x4000)
PA1 = 0x40; else PA0 = 0x40;
if((GPIOA-&IDR & 0x8000)==0x8000)
PA1 = 0x80; else PA0 = 0x80;
return(1);
本文学习 《刘凯老师STm32培训视频》,感谢老师辛勤付出。
编程测试:让开发板的LED灯闪烁
同事帮调试成功的代码,感谢同事的协助。
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
Delay (u32 nCount)
for(; nCount != 0; nCount--);
void GPIO_Config()
GPIO_InitTypeDef GPIO_InitS
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_Init(GPIOB, &GPIO_InitStructure);
int main(void)
SystemInit();
GPIO_Config();
GPIO_SetBits(GPIOC , GPIO_Pin_2);
GPIO_SetBits(GPIOC , GPIO_Pin_2);
GPIO_ResetBits(GPIOB , GPIO_Pin_9);
Delay(0xfffff);
Delay(0xfffff);
Delay(0x5ffff);
GPIO_SetBits(GPIOC , GPIO_Pin_3);
GPIO_ResetBits(GPIOC , GPIO_Pin_2);
GPIO_SetBits(GPIOB , GPIO_Pin_9);
Delay(0xfffff);
Delay(0xfffff);
Delay(0x5ffff);
没有更多推荐了,STM32——GPIO输入模式下上拉和下拉的设置(转)
有个项目要求判断STM32某个按键输入状态,经常出现不稳定的现象,网上查了下,原来需要设置成上拉模式并且要把输入脚输出为高电平,原文如下:
GPIO处于输入模式下,下拉输入和上拉输入的相关配置如下图所示。需要注意的是,下拉输入和上拉输入是通过端口输出寄存器GPIOx_ODR来区分的。因此,在进行上拉/下拉输入配置时候,虽然对GPIO进行的关于输入的操作,但是仍要对和输出相关的寄存器ODR进行配置。
上述注意事项在实际代码编写时表现为:
(1)库函数
特此说明,虽然GPIO_Mode中区分了上拉输入模式GPIO_Mode_IPU和下拉输入模式GPIO_Mode_IPD,如下图所示,但是在GPIO初始化配置时候仍然需要对ODR寄存器进行设置,如上述的GPIO_ResetBits(GPIOA,GPIO_Pin_0);操作。
(2)寄存器
此外,GPIO处于输入模式下,不需要对MODE1和MODE0进行设置(初始化之后默认为00)
输出模式位(仅在输出模式下配置,输入模式下不需要)
没有更多推荐了,}