久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 25942|回復: 58
收起左側

基于STM32F103的任意I/O口矩陣鍵盤驅動程序

  [復制鏈接]
ID:435174 發表于 2019-1-20 22:54 | 顯示全部樓層 |閱讀模式
本帖最后由 Linux— 于 2019-7-30 23:59 編輯

       網上的矩陣鍵盤代碼非常非常多,但絕大部分都是要連續I/O口的,就比如PA0-PA7、PB3-PB10等等等,這些都要用到一排的連續的單片機引腳。用過STM32單片機的都知道,STM32單片機一排過去連續的引腳的不是很多,就算剛好出現了一排PA0-PA10,可是呢,PA2、PA3串口2要用,PA9、PA10串口1要用,這就顯得比較局限。而且市面上的那些很多都是修改引腳要全文上下一處處修改,麻煩且容易錯漏。所以如果我矩陣鍵盤的引腳可以隨便定義的話那么是不是就不用愁這個問題了?     所以,這就是我給大家帶來的任意可用的I/O的矩陣鍵盤程序,按鍵掃描代碼直接操縱IO口,得出按鍵值。用法很簡單:先看下圖
引腳定義.jpg
我們看到,在key4_4.c中已經用宏定義定義好了矩陣鍵盤8個引腳的端口、具體引腳和時鐘,方便程序的移植和修改。所以這個程序的用法非常簡單,且移植性非常非常地高,因為使用者只需要在宏定義中根據實際需要和興趣愛好修改那8個引腳的端口、具體引腳和時鐘就行了,剩下的就不用修改了,且移植到其他程序去就可以直接使用。下面是按鍵掃描函數,用庫函數給IO口設置高低電平,再根據這些引腳電平狀態得出按鍵值,具體請看截圖:(//Author:GXNU_LPK_201512700***(廣西師范大學電子工程學院2015_LPK)注:此部分按鍵掃描代碼是我熬夜摸索嘗試調試出來的,希望不要被認作抄襲或復制,雖然網上可能有雷同的
keyscan1.png keyscan2.png keyscan3.png

當定義存儲按鍵值的變量keyscan類型為unsigned char時,沒有按鍵按下時默認值為255,即keyscan=255,其他類型的默認值可以自己測試。所以可以這么用:

  1. keyscan = Key_Scan();//keyscan為unsigned char 型
  2. if(keyscan != 255)
  3. {
  4.      key_value = keyscan;
  5. }
復制代碼


下面是測試結果截圖: 測試結果.jpg 鍵盤和測試結果.jpg

下圖是我的硬件平臺,用的是STM32F103C8T6最小系統板子
STM32單片機.jpg

代碼用C語言編寫,已經驗證通過,請放心使用,只要修改好了引腳相關信息和不接錯接反線都能正常使用的。特別強調的是,移植時你定義的矩陣鍵盤引腳不能和其他程序或板子設置的硬件沖突,不然可能會出現按鍵無效或部分按鍵無效的情況。還有,如果你測試時發現按鍵值不對應,這是因為你矩陣鍵盤的PCB布線跟我用的這個不同,自己在程序按鍵值里面手動修改就好了。
下面是main.c代碼
  1. //main.c
  2. #include "key4_4.h"
  3. #include "delay.h"
  4. #include "sys.h"
  5. //平臺:STM32F103
  6. //實驗名稱:不連續I/O矩陣鍵盤實驗  
  7. //Author:GXNU_LPK_201512700***(廣西師范大學電子工程學院2015_LPK)
  8. //使用說明:矩陣鍵盤所用引腳都已經用宏定義定義好了,移植只需根據實際需要在key4_4.c中修改對應的時鐘、引腳和端口即可,其余都不用修改。
  9. //矩陣鍵盤所用的8個引腳可連續可不連續,看實際需要和個人愛好自己定義。
  10. int main(void)
  11. {        
  12.      uart_init(9600);            
  13.      Key_Init();                                 
  14.      delay_init();                                
  15.      printf("不連續I/O口矩陣鍵盤測試\r\n");
  16.    
  17.   while(1)
  18.   {                        
  19.       Key_Test();               
  20.   }
  21. }


復制代碼
下面是usart.c代碼
  1. #include "sys.h"
  2. #include "usart.h"         
  3. //////////////////////////////////////////////////////////////////////////////////         
  4. //如果使用ucos,則包括下面的頭文件即可.
  5. #if SYSTEM_SUPPORT_UCOS
  6. #include "includes.h"                                        //ucos 使用         
  7. #endif
  8. //////////////////////////////////////////////////////////////////////////////////         
  9. //本程序只供學習使用,未經作者許可,不得用于其它任何用途
  10. //ALIENTEK STM32開發板
  11. //串口1初始化                  
  12. //正點原子@ALIENTEK
  13. //修改日期:2012/8/18
  14. //版本:V1.5
  15. //版權所有,盜版必究。
  16. //Copyright(C) 廣州市星翼電子科技有限公司 2009-2019
  17. //All rights reserved
  18. //********************************************************************************
  19. //V1.3修改說明
  20. //支持適應不同頻率下的串口波特率設置.
  21. //加入了對printf的支持
  22. //增加了串口接收命令功能.
  23. //修正了printf第一個字符丟失的bug
  24. //V1.4修改說明
  25. //1,修改串口初始化IO的bug
  26. //2,修改了USART_RX_STA,使得串口最大接收字節數為2的14次方
  27. //3,增加了USART_REC_LEN,用于定義串口最大允許接收的字節數(不大于2的14次方)
  28. //4,修改了EN_USART1_RX的使能方式
  29. //V1.5修改說明
  30. //1,增加了對UCOSII的支持
  31. //////////////////////////////////////////////////////////////////////////////////           


  32. //////////////////////////////////////////////////////////////////
  33. //加入以下代碼,支持printf函數,而不需要選擇use MicroLIB         
  34. #if 1
  35. #pragma import(__use_no_semihosting)            
  36. //標準庫需要的支持函數                 
  37. struct __FILE
  38. {
  39.         int handle;

  40. };

  41. FILE __stdout;      
  42. //定義_sys_exit()以避免使用半主機模式   
  43. _sys_exit(int x)
  44. {
  45.         x = x;
  46. }
  47. //重定義fputc函數
  48. int fputc(int ch, FILE *f)
  49. {      
  50.         while((USART1->SR&0X40)==0);//循環發送,直到發送完畢   
  51.     USART1->DR = (u8) ch;      
  52.         return ch;
  53. }
  54. #endif

  55. /*使用microLib的方法*/
  56. /*
  57. int fputc(int ch, FILE *f)
  58. {
  59.         USART_SendData(USART1, (uint8_t) ch);

  60.         while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}        
  61.    
  62.     return ch;
  63. }
  64. int GetKey (void)  {

  65.     while (!(USART1->SR & USART_FLAG_RXNE));

  66.     return ((int)(USART1->DR & 0x1FF));
  67. }
  68. */


  69. //串口1中斷服務程序
  70. //注意,讀取USARTx->SR能避免莫名其妙的錯誤           
  71. u8 USART_RX_BUF[USART_REC_LEN];     //接收緩沖,最大USART_REC_LEN個字節.
  72. //接收狀態
  73. //bit15,        接收完成標志
  74. //bit14,        接收到0x0d
  75. //bit13~0,        接收到的有效字節數目
  76. u16 USART_RX_STA=0;       //接收狀態標記         

  77. //初始化IO 串口1
  78. //bound:波特率
  79. void uart_init(u32 bound){
  80.     //GPIO端口設置
  81.     GPIO_InitTypeDef GPIO_InitStructure;
  82.         USART_InitTypeDef USART_InitStructure;
  83.         NVIC_InitTypeDef NVIC_InitStructure;
  84.          
  85.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);        //使能USART1,GPIOA時鐘
  86.          USART_DeInit(USART1);  //復位串口1
  87.          //USART1_TX   PA.9
  88.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  89.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  90.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //復用推挽輸出
  91.     GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
  92.    
  93.     //USART1_RX          PA.10
  94.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  95.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
  96.     GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10

  97.    //Usart1 NVIC 配置

  98.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  99.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優先級3
  100.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子優先級3
  101.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
  102.         NVIC_Init(&NVIC_InitStructure);        //根據指定的參數初始化VIC寄存器
  103.   
  104.    //USART 初始化設置

  105.         USART_InitStructure.USART_BaudRate = bound;//一般設置為9600;
  106.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式
  107.         USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個停止位
  108.         USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗位
  109.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制
  110.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收發模式

  111.     USART_Init(USART1, &USART_InitStructure); //初始化串口
  112.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟中斷
  113.     USART_Cmd(USART1, ENABLE);                    //使能串口

  114. }
  115. #if EN_USART1_RX   //如果使能了接收
  116. void USART1_IRQHandler(void)                        //串口1中斷服務程序
  117.         {
  118.         u8 Res;
  119. #ifdef OS_TICKS_PER_SEC                 //如果時鐘節拍數定義了,說明要使用ucosII了.
  120.         OSIntEnter();   
  121. #endif
  122.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷(接收到的數據必須是0x0d 0x0a結尾)
  123.                 {
  124.                 Res =USART_ReceiveData(USART1);//(USART1->DR);        //讀取接收到的數據
  125.                
  126.                 if((USART_RX_STA&0x8000)==0)//接收未完成
  127.                         {
  128.                         if(USART_RX_STA&0x4000)//接收到了0x0d
  129.                                 {
  130.                                 if(Res!=0x0a)USART_RX_STA=0;//接收錯誤,重新開始
  131.                                 else USART_RX_STA|=0x8000;        //接收完成了
  132.                                 }
  133.                         else //還沒收到0X0D
  134.                                 {        
  135.                                 if(Res==0x0d)USART_RX_STA|=0x4000;
  136.                                 else
  137.                                         {
  138.                                         USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
  139.                                         USART_RX_STA++;
  140.                                         if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數據錯誤,重新開始接收         
  141.                                         }                 
  142.                                 }
  143.                         }                    
  144.      }
  145. #ifdef OS_TICKS_PER_SEC                 //如果時鐘節拍數定義了,說明要使用ucosII了.
  146.         OSIntExit();                                                                                          
  147. #endif
  148. }
  149. #endif        
