STM32F103RB 实作笔记(五)- Key/ button 按键练习(正点原子 STM32F103 nano开发板)程式解析

这一篇选择解析 以 button 输入的程式练习。
内容很简单,就是

  1. 设定 key/button 的输入寄存器
  2. 掃描检查 哪一个 key/button 被触发并传回一个讯号
  3. 取得讯号,依照讯号指示执行特定功能。

所以,main() 主程式可以看到三部分, 启动各种设定,key_scan 和 switch…case…

以下是 MAIN.c 的内容:

#include "sys.h"	
#include "delay.h"	
#include "led.h" 
#include "key.h" 
#include "beep.h"

/************************************************
int main(void)
{
	vu8 key=0;	
	Stm32_Clock_Init(9);//
	delay_init(72);	    //
	LED_Init();		  	//
	KEY_Init();         //
	BEEP_Init();		//
	LED0=0;			    //
	while(1)
	{
		key = KEY_Scan(0);//
		switch(key)
		{				 
			case KEY0_PRES://KEY0
				 LED0=!LED0;
				 break;
			case KEY1_PRES://KEY1
				 LED1=!LED1;
				 break;
			case KEY2_PRES:// BEEP
				 BEEP=!BEEP;
				 break;
			case WKUP_PRES://KEY_UP				
				 LED0=!LED0;
				 LED1=!LED1;
				 break;
			default:
				 delay_ms(10);	
		} 
	}
 }

线路图

在这里插入图片描述
在这里插入图片描述
图上可以看到 4 个 key

  1. PA0 – wake_up,需要 下拉
  2. PC8 – Key0, 需要 上拉
  3. PC9 – Key1, 需要 上拉
  4. PD2 – Key2, 需要 上拉

key.h 档 和 key.c 档

// key.h
#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"
//	 
#define KEY0   PCin(8)   	
#define KEY1   PCin(9)
#define KEY2   PDin(2)	 
#define WK_UP  PAin(0)	 
 
#define KEY0_PRES	1	//KEY0   这个数字是 return 后的控制码
#define KEY1_PRES	2	//KEY1 这个数字是 return 后的控制码
#define KEY2_PRES	3	//KEY2 这个数字是 return 后的控制码
#define WKUP_PRES	4	//WK_UP  这个数字是 return 后的控制码

void KEY_Init(void);   //
u8 KEY_Scan(u8 mode);  // 			    
#endif

以下是 key.c 档,请看注解

#include "key.h"
#include "delay.h"	  
// 	 
void KEY_Init(void)
{
	
	RCC->APB2ENR|=1<<2;     //PORTA
	RCC->APB2ENR|=1<<4;     //PORTC
	RCC->APB2ENR|=1<<5;     //PORTD
	
	GPIOA->CRL&=0XFFFFFFF0;	//PA0	  
	GPIOA->CRL|=0X00000008; // 8 ==》 二进制 1000
	
	GPIOC->CRH&=0XFFFFFF00;	//PC8 、9	  
	GPIOC->CRH|=0X00000088; 			 
	GPIOC->ODR|=1<<8;	   	//PC8 
	GPIOC->ODR|=1<<9;	   	//PC9 
		
	GPIOD->CRL&=0XFFFFF0FF;	//PD2	  
	GPIOD->CRL|=0X00000800;   
	GPIOD->ODR|=1<<2;	   	//PD2­ 
			
} 
//mode:0,;1,;

// KEY0>KEY1>KEY2>WK_UP!!
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//
	if(mode) key_up=1;  //	  这个 mode 被当成一个“使能” 的旗标,表示是这个程式在跑
	if(key_up&&(KEY0==0||KEY1==0||KEY2==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(KEY2==0)return KEY2_PRES;
		else if(WK_UP==1)return WKUP_PRES; 
	}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0) key_up=1; 	     
	return 0;//
}

这里再复习一次 GPIOx 的 CRL 和 CRH

GPIOA->CRL|=0X00000008;  是 CNFy= 10, MODEy = 00
**“输入模式(复位后的状态),上拉下拉输入模式”**
再查表
GPIOD->ODR|=1<<2;	   	//PD2­ =1 是 上拉输入, 见下一张图表

在这里插入图片描述
在这里插入图片描述

以下是部分 sys.h 的内容,(参考用)

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //

#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008  

#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 

执行后的结果:

  1. PA0 – wake_up,pc0 和 pc1 的 LED 呈现与当下相反的亮或灭 灯
  2. PC8 – Key0, pc0 的 LED 亮或灭
  3. PC9 – Key1, pc1 的 LED 亮或灭
  4. PD2 – Key2, beep 打开或关闭

有兴趣的人,也可以把亮灯改到 7 节显示器上试试!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值