0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于STM32F103單片機(jī)的矩陣按鍵設(shè)計(jì)

CHANBAEK ? 來(lái)源:南山府嵌入式 ? 作者:南山府嵌入式 ? 2022-12-09 17:18 ? 次閱讀

需要知識(shí)點(diǎn)

按鍵的原理

GPIO輸入輸出

寄存器操作,如果學(xué)過(guò)51或者對(duì)C語(yǔ)言很熟練這里不存在問(wèn)題。寄存器說(shuō)白了就是操作他們的位(寄存器我理解就是一串羊肉串,讓你找出你先吃哪個(gè),比如我要吃中間的哪一個(gè)該怎么取出來(lái))

矩陣按鍵原理

本實(shí)驗(yàn)使用STM32F103單片機(jī),主題代碼通用的。

如果每個(gè)按鍵占用一個(gè)GPIO引腳,對(duì)于使用多個(gè)按鍵來(lái)說(shuō)就是一種資源的浪費(fèi),因此當(dāng)我們?cè)谠O(shè)計(jì)時(shí),可以考慮矩陣這種方式。本實(shí)驗(yàn)使用4*4也就是16個(gè)按鍵。

矩陣按鍵相對(duì)于獨(dú)立按鍵稍微麻煩一點(diǎn)。4x4矩陣按鍵按照矩陣方式分別分為4行4列。主要有兩種方式,一種是逐行掃描、一種是行列掃描。

原理圖:

逐行掃描

通過(guò)在矩陣按鍵的每一條行線上輪流輸出低電平,檢測(cè)矩陣按鍵的列線,當(dāng)檢測(cè)到的列線不全為高電平的時(shí)候,說(shuō)明有按鍵按下。然后,根據(jù)當(dāng)前輸出低電平的行號(hào)和檢測(cè)到低電平的列號(hào)組合,判斷是哪一個(gè)按鍵被按下。

行列掃描

首先,在全部行線上輸出低電平,檢測(cè)矩陣按鍵的列線,當(dāng)檢測(cè)到的列線不全為高電平的時(shí)候,說(shuō)明有按鍵按下,并判斷是哪一列有按鍵按下。

然后,反過(guò)來(lái),在全部列線上輸出低電平,檢測(cè)矩陣按鍵的行線,當(dāng)檢測(cè)到的行線不全為高電平的時(shí)候,說(shuō)明有按鍵按下,并判斷是哪一行有按鍵按下。

最后,根據(jù)檢測(cè)到的行號(hào)和檢測(cè)的列號(hào)組合,以判斷是哪一個(gè)按鍵被按下。

按鍵檢測(cè)說(shuō)白了就是按鍵按下之后是不是導(dǎo)通的,而其他沒有按下的按鍵是沒有導(dǎo)通的,代碼也不唯一,是多種多樣的。這里就需要操作寄存器或者使用庫(kù)函數(shù)的位操作。

流程

矩陣按鍵程序?qū)崿F(xiàn)

根據(jù)是國(guó)內(nèi)棉矩陣按鍵電路圖,編寫矩陣按鍵應(yīng)用程序,輪徇K1~K8按鍵動(dòng)作,當(dāng)對(duì)應(yīng)的按鍵按下后,返回對(duì)應(yīng)的值:

矩陣按鍵:

/************
按鍵表盤為: 1 2 3 10
 4 5 6 11
 7 8 9 12
 13 0 14 15
 /K1-K4(行)/
 /K5-K8(列)/
/************
 K1--->PC0
 K2--->PC1
 K3--->PC2
 K4--->PC3
 K5--->PC4
 K6--->PC5
 K7--->PC6
 ***********************/

編程要點(diǎn)

(1)使能LED燈和矩陣按鍵的GPIO時(shí)鐘。調(diào)用函數(shù):

RCC_AHB1PeriphClockCmd();

(2)編寫矩陣按鍵掃描程序。

(3)同2-STM32GPIO輸入之按鍵

矩陣按鍵引腳配置

/************************************************************************
 * @brief KEY_Config 按鍵初始化配置
 * @brief 列檢測(cè)初始化
 * @param  無(wú)
 * @retval 無(wú)
 ***********************************************************************/


