之前用寄存器操作实现了跑马灯和蜂鸣器。这次接着输入寄存器IDR捕获按键。并且综合亮灯和发出声音,作为寄存器GPIO小综合练习。
首先查KEY的电路图,分别用到了ACD几个时钟。KEY0对应PC8,KEY1对应PC9,KEY2对应PD2,KEYUP对应PA0 然后对应的时钟就是APB2的245位
按文档设置为上下拉输出模式(即1000对应16进制的8)
按IDR寄存器读相应端口的电平即可
代码实现如下:
key.h
#ifndef __KEY
#define __KEY
void InitKeyEnv(void);
void TestKey(void);
int GetPressKey(int continuePress);
#endif
key.c
#include "key.h"
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
void InitKeyEnv(void)
{
RCC->APB2ENR|=1<<2;
RCC->APB2ENR|=1<<4;
RCC->APB2ENR|=1<<5;
GPIOA->CRL&=0XFFFFFFF0;
GPIOA->CRL|=0X00000008;
GPIOC->CRH&=0XFFFFFFF0;
GPIOC->CRH|=0X00000008;
GPIOC->ODR|=1<<8;
GPIOC->CRH&=0XFFFFFF0F;
GPIOC->CRH|=0X00000080;
GPIOC->ODR|=1<<9;
GPIOD->CRL&=0XFFFFF0FF;
GPIOD->CRL|=0X00000800;
GPIOD->ODR|=1<<2;
}
void TestKey(void)
{
InitLedEnv();
InitBeepEnv();
InitKeyEnv();
int LED0Stat=0;
int LED1Stat=0;
int LED2Stat=0;
int LED3Stat=0;
while(1)
{
int key=GetPressKey(0);
if(key>=0)
{
if(key==0)
{
if(LED0Stat==0)
{
GPIOC->ODR&=~(1<<0);
GPIOB->ODR&=~(1<<8);
LED0Stat=1;
delay_ms(100);
GPIOB->ODR|=1<<8;
}
else
{
GPIOC->ODR|=1<<0;
GPIOB->ODR&=~(1<<8);
LED0Stat=0;
delay_ms(100);
GPIOB->ODR|=1<<8;
}
}
if(key==1)
{
if(LED1Stat==0)
{
GPIOC->ODR&=~(1<<1);
GPIOB->ODR&=~(1<<8);
LED1Stat=1;
delay_ms(100);
GPIOB->ODR|=1<<8;
}
else
{
GPIOC->ODR|=1<<1;
GPIOB->ODR&=~(1<<8);
LED1Stat=0;
delay_ms(100);
GPIOB->ODR|=1<<8;
}
}
if(key==2)
{
if(LED2Stat==0)
{
GPIOC->ODR&=~(1<<2);
GPIOB->ODR&=~(1<<8);
LED2Stat=1;
delay_ms(100);
GPIOB->ODR|=1<<8;
}
else
{
GPIOC->ODR|=1<<2;
GPIOB->ODR&=~(1<<8);
LED2Stat=0;
delay_ms(100);
GPIOB->ODR|=1<<8;
}
}
if(key==3)
{
if(LED3Stat==0)
{
GPIOC->ODR&=~(1<<3);
GPIOB->ODR&=~(1<<8);
LED3Stat=1;
delay_ms(100);
GPIOB->ODR|=1<<8;
}
else
{
GPIOC->ODR|=1<<3;
GPIOB->ODR&=~(1<<8);
LED3Stat=0;
delay_ms(100);
GPIOB->ODR|=1<<8;
}
}
}
delay_ms(10);
}
}
int GetPressKey(int continuePress)
{
static int keyNotPress=1;
if(continuePress==1)
{
keyNotPress=1;
}
if(keyNotPress==1)
{
int key0=(GPIOC->IDR&(1<<8))>>8;
if(key0==0)
{
delay_ms(10);
key0=(GPIOC->IDR&(1<<8))>>8;
if(key0==0)
{
keyNotPress=0;
return 0;
}
}
int key1=(GPIOC->IDR&(1<<9))>>9;
if(key1==0)
{
delay_ms(10);
key1=(GPIOC->IDR&(1<<9))>>9;
if(key1==0)
{
keyNotPress=0;
return 1;
}
}
int key2=(GPIOD->IDR&(1<<2))>>2;
if(key2==0)
{
delay_ms(10);
key2=(GPIOD->IDR&(1<<2))>>2;
if(key2==0)
{
keyNotPress=0;
return 2;
}
}
int keyUp=(GPIOA->IDR&(1<<0))>>0;
if(keyUp==1)
{
delay_ms(10);
keyUp=(GPIOA->IDR&(1<<0))>>0;
if(keyUp==1)
{
keyNotPress=0;
return 3;
}
}
}
else
{
int key0=(GPIOC->IDR&(1<<8))>>8;
int key1=(GPIOC->IDR&(1<<9))>>9;
int key2=(GPIOD->IDR&(1<<2))>>2;
int keyUp=(GPIOA->IDR&(1<<0))>>0;
if(key0==1&&key1==1&&key2==1&&keyUp==0)
{
keyNotPress=1;
}
}
return -1;
}
led.h
#ifndef __LED
#define __LED
void InitLedEnv(void);
void TestLed(void);
#endif
led.c
#include "led.h"
#include "sys.h"
#include "delay.h"
void InitLedEnv(void)
{
RCC->APB2ENR|=1<<4;
GPIOC->CRL&=0XFFFFFFF0;
GPIOC->CRL|=0X00000003;
GPIOC->CRL&=0XFFFFFF0F;
GPIOC->CRL|=0X00000030;
GPIOC->CRL&=0XFFFFF0FF;
GPIOC->CRL|=0X00000300;
GPIOC->CRL&=0XFFFF0FFF;
GPIOC->CRL|=0X00003000;
GPIOC->CRL&=0XFFF0FFFF;
GPIOC->CRL|=0X00030000;
GPIOC->CRL&=0XFF0FFFFF;
GPIOC->CRL|=0X00300000;
GPIOC->CRL&=0XF0FFFFFF;
GPIOC->CRL|=0X03000000;
GPIOC->CRL&=0X0FFFFFFF;
GPIOC->CRL|=0X30000000;
GPIOC->ODR|=1<<0;
GPIOC->ODR|=1<<1;
GPIOC->ODR|=1<<2;
GPIOC->ODR|=1<<3;
GPIOC->ODR|=1<<4;
GPIOC->ODR|=1<<5;
GPIOC->ODR|=1<<6;
GPIOC->ODR|=1<<7;
}
void TestLed(void)
{
InitLedEnv();
int curIndex=0;
while(1)
{
for(int i=0;i<8;i++)
{
if(i==curIndex)
{
GPIOC->ODR&=~(1<<i);
}
else
{
GPIOC->ODR|=1<<i;
}
}
curIndex++;
curIndex=curIndex%8;
delay_ms(500);
}
}
beep.h
#ifndef __BEEP
#define __BEEP
void InitBeepEnv(void);
void TestBeep(void);
#endif
beep.c
#include "beep.h"
#include "sys.h"
#include "delay.h"
#include "led.h"
void InitBeepEnv(void)
{
RCC->APB2ENR|=1<<3;
GPIOB->CRH&=0XFFFFFFF0;
GPIOB->CRH|=0X00000003;
GPIOB->ODR|=1<<8;
}
void TestBeep(void)
{
InitLedEnv();
InitBeepEnv();
while(1)
{
GPIOB->ODR&=~(1<<8);
GPIOC->ODR&=~(1<<0);
delay_ms(500);
GPIOB->ODR|=1<<8;
GPIOC->ODR|=1<<0;
delay_ms(500);
}
}
mian.c
#include "delay.h"
#include "led.h"
#include "beep.h"
#include "key.h"
int main(void)
{
Stm32_Clock_Init(9);
delay_init(72);
TestKey();
}
实现起来费劲些,搞了个把小时终于搞定了
|