基于正点原子stm32-min板进行学习。
配置流程
1.创建GPIO_InitTypeDef结构体
2.使能要使用gpio时钟:使用RCC_APB2PeriphClockCmd方法。打开rcc.h文件,拖到最后查看常用文件,就可以看到常用时钟函数。
3.配置gpio口基本属性
- gpio口选择
- 输入输出模式选择 :驱动外设一般配置为推挽输出,串口、时钟等外设配置时参考正点原子资料《STM32中文参考手册_V10》手册8.1.11。
- 输入输出速度设置:针对应用场景选择合适速度可以降低功耗和提高稳定性。一般要求不高(对功耗没要求)设置为50mhz即可
4.根据以上配置初始化gpio口:使用GPIO_Init方法。记不住可以打开gpio.h文件,拖到最后查看常用函数。
代码
1.直接点亮led(led0和led1每隔一秒进行闪烁)
led.c文件
#include "led.h"
void Led_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;//创建gpio初始化结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD,ENABLE);//使能PA和PD端口对应时钟
//配置led0对应IO口PA8
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;//设置IO口为PA8
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//设置为推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置速度为50mhz
GPIO_Init(GPIOA,&GPIO_InitStructure);//根据设置初始化PA8
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;//LED1对应io口为PD2
GPIO_Init(GPIOD,&GPIO_InitStructure);//其他配置不变,初始化PD2
}
led.h文件
#ifndef __LED_H
#define __LED_H
#include "sys.h"
//后续使用位带操作控制IO口输出
#define LED0 PAout(8)//PA8输出
#define LED1 PDout(2)//PD2输出
void Led_Init(void);
#endif
main.c文件
#include "stm32f10x.h"
#include "led.h"
int main(void)
{
Led_Init();//初始化led对应IO口
delay_init();//延时函数初始化
while(1)
{
LED0=0;
LED1=1;
delay_ms(1000);//延迟一秒进行反转
LED0=1;
LED1=0;
delay_ms(1000);
}
}
2.通过按键点亮led(按下key0时LED0状态改变,按下key1是led1状态进行改变,按下wk_upl时led0、led1状态同时改变)
led程序不变,添加key.h和key.c文件
key.c
#include "delay.h"
#include "key.h"
void key_init(void){
GPIO_InitTypeDef GPIO_InitStructure;//创建gpio初始化结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);//三个按键在PA,PC两组端口上,同时使能端口时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//设置为上拉输入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15;//PA15,key1
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//速度设置为50mhz
GPIO_Init(GPIOA,&GPIO_InitStructure);//根据配置初始化PA15
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//设置为上拉输入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//PC5,key0
GPIO_Init(GPIOC,&GPIO_InitStructure);//根据配置初始化PC5
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//设置为上拉输入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//PA0,wk_up
GPIO_Init(GPIOA,&GPIO_InitStructure);//根据配置初始化PA0
}
//按键扫描函数
//mode;0,不支持连按,1,支持连按
u8 key_scan(u8 mode){
static u8 key_up=1;//按键松开标志位
if(mode) key_up=1;//支持连按
if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))//有按键按下
{
delay_ms(10);//延时消抖,防止误判
key_up=0;
if(KEY0==0) return KEY0_PRES;
else if(!KEY1) return KEY1_PRES;
else if(WK_UP) return WK_UP_PRES;
}
else if(KEY0==1&&KEY1==1&&WK_UP==0) key_up=1;
return 0;//无按键按下
}
key.h
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
//位带操作检测输入
#define KEY0 PCin(5)//读取PC5
#define KEY1 PAin(15)//读取PA15
#define WK_UP PAin(0)//读取PA0
#define KEY0_PRES 1
#define KEY1_PRES 2
#define WK_UP_PRES 3
void key_init(void);//io初始化
u8 key_scan(u8 mode);//按键检测函数
#endif
main.c
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
int main(void)
{
u8 t=0;
Led_Init();//初始化led对应IO口
delay_init();//初始化延时函数
key_init();//初始化按键对应io口
LED0=0;
LED1=1;
while(1)
{
t=key_scan(0);//检查是否有按键按下
switch(t)
{
case KEY0_PRES:
LED0=!LED0;
break;
case KEY1_PRES:
LED1=!LED1;
break;
case WK_UP_PRES:
LED0=!LED0;
LED1=!LED1;
break;
default:
delay_ms(10);
}
}
}