復制代碼

0.png
剩下的代碼請從附件里面下載整個工程查看喲
若黑幣不足的話也可以從這里下載:https://download.csdn.net/download/qq_36112455/10929213
全部資料51hei下載地址:
可移植的不連續IO口矩陣鍵盤(驗證通過).7z (214.93 KB, 下載次數: 961)



評分

參與人數 2黑幣 +80 收起 理由
謝放 + 30 很給力!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:144634 發表于 2019-2-22 11:31 | 顯示全部樓層
請問下,為什么按照您的程序接好線以后用串口調試軟件并不能得到相應的測試結果?用的是RCT6的應該也是兼容的吧?
回復

使用道具 舉報

ID:435174 發表于 2019-2-23 18:06 來自觸屏版 | 顯示全部樓層
Johnny·JH 發表于 2019-2-22 11:31
請問下,為什么按照您的程序接好線以后用串口調試軟件并不能得到相應的測試結果?用的是RCT6的應該也是兼 ...

是不是接線順序反了?你把接到PA15的線接到PB9,PB9的線線接到PA15這樣,其余線類似調換接線順序再試下,程序我多次驗證過和改過很多不同的IO口都沒問題的
回復

使用道具 舉報

ID:113485 發表于 2019-3-1 15:25 | 顯示全部樓層
Linux— 發表于 2019-2-23 18:06
是不是接線順序反了?你把接到PA15的線接到PB9,PB9的線線接到PA15這樣,其余線類似調換接線順序再試下, ...

