1.资源和命名方式
资源:
我是用的是STM32F103ZET6芯片,一共有144引脚,112个通用GPIO口。
命名方式:
如PE0,P指的是端口,E是分类,0是具体编号。
2.GPIO口的作用
输入:从外界传递给MCU信号
输出:从MCU传递给外界信号
3.GPIO工作模式
一共有8种工作模式:
输入:
上拉输入:空闲状态下,增加高电平的驱动能力;
下拉输入:空闲状态下,增加低电平的驱动能力;
浮空输入:空闲状态下,不具备高低电平驱动能力,直接输入的电压进行转换;
模拟输入:检测模拟电压,数据传给ADC做转换;
图1 GPIO输入电路图
输出:
开漏模式:只能输出0 不能输出1(假如需要输出1 需要外部电路支持)
推挽模式:既能输出0 又能输出1
普通模式:通过MCU直接控制gpio口高低电平
复用模式:通过外设直接控制高低电平
复用:把IO用做复用其他外设功能时选择复用模式; (USART、TIM、SPI、IIC等)
通用:只是把IO做普通输出的功能;
图2 GPIO输出电路图
4.输入检测
输入电压:3.3V / 0V / 0v~3.3V------数值
极端输入:3.3V/0V:逻辑1/逻辑0
模拟输入:ADC:12位/8位/16位
上拉输入:空闲状态下,增加高电平的驱动能力;
下拉输入:空闲状态下,增加低电平的驱动能力;
浮空输入:空闲状态下,不具备高低电平驱动能力,直接输入的电压进行转换;
模拟输入:检测模拟电压,数据传给ADC做转换;
TTL肖特基触发器:把高低电平电压值转换为逻辑值;
5.输出控制
逻辑值:1/0:p-mos/n-mos:电压值:3.3V/0V
中间值:(PWM)/DAC
输出配置:
当IO口被被配置为输出模式时:
1.输出缓冲器被激活
开漏模式:输出寄存器上的‘0’激活N-MOS,而输出寄存器上的‘1’端口置于高阻态(P-MOS从不被激活)。
推挽模式:输出寄存器上的‘0‘激活N-MOS,而输出寄存器上的‘1’将被激活P-MOS。
2.施密特触发器被激活。
3.弱上拉和下拉电阻被禁止。
4.出现在I/O引脚上的数据在每个APB2时钟被采样到输入寄存器。
5.在开漏模式时,对输入数据寄存器的读访问可以得到I/O状态。
6.在推挽模式时,对输出寄存器的访问得到最后一次写的值。
下图是I/O端口位的写配置。
图3 I/O端口位的写配置
6.STM32F1系列GPIO配置
led.h:
头文件,宏定义,函数生命。
#include <stm32f10x.h>
#ifndef __LED_H
#define __LED_H
#define LED1 GPIO_Pin_2
#define LED2 GPIO_Pin_3
#define LED3 GPIO_Pin_4
#define LED4 GPIO_Pin_5
#define R GPIO_Pin_8
#define G GPIO_Pin_7
#define B GPIO_Pin_6
void LED_Init(void);
#endif
led.c:
LED灯初始化函数。
void LED_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE, ENABLE);
//LED1,LED2,LED3,LED4初始化
GPIO_InitStructure.GPIO_Pin = R|G|B;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, R|G|B);
GPIO_InitStructure.GPIO_Pin = LED1|LED2|LED3|LED4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE, LED1|LED2|LED3|LED4);
}
key.h:
#include <stm32f10x.h>
#ifndef __KEY_H
#define __KEY_H
#define KEY1 GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)
#define KEY2 GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4)
#define KEY3 GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_5)
#define KEY4 GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6)
void KEY_Init(void);
u8 KEY_Scan();
#endif
key.c:
void KEY_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
u8 KEY_Scan()
{
if(KEY1==1||KEY2==0||KEY3==0||KEY4==0)
{
delay_ms(10);//去抖动
if(KEY1==1){
while(KEY1==1);
return 1;
}
else if(KEY2==0){
while(KEY2==0);
return 2;
}
else if(KEY3==0){
while(KEY3==0);
return 3;
}
else if(KEY4==0){
while(KEY4==0);
return 4;
}
}
return 0;// 无按键按下
}