现在的位置: 首页 > 综合 > 正文

arm中stm32中矩阵键盘的问题

2013年09月17日 ⁄ 综合 ⁄ 共 3927字 ⁄ 字号 评论关闭

#ifndef __COMMON_H 


#define __COMMON_H 
#include <stm32f10x.h> 
/* 4*4矩阵键盘 */ 
void keyboard_init(void); 
void update_key(void); 
static unsigned char key[4][4];
 void keytest();
 static  void delay(__IO uint32_t nCount);
 #define	Key_row_1 GPIO_Pin_12 // GPIO_pin 为16位的整数
#define	Key_row_2 GPIO_Pin_13 // >> 12	//这里后期可以优化为 直接赋值 0x.....
#define	Key_row_3 GPIO_Pin_14 //  	 //前期方便查看
#define	Key_row_4 GPIO_Pin_15 //  
#define	Key_col_1 GPIO_Pin_7  // 
#define	Key_col_2 GPIO_Pin_8  // 
#define	Key_col_3 GPIO_Pin_10 // 
#define	Key_col_4 GPIO_Pin_11 // 

#endif  


/**************矩阵键盘.c文件*****************************/

#include "TESTKEY.H"
#include "beep.h"

struct io_port {                                            
GPIO_TypeDef *GPIO_x;                 
unsigned short GPIO_pin;
};         
static struct io_port key_output[4] = {
{GPIOG, GPIO_Pin_7}, {GPIOG, GPIO_Pin_8},
{GPIOG, GPIO_Pin_10}, {GPIOG, GPIO_Pin_11}
};
static struct io_port key_input[4] = {
{GPIOG, GPIO_Pin_12}, {GPIOG, GPIO_Pin_13},
{GPIOG, GPIO_Pin_14}, {GPIOG, GPIO_Pin_15}
};
static unsigned char key[4][4];
void keyboard_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
unsigned char i;
/* 键盘行扫描输出线 输出高电平 */
/* 4 列 输出*/
							 
	   GPIO_InitStructure.GPIO_Pin = Key_col_1 | Key_col_2 | Key_col_3 | Key_col_4;
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOG, &GPIO_InitStructure);
/* 键盘列扫描输入线 键被按时输入高电平 放开输入低电平 */
/* 4 行 输入*/
 
	    GPIO_InitStructure.GPIO_Pin = Key_row_1 | Key_row_2 | Key_row_3 | Key_row_4;
    GPIO_InitStructure.GPIO_Mode =   GPIO_Mode_IPU;; // 1> 设置为上拉模式 、、这里设置了 那键盘上 会额外加上上拉电阻么,还是设置后芯片就已经帮你加好了?:芯片已经帮你加好了,见下面的电路图*/
	//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 2 > 这里去掉可以么?  系统有默认值
    GPIO_Init(GPIOG, &GPIO_InitStructure);
for(i = 0; i < 4; i++)
{
  GPIO_ResetBits(key_output[i].GPIO_x, key_output[i].GPIO_pin);
}
}
void update_key(void)
{
unsigned char i, j;
for(i = 0; i < 4; i++)             //i是输出口,依次置高电平  由于不是线与的关系,,下面的代码理所当然有问题
{
  GPIO_SetBits(key_output[i].GPIO_x, key_output[i].GPIO_pin);   
  for(j = 0; j < 4; j++)        //     3 > j是输入口,当键按下时导通, 行列成 “线与” 关系 然后接收到 1 (这里的1是高电平的意思?)的信号。:并非线与的关系相似电路建单片机图   
  {	   delay(1000);//beep();//  这里可以去掉延时函数 是么?:随便  
   if(GPIO_ReadInputDataBit(key_input[j].GPIO_x, key_input[j].GPIO_pin) == 1) //  这里为什么按键按下后也不会==1? : 上面没有配置时钟源
   {  
    
	delay(10);	 beep();
	if(GPIO_ReadInputDataBit(key_input[j].GPIO_x, key_input[j].GPIO_pin) == 1)
   	{
    	key[i][j] = 1; 		beep();
		while (GPIO_ReadInputDataBit(key_input[j].GPIO_x, key_input[j].GPIO_pin)==1);
   	}else{
                 key[i][j] = 0;	//beep();
   		}
	}
  }
  GPIO_ResetBits(key_output[i].GPIO_x, key_output[i].GPIO_pin);//还原
}
}
 void keytest()
 {
 	keyboard_init();
	while(1) 
	update_key();
 }
 void delay(__IO uint32_t nCount)
{
   for(; nCount != 0; nCount--);
}
//为什么仿真一直都能过,而烧到板上就没得反应呢?beep是个蜂鸣器的程序。beep没有问题,已经测试过,这程序应该怎么改呢?

上面红色的3个问题很是疑惑。
由于这个矩阵键盘的问题,把我搅的稀里糊涂的。产生了下面的一堆问题。

什么都不做那么GPIOx_IDR永远都是 0 ??是么?
哪种情况下 IDR 的值才会改变??自己ODR的内容能发送出去让IDR接收吗?那应该怎么做?
IDR与DDR 关系到底是怎样?
这里附上 IO口 IDR,,ODR的电路图

还有我矩阵键盘的电路图

问题在一位老师的帮助下得以解决,附上我的测试文档

//冤啊,居然是没写这两个函数SystemInit();RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG , ENABLE);引起下面乱接受。Set 和 reset反了 以至于下面的一堆信息出现问题

GPIOG->BSRR = 1<<7 ; //这里对IO口电压测试是 0(低电平)、、那么我们要观察BSRR指向的地址是否是BRR的地址 

GPIO_SetBits(GPIOG,GPIO_Pin_8) ;   //多个板测试 结果如下

GPIO_SetBits(GPIOG,GPIO_Pin_12) ; // 这里是输入模式 //测外部引脚 为 0

GPIO_ResetBits(GPIOG,GPIO_Pin_13) ; //这里也是输入模式 //测外部引脚 为 0、、//输入模式对IO口设置没有任何效果?

GPIO_ResetBits(GPIOG,GPIO_Pin_10); //这里对IO口测试是 1

if(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_10) == 1)beep();//我们把 和 10的端口用导线连接后用表测发现 和 10均为高电平,但是GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_10) == 1 仍然为假,、、//即是说 10 口不接受信号,是由于 是输出模式?寄存器被锁了?

      if(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_12) == 1)beep();//输入模式赋值不起作用哦,所以这里仍然是0//我们把10 和 12用导线连起来 发现IO口均为高电平但是 IDR里面仍然没有数据。beep不会被激活

难道IDR被什么锁住了?没有被打开? 还是一种可能只运行了一次beep然后里面就锁住了IDR》?Beep对整个程序产生了很大的干扰??

#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)

/** 

  * @brief General Purpose I/O

  */

typedef struct

{

  __IO uint32_t CRL;

  __IO uint32_t CRH;

  __IO uint32_t IDR;

  __IO uint32_t ODR;

  __IO uint32_t BSRR;

  __IO uint32_t BRR;

  __IO uint32_t LCKR;

} GPIO_TypeDef;

#define GPIOG_BASE            (APB2PERIPH_BASE + 0x2000)

、、、加上上面两个初始化函数后,我们重新对上面的值进行了测试,端口的值均显示正常,

if(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_10) == 1)

beep();   还是因为是输出模式??

//810用导线连上后,IDR中为1,输出模式 IDR也接收

if(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_12) == 1)

beep();//运行正常,是因为输入模式













抱歉!评论已关闭.