static void KEY_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    /*開啟RCC時(shí)鐘*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);


    /*K1-K4(行)*/
    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);
    //設(shè)置引腳為
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    //設(shè)置引腳速度50MHZ
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);


    /*K5-K8(列)*/
    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7);
    //設(shè)置引腳為推挽輸出模式
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    //設(shè)置引腳速度50MHZ
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

矩陣按鍵掃描程序

/************************************************************************
 * @brief KEY_4_4_Scan 掃描函數(shù)  矩陣按鍵掃描,返回一個(gè)鍵值
 * @brief 列檢測(cè)初始化
 * @param  無(wú)
 * @retval uint8_t




***********************************
按鍵表盤為:  1   2  3   10
            4   5  6   11
            7   8  9   12
            13  0  14  15
************************************


矩陣按鍵:
    /************************************
按鍵表盤為:  1   2  3   10
            4   5  6   11
            7   8  9   12
            13  0  14  15
/************************************
        K1--->PC0
    K2--->PC1
    K3--->PC2
    K4--->PC3
    K5--->PC4
    K6--->PC5
    K7--->PC6
 ***********************************************************************/
uint8_t KEY_4_4_Scan(void)
{
    u8 KeyVal = 0;
    GPIO_Write(GPIOC, (GPIOC->ODR & 0xff00 | 0x000f)); // PC0-PC3全部輸出高。
    if (((GPIOC->IDR & 0X00F0)) == 0x0000)             // PC4-PC7為0則沒有按鍵按下(第一次檢測(cè)按鍵是否有按下)
    {
        return 0xFF;
    }
    else
    {
        Delay_ms(10);                          //軟件延時(shí)
        if (((GPIOC->IDR & 0X00F0)) == 0x0000) // PC4-PC7為0則沒有按鍵按下(第二次檢測(cè)按鍵是否有按下)
        {


            return 0xFF;
        }
    }
    GPIO_Write(GPIOC, ((GPIOC->ODR & 0xfff0) | 0x0001)); //僅將PC0置高
    switch ((GPIOC->IDR & 0X00f0))                       //第一行,從PC4開始拉高,其余為0,PC5-PC7一樣
    {
    case 0x0010:
        KeyVal = 1; // PC4
        break;
    case 0x0020:
        KeyVal = 2; // PC5
        break;
    case 0x0040:
        KeyVal = 3; // PC6
        break;
    case 0x0080:
        KeyVal = 10; // PC7
        break;
    }
    while (((GPIOC->IDR & 0X00F0)) > 0) //等待按鍵釋放,
        GPIO_Write(GPIOC, 0x0000);      //重新讓PC0到PC3全部輸出低。


    GPIO_Write(GPIOC, ((GPIOC->ODR & 0xfff0) | 0x0002)); //僅將PC1置高
    switch ((GPIOC->IDR & 0X00F0))                       //第一行,從PC4開始拉高,其余為0,PC5-PC7一樣
    {
    case 0x0010:
        KeyVal = 4;
        break;
    case 0x0020:
        KeyVal = 5;
        break;
    case 0x0040:
        KeyVal = 6;
        break;
    case 0x0080:
        KeyVal = 11;
        break;
    }
    while (((GPIOC->IDR & 0X00F0)) > 0) //等待按鍵釋放
        GPIO_Write(GPIOC, 0x0000);      //重新讓PC0到PC3全部輸出低。


    GPIO_Write(GPIOC, ((GPIOC->ODR & 0xfff0) | 0x0004)); //僅將PC2置高
    switch ((GPIOC->IDR & 0X00F0))
    {
    case 0x0010:
        KeyVal = 7;
        break;
    case 0x0020:
        KeyVal = 8;
        break;
    case 0x0040:
        KeyVal = 9;
        break;
    case 0x0080:
        KeyVal = 12;
        break;
    }
    while (((GPIOC->IDR & 0X00F0)) > 0)
        GPIO_Write(GPIOC, 0x0000); //重新讓PC0到PC3全部輸出低。


    GPIO_Write(GPIOC, ((GPIOC->ODR & 0xfff0) | 0x0008)); //僅將PC3置高
    switch ((GPIOC->IDR & 0X00F0))
    {
    case 0x0010:
        KeyVal = 13;
        break;
    case 0x0020:
        KeyVal = 0;
        break;
    case 0x0040:
        KeyVal = 15;
        break;
    case 0x0080:
        KeyVal = 16;
        break;
    }
    while (((GPIOC->IDR & 0X00F0)) > 0) //等待按鍵釋放
        GPIO_Write(GPIOC, 0x0000);      //重新讓PC0到PC3全部輸出低。


    return KeyVal;
}

