#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();//我们把 8 和 10的端口用导线连接后用表测发现 8 和 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(); 还是0 因为是输出模式??
//8和10用导线连上后,IDR中为1,输出模式 IDR也接收
if(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_12) == 1)
beep();//运行正常,是1 因为输入模式
arm中stm32中矩阵键盘的问题
最新推荐文章于 2024-08-13 10:30:50 发布