PB9?樓主你沒定義PB9
回復

使用道具 舉報

ID:378085 發表于 2019-3-12 17:20 | 顯示全部樓層
感謝樓主分享,但是我用的調試助手是野火專用的  但是數值依舊沒有顯示,波特率以及十六進制這塊我都修改成和樓主您一樣的。是我接線順序的原因嗎
回復

使用道具 舉報

ID:435174 發表于 2019-3-15 22:29 | 顯示全部樓層
劍影 發表于 2019-3-1 15:25
PB9?樓主你沒定義PB9

額,這里我要說聲抱歉,由于回復上面那條評論那天時間匆忙沒注意看,我上面帖子那里如果仔細看的話會發現第一張圖跟第三張圖定義的引腳是不同的,第一張沒有PB9,第三張圖那里是有PB9的,因為我是測試不同的引腳不同時間截或拍的圖,這點是我疏忽了,你們知道我想表達的是第一個引腳跟最后一個引腳交換位置,其他引腳也一樣這個意思就好啦

評分

參與人數 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:435174 發表于 2019-3-15 22:32 | 顯示全部樓層
六號啦 發表于 2019-3-12 17:20
感謝樓主分享,但是我用的調試助手是野火專用的  但是數值依舊沒有顯示,波特率以及十六進制這塊我都修改成 ...

