 |
【电路】

|
 |
【程序】 #include "stm32f10x.h" #define _BV(n) (1 << (n)) #define K1 GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) // 延时函数 void delay() { uint32_t i; for (i = 0; i < 20000; i++); } int main(void) { GPIO_InitTypeDef init; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 开启PB时钟 // PB8~15为输出 init.GPIO_Pin = 0xff00; init.GPIO_Speed = GPIO_Speed_50MHz; init.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &init); // PB0~7为输入 init.GPIO_Pin = 0x00ff; init.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOB, &init); while (1) { // 当按键1按下时 if (!K1) { delay(); if (!K1) { GPIOB->ODR ^= _BV(8); // 反转负载所在引脚的电平 while (!K1); } } } }
|
 |
【说明】 只需要将I/O口的输出模式设为GPIO_Mode_Out_OD(开漏输出),输出的电平就能控制PNP三极管的导通状态。三极管的基极上只需要接200Ω的电阻。 如果把上面程序中的输出模式改为GPIO_Mode_Out_PP(推挽输出)的话,那么无论怎么按K1键,都无法改变三极管的导通状态,所以LED灯始终都是亮着的。
|
 |
如果负载不是通过PNP三极管的基极控制,而是直接接在了单片机的I/O口上的话,那么输出模式应该改回GPIO_Mode_Out_PP(推挽输出)。 因为开漏引脚不连接外部的上拉电阻时,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻。 例如:
 如果用开漏模式输出的话,LED发光会非常暗。
|
 |
STM32中,普通I/O口只有两种输出模式:开漏和推挽。 
|
 |
【四种输入模式】 GPIO_Mode_AIN 模拟输入:用于输入模拟信号 GPIO_Mode_IN_FLOATING 浮空输入:引脚悬空时,读取该端口的电平是不确定的 GPIO_Mode_IPD 下拉输入:没有输入信号的时候默认输入低电平 GPIO_Mode_IPU 上拉输入:没有输入信号的时候默认输入高电平
另外,对于两种复用输出模式,只对内置外设(比如串口之类的功能)有效,不能在普通I/O口上设置使用。
|
 |
因为普中开发板上的I/O口都接了上拉电阻,默认就是输入高电平,不存在没有输入信号的情况,所以在程序中输入模式可以随便设置。
|