原创 STM32 4*4矩阵键盘

2011-7-5 16:29 6764 9 9 分类: MCU/ 嵌入式

 

STM32 4*4矩阵键盘<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

说明:D4,D5,D6,D7连接了VDD,电平被拉高。行线是D0,D1,D2,D3,列线是D4,D5,D6,D7

程序的功能:当按下键,指示灯会产生亮灭,次数为相应按键编号。

设计原理:

1.行线检测到按键触发

行线设置为下拉输入,列线设置为上拉输入。当有键按下时,行线所对应的中断号产生上升沿触发。

2.列线检测具体哪一列

有键按下时,把行线设置为推挽输出,输出低电平。列线设置为上拉输入。同过检测那一根列线是低电平来确定列线。

核心程序:

//行线和列线的配置
void GPIO_Config(){
 RCC->APB2ENR|=1<<(2+KEYIOEN);
 KEYIO->CRL&=0x00000000;
 KEYIO->CRL|=0x88888888;
 KEYIO->ODR|=0x000000F0;
}

//检测列
u8 ReadColumn(){
 u8 c=0;
 u32 temp;
 GPIOD->CRL&=0x00000000;
 GPIOD->CRL|=0x88883333;
 GPIOD->ODR|=0x000000F0;
 temp=(GPIOD->IDR&0x000000F0)>>4;
 if(temp==0x0000000E) c=0;
 if(temp==0x0000000D) c=1;
 if(temp==0x0000000B) c=2;
 if(temp==0x00000007) c=3;
 GPIO_Config();
 return c;
}

//中断配置
void EXTI_Config(){
 NVIC_Config(GPIO_D,0,RTRI);
 NVIC_Config(GPIO_D,1,RTRI);
 NVIC_Config(GPIO_D,2,RTRI);
 NVIC_Config(GPIO_D,3,RTRI);
 PriorityGroup_Config(2);
 Priority_Config(2,2,EXTI0_IRQChannel,2);
 Priority_Config(2,2,EXTI1_IRQChannel,2);
 Priority_Config(2,2,EXTI2_IRQChannel,2);
 Priority_Config(2,2,EXTI3_IRQChannel,2);
}

//中断处理程序
void EXTI0_IRQHandler(){
 func(4*0+ReadColumn());
 EXTI->PR=1<<0;
}    

void EXTI1_IRQHandler(){
 func(4*1+ReadColumn());
 EXTI->PR=1<<1;

void EXTI2_IRQHandler(){
 func(4*2+ReadColumn());
 EXTI->PR=1<<2;
}

void EXTI3_IRQHandler(){
 func(4*3+ReadColumn());
 EXTI->PR=1<<3;
}
附:完整程序
#include<stm32f10x_lib.h>

#define KEYIO GPIOD
#define KEYIOEN 3
#define GPIO_D 3
#define FTRI 1
#define RTRI 2

void LED_Config(){
 RCC->APB2ENR|=1<<(2+4);
 GPIOE->CRL&=0x00000000;
 GPIOE->CRL|=0x00000003;
 GPIOE->ODR|=0x00000001;
}

void func(u32 n){
 int i,temp;
 for(i=0;i<2*n;i++){
  if(i%2==0)
   GPIOE->ODR&=0x00000000;
  else
   GPIOE->ODR|=0x00000001;
  temp=1000000;
  while(temp--);
 }
}

void GPIO_Config(){
  RCC->APB2ENR|=1<<(2+KEYIOEN);
 KEYIO->CRL&=0x00000000;
 KEYIO->CRL|=0x88888888;
 KEYIO->ODR|=0x000000F0;
}

void NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM){
 u8 EXTIADDR=BITx/4;
 u8 EXTIOFFSET=(BITx%4)*4;
 RCC->APB2ENR|=0x00000001;
 AFIO->EXTICR[EXTIADDR]&=~(0x000F<<EXTIOFFSET);
 AFIO->EXTICR[EXTIADDR]|=GPIOx<<EXTIOFFSET;
 EXTI->IMR|=1<<BITx;
 if(TRIM&0x01)
  EXTI->FTSR|=1<<BITx;
 if(TRIM&0x02)
  EXTI->RTSR|=1<<BITx;
}

void PriorityGroup_Config(u8 NVIC_Group){
 SCB->AIRCR&=0x0000F8FF;
 SCB->AIRCR|=0x05FA0000;
 SCB->AIRCR|=((~NVIC_Group)&0x07)<<8;
}

void Priority_Config(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group){
 NVIC->ISER[NVIC_Channel/32]|=1<<(NVIC_Channel%32);
 NVIC->IPR[NVIC_Channel/4]=(((NVIC_PreemptionPriority<<(4-NVIC_Group))|(NVIC_SubPriority&

(0x0F>>NVIC_Group)))&0x0000000F)<<((NVIC_Channel%4)*8+4);
}

void EXTI_Config(){
 NVIC_Config(GPIO_D,0,RTRI);
 NVIC_Config(GPIO_D,1,RTRI);
 NVIC_Config(GPIO_D,2,RTRI);
 NVIC_Config(GPIO_D,3,RTRI);
 PriorityGroup_Config(2);
 Priority_Config(2,2,EXTI0_IRQChannel,2);
 Priority_Config(2,2,EXTI1_IRQChannel,2);
 Priority_Config(2,2,EXTI2_IRQChannel,2);
 Priority_Config(2,2,EXTI3_IRQChannel,2);
}

u8 ReadColumn(){
 u8 c=0;
 u32 temp;
 GPIOD->CRL&=0x00000000;
 GPIOD->CRL|=0x88883333;
 GPIOD->ODR|=0x000000F0;
 temp=(GPIOD->IDR&0x000000F0)>>4;
 if(temp==0x0000000E) c=0;
 if(temp==0x0000000D) c=1;
 if(temp==0x0000000B) c=2;
 if(temp==0x00000007) c=3;
 GPIO_Config();
 return c;
}

void EXTI0_IRQHandler(){
 func(4*0+ReadColumn());
 EXTI->PR=1<<0;
}    

void EXTI1_IRQHandler(){
 func(4*1+ReadColumn());
 EXTI->PR=1<<1;

void EXTI2_IRQHandler(){
 func(4*2+ReadColumn());
 EXTI->PR=1<<2;
}

void EXTI3_IRQHandler(){
 func(4*3+ReadColumn());
 EXTI->PR=1<<3;
}

int main(){
 LED_Config();
 GPIO_Config();
 EXTI_Config();
 while(1){
 }
}

 

文章评论0条评论)

登录后参与讨论
我要评论
0
9
关闭 站长推荐上一条 /2 下一条