那你的“不連續I/O口矩陣鍵盤測試”這句話能正常顯示嗎?

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:435174 發表于 2019-3-15 22:37 | 顯示全部樓層
六號啦 發表于 2019-3-12 17:20
感謝樓主分享,但是我用的調試助手是野火專用的  但是數值依舊沒有顯示,波特率以及十六進制這塊我都修改成 ...

就算接線順序反了那結果也就是得不到理想的數值而已,還不至于沒顯示
回復

使用道具 舉報

ID:422431 發表于 2019-3-16 00:11 | 顯示全部樓層
是不是接線順序反了
回復

使用道具 舉報

ID:333683 發表于 2019-3-16 15:51 | 顯示全部樓層
感謝樓主的分享,用起來感覺非常方便
回復

使用道具 舉報

ID:435174 發表于 2019-3-17 09:23 | 顯示全部樓層
電子發燒友~ 發表于 2019-3-16 15:51
感謝樓主的分享,用起來感覺非常方便

那是啊,不然這程序的意義何在哈哈哈
回復

使用道具 舉報

ID:435174 發表于 2019-3-31 18:19 | 顯示全部樓層
下面附上矩陣鍵盤初始化和按鍵掃描代碼方便大家直接查看:
  1. unsigned char Y1,Y2,Y3,Y4;
  2. void Key_Init(void)
  3. {
  4.    GPIO_InitTypeDef GPIO_InitStructure;   
  5.    RCC_APB2PeriphClockCmd(X1_RCC|X2_RCC|X3_RCC|X4_RCC|Y1_RCC|Y2_RCC|Y3_RCC|Y4_RCC|RCC_APB2Periph_AFIO, ENABLE);
  6.    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
  7.        
  8. /*****************************4行輸出*********************************************/
  9.    GPIO_InitStructure.GPIO_Pin =  X1_GPIO_PIN ;
  10.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
  11.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  12.    GPIO_Init(X1_GPIO_PORT, &GPIO_InitStructure);
  13.    
  14.    GPIO_InitStructure.GPIO_Pin =  X2_GPIO_PIN ;
  15.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
  16.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  17.    GPIO_Init(X2_GPIO_PORT, &GPIO_InitStructure);
  18.    
  19.    GPIO_InitStructure.GPIO_Pin =  X3_GPIO_PIN ;
  20.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
  21.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  22.    GPIO_Init(X3_GPIO_PORT, &GPIO_InitStructure);
  23.        
  24.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
  25.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  26.    GPIO_InitStructure.GPIO_Pin = X4_GPIO_PIN ;   
  27.    GPIO_Init(X4_GPIO_PORT, &GPIO_InitStructure);
  28.    
  29. /**************************************4列輸入*************************************/
  30.    GPIO_InitStructure.GPIO_Pin =  Y1_GPIO_PIN ;   
  31.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;         
  32.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  33.    GPIO_Init(Y1_GPIO_PORT, &GPIO_InitStructure);       
  34.    
  35.    GPIO_InitStructure.GPIO_Pin =  Y2_GPIO_PIN ;   
  36.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;         
  37.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  38.    GPIO_Init(Y2_GPIO_PORT, &GPIO_InitStructure);       
  39.    
  40.    GPIO_InitStructure.GPIO_Pin =  Y3_GPIO_PIN ;   
  41.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;         
  42.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  43.    GPIO_Init(Y3_GPIO_PORT, &GPIO_InitStructure);       
  44.        
  45.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;         
  46.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  47.    GPIO_InitStructure.GPIO_Pin = Y4_GPIO_PIN;      
  48.    GPIO_Init(Y4_GPIO_PORT, &GPIO_InitStructure);       
  49. }