主函數(shù)

int main(void)
{
  uint8_t Key_value = 0;
  // 來(lái)到這里的時(shí)候,系統(tǒng)的時(shí)鐘已經(jīng)被配置成72M。
  LED_Config();
  BEEP_Config();
  SysTick_InitUP(); //配置10us中斷一次


  USART_Config();
  KEY_Init();
  //矩陣按鍵代碼測(cè)試
  while (1)
  {
    Key_value = KEY_4_4_Scan();
    if (Key_value != 0xFF)
    {
      Delay_ms(200);
      printf("Key_value=%d\\r\\n", Key_value);
    }
    Delay_ms(200);
  }
}

實(shí)驗(yàn)現(xiàn)象

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6023

    文章

    44376

    瀏覽量

    628296
  • STM32F103
    +關(guān)注

    關(guān)注

    33

    文章

    475

    瀏覽量

    63195
  • 矩陣按鍵
    +關(guān)注

    關(guān)注

    0

    文章

    28

    瀏覽量

    8348
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    STM32F103單片機(jī)時(shí)鐘樹結(jié)構(gòu)圖及時(shí)鐘配置

    STM32屬于Cortex-M3內(nèi)核的單片機(jī),時(shí)鐘結(jié)構(gòu)比之前的51單片機(jī)較復(fù)雜的多,根據(jù)數(shù)據(jù)手冊(cè),STM32F103的時(shí)鐘結(jié)構(gòu)如下圖所示。
    發(fā)表于 01-19 16:36 ?8163次閱讀
    <b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>時(shí)鐘樹結(jié)構(gòu)圖及時(shí)鐘配置

    STM32F103教程之STM32F103單片機(jī)的使用心得資料免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STM32F103教程之STM32F103單片機(jī)的使用心得資料免費(fèi)下載目前很火的設(shè)計(jì)STM32教程。
    發(fā)表于 09-26 08:00 ?254次下載

    STM32F103單片機(jī)頻率測(cè)試程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STM32F103單片機(jī)頻率測(cè)試程序免費(fèi)下載。
    發(fā)表于 11-05 08:00 ?65次下載
    <b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>頻率測(cè)試程序免費(fèi)下載

    使用STM32F103單片機(jī)驅(qū)動(dòng)TM1638八位數(shù)碼管八按鍵程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用STM32F103單片機(jī)驅(qū)動(dòng)TM1638八位數(shù)碼管八按鍵程序免費(fèi)下載使用了STM32 3.5 庫(kù)。
    發(fā)表于 08-06 17:34 ?91次下載
    使用<b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>驅(qū)動(dòng)TM1638八位數(shù)碼管八<b class='flag-5'>按鍵</b>程序免費(fèi)下載

    使用STM32F103單片機(jī)顯示可移動(dòng)換方向LCD字幕的程序

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用STM32F103單片機(jī)顯示可移動(dòng)換方向LCD字幕的程序。
    發(fā)表于 07-22 08:00 ?10次下載
    使用<b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>顯示可移動(dòng)換方向LCD字幕的程序

    使用STM32F103單片機(jī)進(jìn)行溫度OLED顯示實(shí)驗(yàn)的工程文件免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用STM32F103單片機(jī)進(jìn)行溫度OLED顯示實(shí)驗(yàn)的工程文件免費(fèi)下載。
    發(fā)表于 08-20 08:00 ?46次下載
    使用<b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>進(jìn)行溫度OLED顯示實(shí)驗(yàn)的工程文件免費(fèi)下載

    STM32F103單片機(jī)控制無(wú)刷電機(jī)的程序源碼免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STM32F103單片機(jī)控制無(wú)刷電機(jī)的源代碼免費(fèi)下載。
    發(fā)表于 09-12 08:00 ?71次下載
    <b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>控制無(wú)刷電機(jī)的程序源碼免費(fèi)下載

    使用STM32F103單片機(jī)采集16路ADC的工程文件和程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用STM32F103單片機(jī)采集16路ADC的工程文件和程序免費(fèi)下載。
    發(fā)表于 09-26 08:00 ?31次下載
    使用<b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>采集16路ADC的工程文件和程序免費(fèi)下載

    使用STM32F103單片機(jī)實(shí)現(xiàn)MP3的電路原理圖免費(fèi)下載

      本文檔的主要內(nèi)容詳細(xì)介紹的是使用STM32F103單片機(jī)實(shí)現(xiàn)MP3的電路原理圖免費(fèi)下載。
    發(fā)表于 12-17 08:00 ?7次下載
    使用<b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>實(shí)現(xiàn)MP3的電路原理圖免費(fèi)下載

    使用STM32F103系列單片機(jī)控制ADS1115的程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用STM32F103系列單片機(jī)控制ADS1115的程序免費(fèi)下載。
    發(fā)表于 03-04 08:00 ?132次下載
    使用<b class='flag-5'>STM32F103</b>系列<b class='flag-5'>單片機(jī)</b>控制ADS1115的程序免費(fèi)下載

    使用STM32F103單片機(jī)實(shí)現(xiàn)定時(shí)器實(shí)驗(yàn)的詳細(xì)資料說(shuō)明

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用STM32F103單片機(jī)實(shí)現(xiàn)定時(shí)器實(shí)驗(yàn)的詳細(xì)資料說(shuō)明。
    發(fā)表于 04-07 08:00 ?5次下載
    使用<b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>實(shí)現(xiàn)定時(shí)器實(shí)驗(yàn)的詳細(xì)資料說(shuō)明

    基于STM32f103單片機(jī)的智能家居步進(jìn)電機(jī)

    基于STM32f103單片機(jī)的智能家居步進(jìn)電機(jī)
    發(fā)表于 05-20 14:30 ?16次下載

    物聯(lián)網(wǎng)小項(xiàng)目:STM32F103單片機(jī)通過(guò)MQTT協(xié)議連接阿里云

    物聯(lián)網(wǎng)小項(xiàng)目:STM32F103單片機(jī)通過(guò)MQTT協(xié)議連接阿里云
    發(fā)表于 11-19 10:51 ?43次下載
    物聯(lián)網(wǎng)小項(xiàng)目:<b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>通過(guò)MQTT協(xié)議連接阿里云

    Keil下,基于STM32F103單片機(jī)按鍵中斷的幾種LED實(shí)例

    Keil下,基于STM32F103單片機(jī)按鍵中斷的幾種LED實(shí)例(流水、奇亮偶滅等)這里是通過(guò)實(shí)驗(yàn)室的單片機(jī)實(shí)現(xiàn)的(皮賽公司的)由于Keil版本的問(wèn)題,5.15版本以下的版本使用C/
    發(fā)表于 11-24 16:51 ?24次下載
    Keil下,基于<b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>按鍵</b>中斷的幾種LED實(shí)例

    基于STM32F103單片機(jī)設(shè)計(jì)

    情況,基于STM32F103單片機(jī)設(shè)計(jì)一個(gè)數(shù)字電壓表仿真設(shè)計(jì)。該設(shè)計(jì)應(yīng)滿足的功能要求為: 1、以STM32單片機(jī)為控制核心設(shè)計(jì)數(shù)字電壓表;? 2、可以測(cè)量0~3.3V輸入電壓值;? 3
    的頭像 發(fā)表于 09-10 09:53 ?1512次閱讀
    基于<b class='flag-5'>STM32F103</b><b class='flag-5'>單片機(jī)</b>設(shè)計(jì)