arm中stm32中矩阵键盘的问题

来源:互联网 发布:matlab有linux版本吗 编辑:程序博客网 时间:2024/05/03 01:22


#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); #defineKey_row_1 GPIO_Pin_12 // GPIO_pin 为16位的整数#defineKey_row_2 GPIO_Pin_13 // >> 12//这里后期可以优化为 直接赋值 0x.....#defineKey_row_3 GPIO_Pin_14 //   //前期方便查看#defineKey_row_4 GPIO_Pin_15 //  #defineKey_col_1 GPIO_Pin_7  // #defineKey_col_2 GPIO_Pin_8  // #defineKey_col_3 GPIO_Pin_10 // #defineKey_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();//运行正常,是因为输入模式

	
				
		
原创粉丝点击