復制代碼
回復

使用道具 舉報

ID:435174 發表于 2019-3-31 18:19 | 顯示全部樓層
下面是按鍵掃描代碼:
  1. int Key_Scan(void)
  2. {
  3.    uchar KeyVal;
  4.    GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);  //先讓X1輸出高
  5.    GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);  //先讓X2輸出高
  6.    GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);  //先讓X3輸出高
  7.    GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN);  //先讓X4輸出高


  8.         if((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)|GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN)|GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN)|GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))==0x0000)  
  9.         return -1; //如果X1到X4全為零則沒有按鍵按下  
  10.          else
  11.          {       
  12.             delay_ms(5);    //延時5ms去抖動
  13.          if((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)|GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN)|GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN)|GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))==0x0000)
  14.             return -1;
  15.          }
  16.          
  17.      GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
  18.      GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
  19.      GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
  20.      GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN);
  21.      
  22.     Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
  23.     Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
  24.      if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
  25.             KeyVal='*';
  26.      if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
  27.             KeyVal=0;
  28.      if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
  29.             KeyVal='D';
  30.      if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
  31.             KeyVal='#';
  32.    
  33.      while(((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN))|(GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN))|(GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN))|(GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))) > 0);
  34.     //等待按鍵釋放
  35.      GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);
  36.      GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
  37.      GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
  38.      GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
  39.    
  40.     Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
  41.     Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
  42.      if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
  43.             KeyVal=1;
  44.      if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
  45.             KeyVal=2;
  46.      if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
  47.             KeyVal=3;
  48.      if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
  49.             KeyVal='A';
  50.       
  51.       while(((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN))|(GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN))|(GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN))|(GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))) > 0);
  52.                

  53.      GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
  54.      GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);
  55.      GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
  56.      GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
  57.         
  58.      Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
  59.      Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
  60.      if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
  61.             KeyVal=4;
  62.      if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
  63.             KeyVal=5;
  64.      if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
  65.             KeyVal=6;
  66.      if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
  67.             KeyVal='B';
  68.    
  69.       while(((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN))|(GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN))|(GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN))|(GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))) > 0);
  70.                
  71.      GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
  72.      GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
  73.      GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);
  74.      GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);   

  75.      Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
  76.      Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
  77.      if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
  78.             KeyVal=7;
  79.      if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
  80.             KeyVal=8;
  81.      if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
  82.             KeyVal=9;
  83.      if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
  84.             KeyVal='C';

  85.        while(((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN))|(GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN))|(GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN))|(GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))) > 0);
  86.           
  87.                 return KeyVal;
  88. }

  89. /************************************
  90.         按鍵表盤為:                1  2  3  A
  91.                                                         4  5  6  B
  92.                                                         7  8  9  C
  93.                                                         *  0  #  D
  94. ************************************/
復制代碼
回復

使用道具 舉報

ID:573105 發表于 2019-6-27 08:38 | 顯示全部樓層
戰艦V3好用嗎
回復

使用道具 舉報

