上一个也就是第一个实验做的是关于LED的,属于IO口的输出使用,这一节实验是独立按键的使用,即IO 口的输入使用
ministm32 开发板上一共有3个独立按键,分别为 KEY0 KEY1 WK_UP 原理图如下:
注意: KEY0 KEY1 是低电平有效(即它们为低电平时代表按键按下)而 WK_UP 是高电平有效,为什么呢。。很明显,这个问题要分析上面的原理图才能知道的,好吧本渣没学过数模电电路也就勉强70多分(半本书。。还没学完),就硬着头皮来分析一下吧(对错可不保证啊。。QAQ):很明显上图有两个不认识的符号,GND 和VCC 度娘了一下
GND是接地的意思 就是GND那端的电平为0,而VCC 大概是电压源(3.3V),意味着VCC端电平为1 首先KEY0,KEY1 都是跟GND接在一块的,所以它们想要起作用电平肯定是一致的,那么为什么是低电平有效?首先对于开关,想象一下一根导线被一个开关截断,然后这根导线就断开了,怎么让它接起来呢?如果在开关处使得两点电平一致。。那么这根导线不就连起来了么(。。好像有点牵强ORZ)
ok实在不行就先记住,接下就要配置按键了。。新建两个文件key.c key.h导入工程
#include "key.h"
#include "delay.h"
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_ist;
//使能PORTA,PORTC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);
//关闭JTAG 使能SWD
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
//PC5-->KEY0
GPIO_ist.GPIO_Pin=GPIO_Pin_5;
GPIO_ist.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
GPIO_Init(GPIOC, &GPIO_ist);
//PA15-->KEY1
GPIO_ist.GPIO_Pin=GPIO_Pin_15;
GPIO_ist.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
GPIO_Init(GPIOA, &GPIO_ist);
//PA0-->WK-UP
GPIO_ist.GPIO_Pin=GPIO_Pin_0;
GPIO_ist.GPIO_Mode=GPIO_Mode_IPD;//下拉输入
GPIO_Init(GPIOA, &GPIO_ist);
}
//参数mode:0 代表不支持连续按键 非0代表支持连续按键
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==0)return KEY1_PRES;
else if(WK_UP==1) return WK_UP_PRES;
}
else if(KEY0==1&&KEY1==1&&WK_UP==0) key_up=1;
return 0;
}
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 这个语句。。首先看到KEY1 对应的PA15那个口后面还多了一堆JTDI PS 什么东西的,手册上说PA15占用了JTAG的一个IO,这条语句是禁止JTAG,开启SWD 让PA15用作普通IO输出(说实话 没懂)
再看下面那个按键扫描函数,由参数决定是否支持连续按键,好吧,分析一下不支持连续按键的情况吧,假如参数传入的是0,按下键后没松手,第一次扫描之后,key_up变为0了,注意第二次扫描的时候,由于用静态关键字static key_up并不会重新赋值1(这个可以度娘一下static用法),依旧是0,那么就会返回0,。。之后啥也不会执行了。。
直到松手
接下来写key.h 主要是一些关键字的宏定义
#ifndef _KEY_H
#define _KEY_H
#include "sys.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)
#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define KEY0_PRES 1
#define KEY1_PRES 2
#define WK_UP_PRES 3
void KEY_Init(void);
u8 KEY_Scan(u8 mode);
#endif
主函数(很简单的控制。。一眼就能看懂拉)
#include "led.h"
#include "sys.h"
#include "delay.h"
#include "key.h"
int main(void)
{
u8 t;
delay_init();
LED_Init();
KEY_Init();LED0=0;
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);
}
}
}
忘记了既然用按键控制led当然也要配置led 可以把上次做led实验写的led.c led.h 添加的工程里面去
再贴一下吧
led.c
#include "led.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_ist;
//LED0
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD,ENABLE);
GPIO_ist.GPIO_Pin=GPIO_Pin_8;//LED0-->PA.8
GPIO_ist.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_ist.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_ist);
GPIO_SetBits(GPIOA,GPIO_Pin_8);
//LED1
GPIO_ist.GPIO_Pin=GPIO_Pin_2;
GPIO_Init(GPIOD,&GPIO_ist);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
}
led.h
#ifndef _LED_H
#define _LED_H
#include "sys.h"
#define LED0 PAout(8) //PA 8
#define LED1 PDout(2) //PD 2
void LED_Init(void);
#endif