cortex_m3_stm32嵌入式学习笔记(二):独立按键实验(IO输入)

ARM 406浏览

上一个也就是第一个实验做的是关于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