ID:435174 發表于 2019-7-3 12:52 來自觸屏版 | 顯示全部樓層
570744034 發表于 2019-6-27 08:38
戰艦V3好用嗎

STM32F1系列可以直接用(如果按鍵值不對的話跟接線順序和鍵盤PCB布線有關,手動修改一下即可);F4等系列需要在初始化那里改一下
回復

使用道具 舉報

ID:585331 發表于 2019-7-16 20:02 | 顯示全部樓層
我用的野火的串口調試器,但是只能顯示那一行字,沒有具體的按鍵顯示,是什么問題呢?
回復

使用道具 舉報

ID:435174 發表于 2019-7-16 23:59 | 顯示全部樓層
ANNAA 發表于 2019-7-16 20:02
我用的野火的串口調試器,但是只能顯示那一行字,沒有具體的按鍵顯示,是什么問題呢?

是用我提供的那個工程嗎?還是你移植去了其他工程?程序有改動過嗎?線接好了沒?你可以在主頁私信給我,看到的話我會第一時間回復,幫你分析是什么問題
回復

使用道具 舉報

ID:282095 發表于 2019-7-17 09:17 | 顯示全部樓層
使用GPIO進行調試啊
回復

使用道具 舉報

ID:435174 發表于 2019-7-17 23:44 | 顯示全部樓層
鵬博士PBs 發表于 2019-7-17 09:17
使用GPIO進行調試啊

嗯啊,在線debug是個好習慣
回復

使用道具 舉報

ID:435388 發表于 2019-7-27 11:32 來自觸屏版 | 顯示全部樓層
終于調好了,移植到其他的開發版的時候,他定義的引腳可能會和你的板子的設計相碰撞,換個引腳就好,謝謝樓主,很好用
回復

使用道具 舉報

ID:435174 發表于 2019-7-27 18:36 | 顯示全部樓層
牛逼的小菜鳥 發表于 2019-7-27 11:32
終于調好了,移植到其他的開發版的時候,他定義的引腳可能會和你的板子的設計相碰撞,換個引腳就好,謝謝樓 ...

對的,矩陣鍵盤定義的引腳不能和其他硬件沖突,那些出現只能串口打印按鍵沒用或者一部分按鍵有效一部分按鍵沒效的原因多半都是這樣。解決方法是把按鍵引腳改成可用的,沒被其他模塊或硬件占用的就好了,這也我這個程序的與眾不同之處,靈活方便,只需要小小的改動就能達到目的,不像很多市面上的那種要全文上下修改,還容易錯漏。
回復

使用道具 舉報

ID:110942 發表于 2019-7-27 20:01 | 顯示全部樓層
不錯,學習了!
回復

使用道具 舉報

ID:597942 發表于 2019-8-9 10:05 | 顯示全部樓層
Linux— 發表于 2019-7-3 12:52
STM32F1系列可以直接用(如果按鍵值不對的話跟接線順序和鍵盤PCB布線有關,手動修改一下即可);F4等系列需 ...

請問F4要在那里改啊
回復

使用道具 舉報

ID:597942 發表于 2019-8-9 10:54 | 顯示全部樓層
請問F4要怎么改呢
回復

使用道具 舉報

ID:435174 發表于 2019-8-9 23:51 | 顯示全部樓層

改void Key_Init(void)這個初始化函數的GPIO設置部分,你編譯根據錯誤提示修改。掃描函數不用改。
回復

使用道具 舉報

ID:92181 發表于 2019-11-23 17:34 | 顯示全部樓層
感謝樓主的分享,用起來感覺非常方便
回復

使用道具 舉報

ID:453484 發表于 2019-11-25 08:37 | 顯示全部樓層
有圖有真相,不錯
回復

使用道具 舉報

ID:405123 發表于 2019-12-12 09:58 | 顯示全部樓層
本帖最后由 530157193 于 2019-12-12 19:43 編輯

基于STM32F103的任意I/O口矩陣鍵盤驅動程序  這個程序只有接地才有用 如果我要接帶3.3V上拉電阻的矩陣按鍵耀怎么改啊  能不能再發一個貼- -
回復

