NVIC :NVIC_Init(&NVIC_Initsture);
1、NVIC只是设置某一种中断的优先级,而不是打开某种中断。
2、ppp_ITConfig();才是开/关具体某种中断使能位的函数。
3、当遇到具体的中断标志位发生时,便会触发中断,需提前写好相应的中断服务函数。
AFIO :跟 AFIO 相关的寄存器有:
1、事件控制寄存器(AFIO_EVCR)
2、复用重映射和调试I/O 配置寄存器(AFIO_MAPR)
3、外部中断配置寄存器1(AFIO_EXTICR1)
4、外部中断配置寄存器2(AFIO_EXTICR2)
5、外部中断配置寄存器3(AFIO_EXTICR3)
6、外部中断配置寄存器4(AFIO_EXTICR4)
只有在“事件控制”、“重映射”、“调试IO配置”、“外部中断”此4种情况下才需要开启AFIO时钟。
输入模式:
与VDD相连的是上拉电阻,与VSS相连的是下拉电阻,在连接到TTL施密特触发器就把电压信号转换为0、1的数字信号存储在输入数据寄存器(IDR)。我们可以通过设置配置寄存器(CRL、CRH)来控制这两个开关,于是就可以得到GPIO的上拉和下拉输入模式。
若GPIO配置为上拉输入模式,在默认状态下(GPIO引脚无输入),读取的GPIO引脚数据为1,高电平,下拉则相反。在上电未配置默认状态下stm32引脚为浮空输入模式,其数据为0,低电平。
浮空输入模式指在芯片内部既没有接上拉也没有接下拉,经有触发器输入。配置成此模式下电压为一点几伏, IO的电平是个不定值,完全由外部输入决定;由于输入阻抗大,一般把这种模式用于外部按键输入,I2C,USART等通信的数据接收端。
模拟输入则关闭了施密特触发器,也不接上下拉电阻,经由另一路把电压信号送到片上外设ADC等,所以使用ADC时配成模拟输入。
输出模式:
推挽输出模式下, 在输出高电平时,P-MOS管导通;低电平时,N-MOS管导通,两个管子一个负责灌电流,一个负责拉电流;推挽输出的低电平为0V,高电平为Vcc(3.3V)。
开漏输出模式下,如果控制输出为0,则N-MOS导通,使输出接地;若控制输出为1(无法直接输出高电平),则既不输出高电平也不输出低电平,为高阻态。为正常使用必须在外部接一个上拉电阻。
开漏输出具有线与特性,即很多个开漏模式引脚连接到一起时,只有当所有引脚都输出高阻态,才由上拉电阻提供高电平,此高电平的电压为外部上拉电阻所接电源电压。若其中一个引脚为低电平,那线路就相当于短路接地,使整条线路都为低电平0V。输出端相当于三极管的集电极。 要得到高电平状态需要上拉电阻才行。 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。
普通推挽输出模式一般应用在输出电平为0 或 Vcc (3.3V)的场合,无法输出中间电压值。
普通开漏输出模式一般应用在电平不匹配的场合,如果要输出5V高电平就要外接一个上拉电阻,电源为5V,把GPIO设置为开漏模式,当输出高阻态时,由上拉电阻和电源向外输出5V电平。
对于相应的复用模式,则根据GPIO的复用功能来选择,如GPIO的引脚用做串口的输出,则使用复用推挽输出模式;如果在IC,SMBUS这些需要线与功能的复用场合,就使用复用开漏模式,在使用任何一种开漏模式时,都需要接上拉电阻。
浮空:顾名思义就是浮在空中,上面用绳子一拉就上去了,下面用绳子一拉就沉下去了。
推挽:就是有推有拉,任何时候IO口的电平都是确定的, 不需要外接上拉或者下拉电阻。
开漏:就等于输出口接了个NPN三极管,并且只接了e,b。 c极是开路的,你可以接一个电阻到3.3V,也可以接一个电阻到5V,这样,在输出1的时候,就可以是5V电压,也可以是3.3V电压了。但是不接电阻上拉的时候,这个输出高就不能实现了。
推挽电路:
两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推挽式输出级既提高电路的负载能力,又提高开关速度。
开漏形式的电路有以下几个特点:
1、利用外部电路的驱动能力,减少IC内部的驱动。当IC内部MOSFET导通时,驱动电流是从外部的VDD流经外部上拉电阻,MOSFET到GND。IC内部仅需很小的栅极驱动电流。
2、一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平;如果需要同时具备输出高电平的功能,则需要接上拉电阻。很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。上拉电阻的阻值决定了逻辑电平转换的沿的速度(电平翻转速度)。阻值越大,速度越低,功耗越小,所以负载电阻的选择要兼顾功耗和速度。
3、开漏提供了灵活的输出方式,但是也有其弱点,就是带来上升沿的延时。因为上升沿是通过外接上拉无源电阻对负载充电,所以当电阻选择小时延时就小,但功耗大;反之延时大功耗小。所以如果对延时有要求,则建议用下降沿输出。
4。 可以将多个开漏输出的Pin,连接到一条线上。通过一只上拉电阻,在不增加任何器件的情况下,形成“与逻辑”关系。这也是I2C,SMBus等总线判断总线占用状态的原理。
什么是“线与”:
在一个结点(线)上, 连接一个上拉电阻到电源 VCC 或 VDD 和 n 个 NPN 或 NMOS 晶体管的集电极 C 或漏极 D, 这些晶体管的发射极 E 或源极 S 都接到地线上, 只要有一个晶体管饱和, 这个结点(线)就被拉到地线电平上。 因为这些晶体管的基极注入电流(NPN)或栅极加上高电平(NMOS),晶体管就会饱和,所以这些基极或栅极对这个结点(线)的关系是 或非 NOR 逻辑。 如果这个结点后面加一个反相器, 就是 或 OR 逻辑。
其实可以简单的理解为:在所有引脚连在一起时,外接一上拉电阻,如果有一个引脚输出为逻辑0,相当于接地,与之并联的回路“相当于被一根导线短路”,所以外电路逻辑电平便为0,只有都为高电平时,与的结果才为逻辑1。
上拉输入 / 下拉输入 / 模拟输入:这几个概念很好理解,从字面便能轻易读懂。
复用开漏输出、复用推挽输出:可以理解为GPIO口被用作第二功能(数据手册的Remap栏)时的配置情况,即并非作为通用IO口使用(数据手册的Default栏)。
最后总结下使用情况:
在STM32中选用IO模式
(0)按键配 输入模式,控制配 输出模式
(1)浮空输入_IN_FLOATING ——浮空输入,可以做KEY识别,RX1
(2)带上拉输入_IPU——IO内部上拉电阻输入
(3)带下拉输入_IPD—— IO内部下拉电阻输入
(4)模拟输入_AIN ——应用ADC模拟输入,或者低功耗下省电
(5)开漏输出_OUT_OD ——IO输出0接GND;IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的IO双向功能
(6)推挽输出_OUT_PP ——IO输出0-接GND, IO输出1 -接VCC,读输入值是未知的
(7)复用功能的推挽输出_AF_PP ——片内外设功能(I2C的SCL,SDA)
(8)复用功能的开漏输出_AF_OD——片内外设功能(TX1,MOSI,MISO,SCK,SS)
STM32设置实例:
(1)模拟I2C使用开漏输出_OUT_OD,接上拉电阻,能够正确输出0和1;读值时先GPIO_SetBits(GPIOB, GPIO_Pin_0)拉高,然后可以使用GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)读IO的值;
(2)如果是无上拉电阻,IO默认是高电平;需要读取IO的值,可以使用带上拉输入_IPU和浮空输入_IN_FLOATING和开漏输出_OUT_OD;
按键GPIO口配置方案:
1、采用上拉输入,因为外部按键电路也是上拉的形式,在没有按键时GPIO也是高电平,和内部采用上拉模式一致。
2、采用浮空输入,因为外部按键电路也是上拉的形式,就没必要再配置成内部上拉模式了,内部上拉和外部上拉效果一样。
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE)
#define GPIOC_BASE (0x40011000) // 驱动代码中只定义了类型和一个该类型的指针宏,而并未定义结构体变量实体,且使用GPIOC->去访问其下的寄存器,原因在于硬件当中从地址0x40011000到0x40011000+sizeof(GPIO_TypeDef)这段空间是外设物理寄存器,它们可以被系统总线访问到,具有RW属性,就好比访问0x20000000开头的内存一样,只是其是物理寄存器,地址不在RAM范围内。如果是RAM中的结构体变量则在RAM中必须有且仅有分配一个结构体变量实体,使用时全通过指针访问内部成员。