精华内容
下载资源
问答
  • STM32 f103 矩阵键盘

    千次阅读 2015-12-25 15:36:31
    #include "stm32f10x.h" #include "delay.h" #include "key.h" void KEY_Init(void) //³õʼ»¯¾ØÕó¼üÅÌҪʹÓõÄGPIO¿Ú¡£ { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2...
    #include "stm32f10x.h"
    #include "delay.h"
    #include "key.h"
    
    
    void KEY_Init(void) //³õʼ»¯¾ØÕó¼üÅÌҪʹÓõÄGPIO¿Ú¡£
    {
    
    
     	GPIO_InitTypeDef  GPIO_InitStructure;
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
    
    
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //¶¨ÒåPE8µ½PE11ΪÉÏÀ­ÊäÈë¡¢¡¢¡£
    	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
        GPIO_Init(GPIOE,&GPIO_InitStructure);
    	
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;       //¶¨ÒåPE12µ½PE15ΪÏÂÀ­ÊäÈë¡£
    	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
        //ÒòΪÉÏÃ涨ÒåÒý½ÅΪÊä³öʱ£¬ÒѾ­´ò¿ªÕû¸öGPIOAµÄʱÖÓÁË£¬
    	//ËùÒÔ´Ë´¦²»ÔÙÐèÒªº¯ÊýRCC_APB2PeriphClockCmd()À´´ò¿ªÊ±ÖÓÁË¡£
        GPIO_Init(GPIOE,&GPIO_InitStructure);		
    }
    
    
    int KEY_Scan(void) //ʵÏÖ¾ØÕó¼üÅÌ¡£·µ»ØֵΪ£¬¸÷°´¼üµÄ¼üÖµ£¬´Ë¼üÖµÓÉÓû§×Ô¼º¶¨Òå¡£
    {
    	u8 KeyVal;	 //keyValΪ×îºó·µ»ØµÄ¼üÖµ¡£
    	GPIO_Write(GPIOE,(GPIOE->ODR & 0xf0ff | 0x0f00)); //ÏÈÈÃPB8µ½PB11È«²¿Êä³ö¸ß¡£
    	
    	if((GPIOE->IDR & 0xf000)==0x0000)  //Èç¹ûPB12µ½PB15ȫΪ0£¬ÔòûÓмü°´Ï¡£´Ëʱ£¬·µ»ØֵΪ-1.
    		return -1;
    	else
    	{	
    	    delay_ms(5);    //ÑÓʱ5msÈ¥¶¶¶¯¡£
    	    if((GPIOE->IDR & 0xf000)==0x0000)//Èç¹ûÑÓʱ5msºó£¬PB12µ½PB15ÓÖȫΪ0£¬Ôò£¬¸Õ²ÅÒý½ÅµÄµçλ±ä»¯ÊǶ¶¶¯²úÉúµÄ.
    	    return -1;
    	}
    
    
    	GPIO_Write(GPIOE,(GPIOE->ODR & 0xf0ff | 0x0100));	//ÈÃPB11µ½PB8Êä³ö¶þ½øÖƵÄ0001.
    
    
    		switch(GPIOE->IDR & 0xf000)//¶ÔPB12µ½PB15µÄÖµ½øÐÐÅжϣ¬ÒÔÊä³ö²»Í¬µÄ¼üÖµ¡£
    			{
    				case 0x1000: KeyVal=15; break;
    				case 0x2000: KeyVal=11;	break;
    				case 0x4000: KeyVal=7;	break;
    				case 0x8000: KeyVal=3;	break;
    			}
    	   
    	GPIO_Write(GPIOE,(GPIOE->ODR & 0xf0ff | 0x0200));	//ÈÃPB11µ½PB8Êä³ö¶þ½øÖƵÄ0.
    		switch(GPIOE->IDR & 0xf000)		        //¶ÔPB12µ½PB15µÄÖµ½øÐÐÅжϣ¬ÒÔÊä³ö²»Í¬µÄ¼üÖµ¡£
    		{
    			case 0x1000: KeyVal=14;	break;
    			case 0x2000: KeyVal=10;	break;
    			case 0x4000: KeyVal=6;	break;
    			case 0x8000: KeyVal=2;	break;
    		}
    
    
    	GPIO_Write(GPIOE,(GPIOE->ODR & 0xf0ff | 0x0400));	//ÈÃPB11µ½PB8Êä³ö¶þ½øÖƵÄ1011.
    		switch(GPIOE->IDR & 0xf000)		        //¶ÔPB12µ½PB15µÄÖµ½øÐÐÅжϣ¬ÒÔÊä³ö²»Í¬µÄ¼üÖµ¡£
    		{
    			case 0x1000: KeyVal=13;	break;
    			case 0x2000: KeyVal=9;	break;
    			case 0x4000: KeyVal=5;	break;
    			case 0x8000: KeyVal=1;	break;
    		}
     
    	 GPIO_Write(GPIOE,(GPIOE->ODR & 0xf0ff | 0x0800));	//ÈÃPB11µ½PB8Êä³ö¶þ½øÖƵÄ0111.
    		switch(GPIOE->IDR & 0xf000)		        //¶ÔPB12µ½PB15µÄÖµ½øÐÐÅжϣ¬ÒÔÊä³ö²»Í¬µÄ¼üÖµ¡£
    		{
    			case 0x1000: KeyVal=12;	break;
    			case 0x2000: KeyVal=8;	break;
    			case 0x4000: KeyVal=4;	break;
    			case 0x8000: KeyVal=0;	break;
    		}									  
    	return KeyVal;		
    }
    

    展开全文
  • 基于STM32的按键扫描测试程序(学习记录): 目录: 源码; 4x4按键原理; Tips: 粘贴代码时,粘贴在源文件存放的位置中(如:HARDWARE中的.c和.h文件),用C++编译器打开,而不是kei;最后keil会正常显示中文...

    基于STM32的按键扫描测试程序(学习记录):

    目录:

    1. 源码;
    2. 4x4按键原理;
    3. 按键扫描逻辑;

    Tips:

    1. 粘贴代码时,粘贴在源文件存放的位置中(如:HARDWARE中的.c和.h文件),用C++编译器打开,而不是kei;最后keil会正常显示中文字符;
    2. 程序使用嵌套循环实现4x4按键扫描,如果IO口设置过乱时,将循环拆分即可;

    key4x4.h源文件

    #ifndef __KEY4x4_H
    #define __KEY4x4_H	 
    #include "sys.h"
     
    #define KEY_X(X)	PEin(X)				// 尽量避免使用PD以上GPIO,便于移植;
    #define KEY_Y(Y)	PEout(Y)
    
    #define ALL_DOWN_KEY_Y	{	KEY_Y(11) = 0; KEY_Y(12) = 0; KEY_Y(13) = 0; KEY_Y(14) = 0;}
     
    void KEY4x4_Init(void);		// IO口初始化
    u8 KEY4x4_Scan(void);  		// 矩阵按键反馈函数	// 可配置任意矩阵按键使用!!
    u8 KEY16_Scan(void);
    
    /**************
    按键扫描方案二:
    按键使用8个输入IO口, 且所有IO口一端接VCC/VSS;
    
    程序框架:	
    	扫描检测哪两个IO口输入高/低电平;VCC/VSS
    	根据对应坐标,return对应编号;
    **************/
    
    #endif
    

    key4x4.c源文件

    #include "stm32f10x.h"
    #include "key4x4.h"
    #include "sys.h" 
    #include "delay.h"
    #include "usart.h"
    
    
    /*************************
    X:
    	PEin	7-10
    Y:
    	PEout	11-14
    *************************/
    
    
    // 矩阵按键初始化函数
    void KEY4x4_Init(void)
    {
    		GPIO_InitTypeDef GPIO_InitStructure;
    
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
    
    		GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;//KEY0-KEY1
    		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置成下拉输入
    		GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE
    
    		GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;				 //LED0-->PB.5 端口配置
    		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
    		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
    		GPIO_Init(GPIOE, &GPIO_InitStructure);					 		//根据设定参数初始化GPIOE
    }
    
    // 使所有输出拉低;初始化;		// 可以使用define宏定义,执行速度更快,不用跳转函数!!
    static void KEY_ALL_Pull_Down(void)
    {
    	KEY_Y(11) = 0;
    	KEY_Y(12) = 0;
    	KEY_Y(13) = 0;
    	KEY_Y(14) = 0;
    }
    
    // 4x4按键扫描函数
    // 使用一个嵌套循环,完成扫描X和Y;
    // 原理: 通过Y 依次输出高电平,
    //				扫描X 那个IO口输入高电平;
    // X轴:输入检查、扫描;
    // Y轴:设置输出状态;
    // 该函数适合任意排列矩阵按键,只需修改循环中对应编号!!
    // 注意: 1. 改变IO口时,该函数还需要改变循环中IO口编号;(可以定义好IO口编号,便于修改)
    //				2. 该函数同样有优先级问题! 即同时按下时,只反馈先被扫描到的(0-15标号最小的)
    //				3. 函数同一坐标轴的IO口编号必须相邻或能有 规律递增可寻;(否则无法用循环判断)
    //				4. 暂时未添加功能(模式):	按键复用 和 长按;
    // 2020-11-13		返回值调整为:1-16
    // 11/14 不支持连按;解决重复反馈的问题;
    u8 KEY4x4_Scan(void)
    {
    	int i,j;
    	u8 IO_Sign = 0;				// 很简便的一个IO反馈方式标签!!!  且嵌套循环特有!!  // 能返回0-15,适合任意排列矩阵按键
    	static key_up = 1;
    	
    	//KEY_ALL_Pull_Down();										// 初始化所有按键输出拉低;
    	
    	for (i = 11; i <= 14; i++)							// Y输出IO口编号;
    		for (j = 7; j <= 10; j++,IO_Sign++)		// X输出IO口编号;  // 递增IO_Sign,反馈对应值(0-15);
    		{
    			KEY_Y(i) = 1;			// 使PEout(i)输出高电平;
    			
    			if (KEY_Y(i))			// 扫描Y输出高电平, 可以取消此判断; 因为必须输出高电平时,才能正常判断!!
    			{
    				if (KEY_X(j) && key_up)		// 当输入检查到高电平时;
    				{
    					key_up = 0;
    					printf("按键扫描反馈: %d  \r\n",IO_Sign);
    					return IO_Sign;
    				}
    				else if (!KEY_X(7)&&!KEY_X(8)&&!KEY_X(9)&&!KEY_X(10))			// 当所有输入检测到低电平时,再次使能按键; 防止重复反馈
    				{
    					key_up = 1;
    					KEY_ALL_Pull_Down();										// 初始化所有按键输出拉低(低电平);必须在此位置;
    				}
    			}
    			else
    				printf("PEout:IO口%d输出异常!  \r\n ", i);
    		}
    		
    	delay_ms(10);					// 按键防抖;
    }
    
    
    /******************************************标准扫描函数*********************************************/
    // 支持连按
    u8 KEY16_Scan(void)
    {
    	int i,j;
    	u8 IO_Sign = 0;				// 很简便的一个IO反馈方式标签!!!  且嵌套循环特有!!  // 能返回0-15,适合任意排列矩阵按键
    	
    	ALL_DOWN_KEY_Y													// 初始化所有按键输出拉低;
    	
    	for (i = 11; i <= 14; i++)							// Y输出IO口编号;
    		for (j = 7; j <= 10; j++,IO_Sign++)		// X输出IO口编号;  // 递增IO_Sign,反馈对应值(0-15);
    		{
    			KEY_Y(i) = 1;			// 使PEout(i)输出高电平;
    
    			if (KEY_X(j))			// 当输入检查到高电平时;
    				return IO_Sign;
    		}
    		
    	delay_ms(20);					// 按键防抖;		// 连按延时;
    }
    
    

    *4x4按键原理图
    在这里插入图片描述

    1. 按键工作原理:
      当按键被按下时,相连的电路导通;即S1按下时,位于0行0列的线短路,使标号4和5对应的IO口相连(导通);
      最后通过扫描检测输入输出状态即可判断出对应按键被按下;

    2. 程序设计思路:
      程序通过依次使标号1、2、3、4(列0-3)输出高电平,判断5/6/7/8(行0-3)状态;完成按键扫描;

    展开全文
  • 基于stm32f103矩阵键盘

    万次阅读 2014-12-03 13:47:27
    大多数的芯片内部上拉或下拉电阻都是弱上拉或弱下拉,stm32f103的内部也一样,内部上拉或下拉的电阻阻值约为40K,这样可以方便外部调整,但是,在作为一些通讯引脚时,可能会出现上电时数据不稳定的问题,如I2C通讯...

    我现在的任务是做一个8*8的矩阵键盘,制PCB版之前,我用电路板搭了一个3*3的矩阵键盘来模拟一下,设置PA0、PA1、PA2为PP输出,设置P3、P4、P5下拉输入。大多数的芯片内部上拉或下拉电阻都是弱上拉或弱下拉,stm32f103的内部也一样,内部上拉或下拉的电阻阻值约为40K,这样可以方便外部调整,但是,在作为一些通讯引脚时,可能会出现上电时数据不稳定的问题,如I2C通讯,解决的办法是在外部在加上一个较强的上拉或下拉即可。具体程序如下:


    #include <stm32f10x.h>
    #include "usart.h"


    void KeyBoard_Init(void)//按键初始化
    {
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2);
    GPIO_ResetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
    }
    void Delay(u32 nCount)//延时函数
    {
    for(; nCount != 0; nCount--);
    }


    u8 KeyDown(void)
    {
    if((GPIO_ReadInputData(GPIOA)&0xff)!=0x07)//判断是否有键按下

    return 1;//keydown
    }
    else return 0;
    }


    u8 Read_KeyValue(void)   
    {
    unsigned int  KeyValue=0;

    GPIO_SetBits(GPIOA,GPIO_Pin_0);
    GPIO_ResetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);//此时PA0读取的数据是0x01
    switch(GPIO_ReadInputData(GPIOA)&0xff)
    {
    case 0x11:KeyValue='A';break;//此时PA口去的数据是0x11,其余读数与此原理相同
    case 0x21:KeyValue='B';break;
    case 0x41:KeyValue='C';break;
    default: break;
    }
    GPIO_SetBits(GPIOA,GPIO_Pin_1);
    GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_2);
    switch(GPIO_ReadInputData(GPIOA)&0xff)
    {
    case 0x12:KeyValue='D';break;
    case 0x22:KeyValue='E';break;
    case 0x42:KeyValue='F';break;
    default: break;
    }
    GPIO_SetBits(GPIOA,GPIO_Pin_2);
    GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1);
    switch(GPIO_ReadInputData(GPIOA)&0xff)
    {
    case 0x14:KeyValue='G';break;
    case 0x24:KeyValue='H';break;
    case 0x44:KeyValue='I';break;
    default: break;
    }
    GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2);
    GPIO_ResetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
    while((GPIO_ReadInputData(GPIOA)&0xff)!=0x07);
    printf("%c",KeyValue);
    return KeyValue;
    }



    int ScanKeyBoard(void)
    {
    if(KeyDown()
    {
    Delay(0xffff);//软件去抖。按键抖动时间一般为5-10ms,延时以20ms为宜

    if(KeyDown())
    {

    return Read_KeyValue();//按键扫描
    }
    else 
    {
    printf("nothing");

    }
    }
    return 0;
    }


    int main(void)
    {
    u32 i=100;
    SystemInit();
    usart_Configuration();
    KeyBoard_Init();
    Delay(i);
      while(1)
    {
    ScanKeyBoard();
        Delay(500);
    }
    }

    用串口观察实验结果还可以,但个别时候会同时打印出按键字母和“nothing”,我感觉可能是焊接的问题,元器件接触不良很有可能造成这种结果,具体等PCB板回来再测量。

    若以上程序或说明有什么不对的地方,还望指正,谢谢。

    展开全文
  • stm32f103zet6 矩阵键盘代码 在正点原子精英版上测试通过。 matrix_key.c 驱动文件 #include "matrix_key.h" #include "delay.h" #include "sys.h" /************************************ 按键表盘为: 1 2 3 4 ...

    stm32f103zet6 矩阵键盘代码

    在正点原子精英版上测试通过。

    matrix_key.c 驱动文件

    #include "matrix_key.h"
    #include "delay.h"
    #include "sys.h"
    
    /************************************
            按键表盘为:		1  2  3  4 
    							5  6  7  8
    							9  0  A  B
    							C  D  E  F 
    ************************************/
    
    
    unsigned char Y1,Y2,Y3,Y4;
    
    void Matrix_Key_Init(void)
    {
       GPIO_InitTypeDef GPIO_InitStructure;   
       RCC_APB2PeriphClockCmd(X1_RCC|X2_RCC|X3_RCC|X4_RCC|Y1_RCC|Y2_RCC|Y3_RCC|Y4_RCC|RCC_APB2Periph_AFIO, ENABLE);
       GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 
    	
    /*****************************4行输出*********************************************/
       GPIO_InitStructure.GPIO_Pin =  X1_GPIO_PIN ;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(X1_GPIO_PORT, &GPIO_InitStructure);
        
       GPIO_InitStructure.GPIO_Pin =  X2_GPIO_PIN ;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(X2_GPIO_PORT, &GPIO_InitStructure);
        
       GPIO_InitStructure.GPIO_Pin =  X3_GPIO_PIN ;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(X3_GPIO_PORT, &GPIO_InitStructure);
    	
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_InitStructure.GPIO_Pin = X4_GPIO_PIN ;    
       GPIO_Init(X4_GPIO_PORT, &GPIO_InitStructure);
       
    /**************************************4列输入*************************************/
       GPIO_InitStructure.GPIO_Pin =  Y1_GPIO_PIN ;   
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(Y1_GPIO_PORT, &GPIO_InitStructure);	
       
       GPIO_InitStructure.GPIO_Pin =  Y2_GPIO_PIN ;   
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(Y2_GPIO_PORT, &GPIO_InitStructure);	
       
       GPIO_InitStructure.GPIO_Pin =  Y3_GPIO_PIN ;   
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(Y3_GPIO_PORT, &GPIO_InitStructure);	
    	
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_InitStructure.GPIO_Pin = Y4_GPIO_PIN;      
       GPIO_Init(Y4_GPIO_PORT, &GPIO_InitStructure);	
    }
    
    int Matrix_Key_Scan(void)
    {
    	uchar KeyVal = KEY_ERR;
    	static char key_down = 0;
    	GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);  //先让X1输出高
    	GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);  //先让X2输出高
    	GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);  //先让X3输出高
    	GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN);  //先让X4输出高
    
    	if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
    	{
    		delay_ms(10);//去抖动 
    		if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
    		{
    			if (key_down == 0)
    			{	
    				key_down = 1;		//重复按标志位
    				
    				GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);
    				GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
    				GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
    				GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
    					 
    				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
    				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
    				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
    				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
    				
    				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
    					KeyVal=4;
    				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
    					KeyVal=8;
    				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
    					KeyVal='B';
    				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
    					KeyVal='F';
    /**************************************************/		
    				
    				GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
    				GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);
    				GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
    				GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
    								
    				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
    				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
    				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
    				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
    				
    				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
    					KeyVal=3;
    				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
    					KeyVal=7;
    				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
    					KeyVal='A';
    				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
    					KeyVal='E';
    				
    /**************************************************/
    				
    				GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
    				GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
    				GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);
    				GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);   
    
    				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
    				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
    				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
    				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
    				
    				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
    					KeyVal=2;
    				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
    					KeyVal=6;
    				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
    					KeyVal=0;
    				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
    					KeyVal='D';	
    				
    /**************************************************/
    				
    				GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
    				GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN); 
    				GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN); 
    				GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN); 
    				
    				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
    				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
    				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
    				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
    				
    				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
    					KeyVal=1;
    				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
    					KeyVal=5;
    				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
    					KeyVal='C';
    				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
    					KeyVal=9;
    			}
    		}
    	}
    	else
    	{
    		key_down = 0;	//没有检测到有按键按下,则让连按标志位归0
    	}
    	
    	return KeyVal;
    }
    
    void Matrix_Key_Test(void) 
    {
        int num;
    	  num = Matrix_Key_Scan();
    	  switch(num)
    	  { 
    				case KEY_ERR:break;
                    case 0: printf("0\r\n"); break;					  				      
    				case 1: printf("1\r\n"); break;					  				       
    				case 2: printf("2\r\n"); break;					  				     
    				case 3: printf("3\r\n"); break;					  				     
    				case 4: printf("4\r\n"); break;				 	       
    				case 5: printf("5\r\n"); break;					  				      
    				case 6: printf("6\r\n"); break;					  				      
    				case 7: printf("7\r\n"); break;					 			       
    				case 8: printf("8\r\n"); break;								 		       
    				case 9: printf("9\r\n"); break;							 				     	
                    case 'A': printf("A\r\n"); break;						 				      		
    				case 'B': printf("B\r\n"); break;					 				      
    				case 'C': printf("C\r\n"); break;							 				      	
                    case 'D': printf("D\r\n"); break;							 				       	
    				case 'E': printf("E\r\n"); break;					 				      
    				case 'F': printf("F\r\n"); break;				 
          }
    	
    }
    
    

    matrix_key.h 头文件

    #ifndef MATRIX_KEY_H
    #define MATRIX_KEY_H	 
    
    #include <stm32f10x.h>
    #include "usart.h"
    #include "sys.h"
    
    #define uint unsigned int 
    #define uchar unsigned char
    
    //8个引脚 4个为行 4个为列
    //行输出端口定义
    #define X1_GPIO_PORT GPIOA           
    #define X2_GPIO_PORT GPIOA   
    #define X3_GPIO_PORT GPIOA           
    #define X4_GPIO_PORT GPIOA 
    //列输入端口定义
    #define Y1_GPIO_PORT GPIOA         
    #define Y2_GPIO_PORT GPIOA   
    #define Y3_GPIO_PORT GPIOA           
    #define Y4_GPIO_PORT GPIOA 
    
    //行输出引脚定义
    #define X1_GPIO_PIN GPIO_Pin_0
    #define X2_GPIO_PIN GPIO_Pin_1
    #define X3_GPIO_PIN GPIO_Pin_2
    #define X4_GPIO_PIN GPIO_Pin_3
    
    //列输入引脚定义
    #define Y1_GPIO_PIN GPIO_Pin_4
    #define Y2_GPIO_PIN GPIO_Pin_5
    #define Y3_GPIO_PIN GPIO_Pin_6
    #define Y4_GPIO_PIN GPIO_Pin_7
    
    //行输出时钟定义
    #define X1_RCC RCC_APB2Periph_GPIOA
    #define X2_RCC RCC_APB2Periph_GPIOA
    #define X3_RCC RCC_APB2Periph_GPIOA
    #define X4_RCC RCC_APB2Periph_GPIOA
    
    //列输入时钟定义
    #define Y1_RCC RCC_APB2Periph_GPIOA
    #define Y2_RCC RCC_APB2Periph_GPIOA
    #define Y3_RCC RCC_APB2Periph_GPIOA
    #define Y4_RCC RCC_APB2Periph_GPIOA
    //移植代码只需要修改上面的端口和引脚和时钟即可,下面的代码不用修改。
    //矩阵键盘所用的8个引脚可连续可不连续,看实际需要和个人爱好自己定义。
    
    #define KEY_ERR 255
    
    
    void Matrix_Key_Init(void);
    int Matrix_Key_Scan(void);
    void Matrix_Key_Test(void) ;
    
    #endif
    
    
    

    main.c

    #include "led.h"
    #include "delay.h"
    #include "key.h"
    #include "sys.h"
    #include "usart.h"
    #include "matrix_key.h"
    
    
     int main(void)
     {		
    	delay_init();	    	 //延时函数初始化	  
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    	uart_init(115200);	 //串口初始化为115200
     	LED_Init();			     //LED端口初始化
    	 Matrix_Key_Init();
    	 printf("ok\r\n");
     	while(1)
    	{
    		delay_ms(50);
    		Matrix_Key_Test();
    	}	 
     }
    
    
    
    展开全文
  • stm32F103状态机矩阵键盘

    千次阅读 2015-12-08 08:06:48
    矩阵键盘程序,作为麦知club小车项目的一部分,从IAR状态机应用修改而来。 IAR7.4+STM32CUBEMX调试通过。 键盘行4,列3,每条线都有10K上拉电阻。改到4×4矩阵也很容易。 行线设置为 输入,针脚为浮空; 列线设置...
  • 该程序已经过测验通过,使用扫描法完成了矩阵键盘的设计,每一句基本都有注释,工程文件齐全,测试方便,使用的是神州I号 STM32F103RBT6
  • 矩阵键盘代码,可以直接用
  • 一个基于stm32f103zet6的矩阵键盘程序,stm32接上矩阵键盘即可使用。
  • 使用的是正点原子战舰开发板,屏幕使用的是lcd触摸屏,矩阵键盘连接PA0-PA7,可以改变其他值,有个问题是第三排按键好像不能用,应该是战舰开发板的硬件问题,这里我没有修改
  • 在各种应用和比赛中我们都会用到矩阵键盘,所以矩阵键盘必不可少。我已经帮大家封装好了,大家只需要移植就行。管脚直接可修改。 这是他的头文件: #ifndef __keyboad_h__ #define __keyboad_h__ #include "stm32f10...
  • STM32F103矩阵键盘实验,按下那个键,串口输入显示,双去抖
  • 4*4矩阵键盘(方法1)已经在STM32F103RBT6亲测通过,引脚排布、键值排布均已标出。第二种方法见另外一个资源4*4矩阵键盘(方法2)。
  • 4*4矩阵键盘(方法2)已经在STM32F103RBT6亲测通过,引脚排布、键值排布均已标出。第一种方法见另外一个资源4*4矩阵键盘(方法1)。.
  • 上一篇说完了STM32库开发的引脚输出控制,这一篇对其引脚输入控制方法进行说明,引脚设置为输入功能时能够感知引脚上的电平高低,具有模拟输入复用功能的引脚还可以结合芯片内部的A/D准确测量其电平值,后续在ADC...
  • 基于STM32F103矩阵键盘代码,引脚可根据您的需求和爱好随意定义,无论连不连续都可以!引脚信息已经在key4_4.c中宏定义好了,只需要在宏定义中修改你定义的引脚时钟、引脚号和引脚对应的端口即可!非常方便。可...
  • 该文件为基于STM32F103C8T6的简易计算器设计,外接设备为行列式矩阵键盘与LCD12864,采用串行方式接口,能实现简单的加减乘除,LCD中英显示均无问题。程序里面的所用引脚有详细定义,可根据自己的实际情况适当修改。
  • stm32f103vet6外部中断来获取矩阵键盘键值外加可精确到小数点后6位计算器源程序
  • 可直接用的4x4和4x3薄膜矩阵面板stm32f103控制实例,横列和竖列引脚请对照程序进行连接,也可自行更改引脚。
  • STM32矩阵键盘代码

    2016-12-16 08:43:17
    该程序是STM32F103系列的矩阵键盘代码,本人使用过
  • 使用了STM32CubeMX及Keil(HAL库)材料:stm32开发板、无源蜂鸣器、4×4矩阵键盘、杜邦线、st-link实验原理:1、音高和矩形波周期有关 ,音强和占空比有关(?),通过设置TIM2为PWM,对应按键信息设置不同的方波...
  • 该文件为基于STM32F103C8T6的简易计算器设计,外接设备为行列式矩阵键盘与LCD12864,采用串行方式接口,能实现简单的加减乘除,LCD中英显示均无问题。程序里面的所用引脚有详细定义,可根据自己的实际情况适当修改。

空空如也

空空如也

1 2 3 4
收藏数 64
精华内容 25
关键字:

stm32f103矩阵键盘