使用道具 舉報

ID:435174 發表于 2019-12-23 19:45 | 顯示全部樓層
530157193 發表于 2019-12-12 09:58
基于STM32F103的任意I/O口矩陣鍵盤驅動程序  這個程序只有接地才有用 如果我要接帶3.3V上拉電阻的矩陣按鍵 ...

我手上沒有帶上拉電阻的鍵盤,這個程序怎么改動只能靠你自己探索了。
回復

使用道具 舉報

ID:662414 發表于 2019-12-25 18:35 | 顯示全部樓層
超級給力,謝謝樓主
回復

使用道具 舉報

ID:435174 發表于 2019-12-26 22:12 | 顯示全部樓層
565661340 發表于 2019-12-25 18:35
超級給力,謝謝樓主

好用就好,本就是為了方便大家和方便自己而寫的
回復

使用道具 舉報

ID:711830 發表于 2020-3-19 22:28 | 顯示全部樓層
樓主請問一下會出現第4行打印不出數據的情況嗎?
回復

使用道具 舉報

ID:712484 發表于 2020-3-20 19:26 | 顯示全部樓層
用起來感覺非常方便
回復

使用道具 舉報

ID:435174 發表于 2020-3-20 20:11 | 顯示全部樓層
yw禿頭了 發表于 2020-3-19 22:28
樓主請問一下會出現第4行打印不出數據的情況嗎?

我的不會。你第四行的按鍵值打印不出可能是第四行相關的那個IO跟其它硬件或軟件沖突了,檢查下。
回復

使用道具 舉報

ID:146041 發表于 2020-4-2 20:12 | 顯示全部樓層
程序很好,已移植成功
回復

使用道具 舉報

ID:435174 發表于 2020-4-2 22:53 | 顯示全部樓層
撼地神牛雨 發表于 2020-4-2 20:12
程序很好,已移植成功

哈哈哈,厲害。我也一直在用。兄弟覺得好用的話可以把帖子分享給你周邊的人哦
回復

使用道具 舉報

ID:614378 發表于 2020-5-14 11:22 | 顯示全部樓層
很有用,以后鍵盤掃面就用這個程序了,謝謝
回復

使用道具 舉報

ID:435174 發表于 2020-5-14 22:23 | 顯示全部樓層
18990289759 發表于 2020-5-14 11:22
很有用,以后鍵盤掃面就用這個程序了,謝謝

可以
回復

使用道具 舉報

ID:338614 發表于 2020-6-8 00:07 | 顯示全部樓層
請問樓主怎么輸入多位啊?
回復

使用道具 舉報

ID:338614 發表于 2020-6-8 00:09 | 顯示全部樓層
請問樓主,這個程序怎么寫才能輸入多位數據?
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美一级黄色免费看 | 欧美婷婷| 久久精品一级 | 97av视频在线观看 | 99精品久久99久久久久 | 国产一区二区 | 正在播放国产精品 | 日韩一区二区av | 91精品国产综合久久精品 | 欧美国产一区二区 | 成人一区二区三区 | 国产一区二区在线视频 | 亚洲一区二区不卡在线观看 | 免费在线观看成人av | 亚洲高清视频在线 | 四虎影院免费在线播放 | 国产精品一区二区免费 | 久久久久久久久久久久久9999 | 日本一区二区三区免费观看 | 激情五月婷婷 | 亚洲日本欧美日韩高观看 | 欧美综合在线观看 | 午夜激情免费视频 | 欧美激情国产精品 | 久久久久国产精品 | 国产免费观看视频 | 91毛片网| 在线婷婷 | 久久国产欧美日韩精品 | 久草视频在线播放 | 欧美精选一区二区 | 日本中出视频 | 毛片a级| 国产一级在线观看 | 国产精品美女一区二区 | 亚洲欧美精品在线 | 成人在线观看免费爱爱 | 日韩av一区在线观看 | 亚洲欧美视频 | 久久com | 久久高清亚洲 |