單片機實驗說明<四>矩陣鍵盤與LCD基本使用

      網友投稿 751 2022-05-28

      實驗四 矩陣鍵盤識別設計

      設計要求:

      對4×4矩陣式鍵盤電路的鍵值進行編碼,編程實現在LCD液晶顯示器上顯示每個按鍵的“0-F”序號

      電路設計:

      軟件代碼:

      #include "hml/hml.h"

      #define uchar unsigned char

      #define uint unsigned int

      #define lcden P1_2

      #define lcdrs P1_0

      #define rw P1_1

      /* IO引腳分配定義 */

      #define KEY_IN_1 P2_4 //矩陣按鍵的掃描輸入引腳1

      #define KEY_IN_2 P2_5 //矩陣按鍵的掃描輸入引腳2

      #define KEY_IN_3 P2_6 //矩陣按鍵的掃描輸入引腳3

      #define KEY_IN_4 P2_7 //矩陣按鍵的掃描輸入引腳4

      #define KEY_OUT_1 P2_0 //矩陣按鍵的掃描輸出引腳1

      #define KEY_OUT_2 P2_1 //矩陣按鍵的掃描輸出引腳2

      #define KEY_OUT_3 P2_2 //矩陣按鍵的掃描輸出引腳3

      #define KEY_OUT_4 P2_3 //矩陣按鍵的掃描輸出引腳4

      #define LSA P1_5 //LED位選譯碼地址引腳A

      #define LSB P1_6 //LED位選譯碼地址引腳B

      #define LSC P1_7 //LED位選譯碼地址引腳C

      unsigned char disBuf=0;

      uchar table1[] = "Welcome To CSLG!";

      uchar table2[] = "0123456789ABCDEF";

      uchar table3[] = " ";

      uchar num;

      const unsigned char KeyCodeMap[4][4] = { //矩陣按鍵到標準鍵碼的映射表

      { '0', '1', '2', '3' }, //

      { '4', '5', '6', '7' }, //

      { '8', '9', 'a', 'b' }, //

      { 'c', 'd', 'e', 'f' } //

      };

      unsigned char KeySta[4][4] = { //全部矩陣按鍵的當前狀態

      單片機實驗說明<四>矩陣鍵盤與LCD基本使用

      {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1} };

      /* 函數聲明 */

      void KeyScan();

      void KeyDriver();

      void KeyAction(unsigned char keycode);

      /* 按鍵驅動函數,檢測按鍵動作,調度相應動作函數,需在主循環中調用 */

      void KeyDriver()

      {

      unsigned char i, j;

      static unsigned char backup[4][4] = { //按鍵值備份,保存前一次的值

      {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}

      };

      for (i=0; i<4; i++) //循環檢測4*4的矩陣按鍵

      {

      for (j=0; j<4; j++)

      {

      if (backup[i][j] != KeySta[i][j]) //檢測按鍵動作

      {

      if (backup[i][j] != 0) //按鍵按下時執行動作

      {

      KeyAction(KeyCodeMap[i][j]); //調用按鍵動作函數

      }

      backup[i][j] = KeySta[i][j]; //刷新前一次的備份值

      }

      }

      }

      }

      /* 按鍵掃描函數,需在定時中斷中調用,推薦調用間隔1ms */

      void KeyScan()

      {

      unsigned char i;

      static unsigned char keyout = 0; //矩陣按鍵掃描輸出索引

      static unsigned char keybuf[4][4] = { //矩陣按鍵掃描緩沖區

      {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},

      {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}

      };

      //將一行的4個按鍵值移入緩沖區

      keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;

      keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;

      keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;

      keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;

      //消抖后更新按鍵狀態

      for (i=0; i<4; i++) //每行4個按鍵,所以循環4次

      {

      if ((keybuf[keyout][i] & 0x0F) == 0x00)

      { //連續4次掃描值為0,即4*4ms內都是按下狀態時,可認為按鍵已穩定的按下

      KeySta[keyout][i] = 0;

      }

      else if ((keybuf[keyout][i] & 0x0F) == 0x0F)

      { //連續4次掃描值為1,即4*4ms內都是彈起狀態時,可認為按鍵已穩定的彈起

      KeySta[keyout][i] = 1;

      }

      }

      //執行下一次的掃描輸出

      keyout++; //輸出索引遞增

      keyout &= 0x03; //索引值加到4即歸零

      switch (keyout) //根據索引值,釋放當前輸出引腳,拉低下次的輸出引腳

      {

      case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;

      case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;

      case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;

      case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;

      default: break;

      }

      }

      void KeyAction(unsigned char keycode)

      {

      disBuf = keycode;

      }

      void delay(uint z) {

      uint x, y;

      for(x = z; x > 0; x--)

      for(y = 110; y > 0; y--);

      }

      void write_com(uchar com) {

      lcdrs = 0;

      P0 = com;

      delay(5);

      lcden = 1;

      delay(5);

      lcden = 0;

      }

      void write_data(uchar date) {

      lcdrs = 1;

      P0 = date;

      delay(5);

      lcden = 1;

      delay(5);

      lcden = 0;

      }

      void init() {

      rw = 0;

      lcden = 0;

      write_com(0x38);

      write_com(0x0e);

      write_com(0x06);

      write_com(0x01);

      }

      void main() {

      init();

      write_com( 0x00 | 0x80 );

      for(num = 0; num < 16; num++) {

      write_data(table1[num]);

      delay(100);

      }

      write_com( 0x40 | 0x80 );

      for(num = 0; num < 16; num++) {

      write_data(table2[num]);

      delay(100);

      }

      write_com( 0x40 | 0x80 );

      for(num = 0; num < 16; num++) {

      write_data(table3[num]);

      delay(100);

      }

      while(1)

      {

      KeyScan();

      KeyDriver();

      write_com( 0x40 | 0x80 );

      write_data(disBuf);

      }

      }

      思考題

      1. LCD 顯示改為數碼管顯示(選做);

      2. 若要實現數字鍵 0~9 按下后,直接在 LCD 上顯示數字,如何修改程序?

      單片機

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:UNIX 環境高級編程|文件 I/O
      下一篇:一條數據的HBase之旅,簡明HBase入門教程9:RegionServer寫數據
      相關文章
      亚洲AV无码专区在线亚| 久久亚洲国产精品123区| 亚洲国产另类久久久精品小说| 亚洲精品无码久久久久APP| 少妇中文字幕乱码亚洲影视| 相泽亚洲一区中文字幕| 亚洲AV无码乱码在线观看性色扶 | 亚洲AV日韩综合一区尤物| 亚洲明星合成图综合区在线| 亚洲电影在线播放| 亚洲小视频在线播放| 亚洲人成在线免费观看| 亚洲五月综合缴情婷婷| 中文字幕在线日亚洲9| 亚洲私人无码综合久久网| 亚洲人成电影网站色| 亚洲免费综合色在线视频| 亚洲av乱码一区二区三区按摩| 亚洲人成网站在线播放2019| 亚洲av无码专区青青草原| 精品国产亚洲AV麻豆| 亚洲精品国产综合久久一线| 亚洲国产精品白丝在线观看| 亚洲欧洲高清有无| 亚洲永久在线观看| 亚洲国产精华液2020| heyzo亚洲精品日韩| 精品国产亚洲男女在线线电影| 亚洲精品无码成人AAA片| 亚洲avav天堂av在线不卡| 中文字幕亚洲色图| 亚洲人成高清在线播放| 亚洲熟妇久久精品| 午夜亚洲福利在线老司机| 浮力影院亚洲国产第一页| 亚洲爆乳无码专区| 亚洲精品午夜在线观看| 亚洲日韩乱码中文字幕| 亚洲国产V高清在线观看| 亚洲宅男天堂在线观看无病毒| 亚洲av片劲爆在线观看|