(51單片機)矩陣按鍵密碼鎖表白(C語言代碼編撰)(矩陣按鍵教程)(LCD1602淺教程)

目錄

源代碼

?main.c

MatrixKey.c

MatrixKey.h

LCD1602.c

?LCD1602.h

?Delay.c

Delay.h

運行效果圖:

第一步:

第二步:

第三步:

第四步:

?代碼解析與教程:

延時函數Delay

?LCD1602

?MatrixKey模塊


源代碼

如上圖將7個文放在Keli5 中即可,然后燒錄在單片機中就行了

燒錄軟件用的是STC-ISP,不知道怎么安裝的可以去看江科大的視頻:

【51單片機入門教程-2020版 程序全程純手打 從零開始入門】https://www.bilibili.com/video/BV1Mb411e7re?p=2&vd_source=ada7b122ae16cc583b4add52ad89fd5e

源代碼:

?main.c

//mian.c#include <STC89C5xRC.H>
#include	"Delay.h"
#include	"LCD1602.h"
#include	"MatrixKey.h"unsigned char KeyNum;
unsigned int Password,Count;void main(){LCD_Init();LCD_ShowString(1,1,"Password:");//上行顯示LCD_ShowNum(2,1,0,4);//下行初始顯示while(1){KeyNum=MatrixKey();if(KeyNum){//檢測是否摁按鍵if(KeyNum<=10){//檢測摁按鍵的按鍵是否小于10,輸入密碼if(Count<4){Password*=10;//密碼左移一位,利用當前數乘10得Password+=KeyNum%10;	//將10變成0,并且每次獲得新輸入的數Count++;//配合if條件最大位數為4,限制密碼位數}}LCD_ShowNum(2,1,Password,4);//更新顯示屏}if(KeyNum==11){//按鍵是否等于于11,確認密碼if(Password==301){//在此自定義密碼(可改6666等,這里用的301)LCD_ShowString(1,14," OK");//如果密碼等于6666,顯示OKDelay(2000);//OK顯示2秒LCD_ShowNum(2,1,0,4);//刷新顯示LCD_ShowString(1,1,"zxy I Love You ");LCD_ShowString(1,16,"!");LCD_ShowNum(2,1,520,3);LCD_ShowNum(2,6,1314,4);LCD_ShowString(2,10,"  mua !");}else{LCD_ShowString(1,14,"ERR");//如果密碼不等于6666,顯示ERRLCD_ShowNum(2,1,0,4);//刷新顯示Password=0;//密碼清零Count=0;//計數清零}}if(KeyNum==12){//清空當前密碼LCD_ShowString(1,14,"   ");//刷新當前狀態LCD_ShowNum(2,1,0,4);//刷新顯示Password=0;//密碼清零Count=0;//計數清零}}
}

MatrixKey.c

//MatrixKey.c#include <STC89C5xRC.H>
#include	"Delay.h"
#include	"LCD1602.h"
#include	"MatrixKey.h"//矩陣按鍵源代碼unsigned char MatrixKey(){unsigned char KeyNumber=0;//矩陣按鍵第一列P1=0xFF;P13=0;if(P17==0){Delay(20);while(P17==0);//防抖操作Delay(20);KeyNumber=1;}if(P16==0){Delay(20);while(P16==0);Delay(20);KeyNumber=5;}if(P15==0){Delay(20);while(P15==0);Delay(20);KeyNumber=9;}if(P14==0){Delay(20);while(P14==0);Delay(20);KeyNumber=13;}//矩陣按鍵第二列P1=0xFF;P12=0;if(P17==0){Delay(20);while(P17==0);Delay(20);KeyNumber=2;}if(P16==0){Delay(20);while(P16==0);Delay(20);KeyNumber=6;}if(P15==0){Delay(20);while(P15==0);Delay(20);KeyNumber=10;}if(P14==0){Delay(20);while(P14==0);Delay(20);KeyNumber=14;}//矩陣按鍵第三列P1=0xFF;P11=0;if(P17==0){Delay(20);while(P17==0);Delay(20);KeyNumber=3;}if(P16==0){Delay(20);while(P16==0);Delay(20);KeyNumber=7;}if(P15==0){Delay(20);while(P15==0);Delay(20);KeyNumber=11;}if(P14==0){Delay(20);while(P14==0);Delay(20);KeyNumber=15;}//矩陣按鍵第四列P1=0xFF;P10=0;if(P17==0){Delay(20);while(P17==0);Delay(20);KeyNumber=4;}if(P16==0){Delay(20);while(P16==0);Delay(20);KeyNumber=8;}if(P15==0){Delay(20);while(P15==0);Delay(20);KeyNumber=12;}if(P14==0){Delay(20);while(P14==0);Delay(20);KeyNumber=16;}return KeyNumber;
}

MatrixKey.h

//MatrixKey.h#ifndef __MatrixKey_H__
#define __MatrixKey_H__//矩陣按鍵頭文件unsigned char MatrixKey();
#endif

LCD1602.c

//LCD1602.c#include <STC89C5xRC.H>
//LCD1602源代碼//引腳配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0//函數定義:
/*** @brief  LCD1602延時函數,12MHz調用可延時1ms* @param  無* @retval 無*/
void LCD_Delay()		//@11.0592MHz
{unsigned char i, j;i = 11;j = 190;do{while (--j);} while (--i);
}/*** @brief  LCD1602寫命令* @param  Command 要寫入的命令* @retval 無*/
void LCD_WriteCommand(unsigned char Command)
{LCD_RS=0;LCD_RW=0;LCD_DataPort=Command;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief  LCD1602寫數據* @param  Data 要寫入的數據* @retval 無*/
void LCD_WriteData(unsigned char Data)
{LCD_RS=1;LCD_RW=0;LCD_DataPort=Data;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief  LCD1602設置光標位置* @param  Line 行位置,范圍:1~2* @param  Column 列位置,范圍:1~16* @retval 無*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{if(Line==1){LCD_WriteCommand(0x80|(Column-1));}else if(Line==2){LCD_WriteCommand(0x80|(Column-1+0x40));}
}/*** @brief  LCD1602初始化函數* @param  無* @retval 無*/
void LCD_Init()
{LCD_WriteCommand(0x38);//八位數據接口,兩行顯示,5*7點陣LCD_WriteCommand(0x0c);//顯示開,光標關,閃爍關LCD_WriteCommand(0x06);//數據讀寫操作后,光標自動加一,畫面不動LCD_WriteCommand(0x01);//光標復位,清屏
}/*** @brief  在LCD1602指定位置上顯示一個字符* @param  Line 行位置,范圍:1~2* @param  Column 列位置,范圍:1~16* @param  Char 要顯示的字符* @retval 無*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{LCD_SetCursor(Line,Column);LCD_WriteData(Char);
}/*** @brief  在LCD1602指定位置開始顯示所給字符串* @param  Line 起始行位置,范圍:1~2* @param  Column 起始列位置,范圍:1~16* @param  String 要顯示的字符串* @retval 無*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++){LCD_WriteData(String[i]);}
}/*** @brief  返回值=X的Y次方*/
int LCD_Pow(int X,int Y)
{unsigned char i;int Result=1;for(i=0;i<Y;i++){Result*=X;}return Result;
}/*** @brief  在LCD1602指定位置開始顯示所給數字* @param  Line 起始行位置,范圍:1~2* @param  Column 起始列位置,范圍:1~16* @param  Number 要顯示的數字,范圍:0~65535* @param  Length 要顯示數字的長度,范圍:1~5* @retval 無*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');}
}/*** @brief  在LCD1602指定位置開始以有符號十進制顯示所給數字* @param  Line 起始行位置,范圍:1~2* @param  Column 起始列位置,范圍:1~16* @param  Number 要顯示的數字,范圍:-32768~32767* @param  Length 要顯示數字的長度,范圍:1~5* @retval 無*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{unsigned char i;unsigned int Number1;LCD_SetCursor(Line,Column);if(Number>=0){LCD_WriteData('+');Number1=Number;}else{LCD_WriteData('-');Number1=-Number;}for(i=Length;i>0;i--){LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');}
}/*** @brief  在LCD1602指定位置開始以十六進制顯示所給數字* @param  Line 起始行位置,范圍:1~2* @param  Column 起始列位置,范圍:1~16* @param  Number 要顯示的數字,范圍:0~0xFFFF* @param  Length 要顯示數字的長度,范圍:1~4* @retval 無*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i,SingleNumber;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){SingleNumber=Number/LCD_Pow(16,i-1)%16;if(SingleNumber<10){LCD_WriteData(SingleNumber+'0');}else{LCD_WriteData(SingleNumber-10+'A');}}
}/*** @brief  在LCD1602指定位置開始以二進制顯示所給數字* @param  Line 起始行位置,范圍:1~2* @param  Column 起始列位置,范圍:1~16* @param  Number 要顯示的數字,范圍:0~1111 1111 1111 1111* @param  Length 要顯示數字的長度,范圍:1~16* @retval 無*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');}
}

?LCD1602.h

//LCD1602.h#ifndef __LCD1602_H__
#define __LCD1602_H__//LCD1602頭文件
//用戶調用函數:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);#endif

?Delay.c

//Delay.c#include <STC89C5xRC.H>
#include <INTRINS.H>//延時函數
void Delay(unsigned int xms)		//@11.0592MHz
{unsigned char i, j;while(xms){i = 2;j = 199;do{while (--j);} while (--i);xms--;}
}

Delay.h

//Delay.h#ifndef __Delay_H__
#define __Delay_H__//延時函數頭文件
void Delay(unsigned int xms);
#endif

運行效果圖:

第一步:

初始化顯示,按下開關后顯示如下

第二步:

在矩陣按鍵中按S1-S10,對應數字1-9,S10是0,輸入密碼(可以自己修改)

第三步:

輸入完后,按S11(S12是清空當前輸入,S13-S16,暫時沒有綁定按鍵,可自行設置)確定驗證密碼,正確右上角顯示OK(2秒),錯誤顯示ERR

  • 注:因為編譯器會將0開頭的數字認為是八進制,因次想要實現0開頭的密碼必須使用字符串來,在本代碼中我將忽略第一個0的情況,例如:0123,輸入123,就可以實現顯示0123時密碼正確

第四步:

密碼正確會,2秒后會跳轉新界面,顯示你表白的內容(可自己更改)

?代碼解析與教程:

延時函數Delay
  • 包含源代碼與頭文件,不需要知道怎么實現的會用即可,后續使用,直接將頭文件和源代碼拿過來用即可;例如:Delay(1000)就是延遲1秒(單位毫秒)
?LCD1602
  • 包含源代碼與頭文件,不需要知道怎么實現的會用即可,后續使用,直接將頭文件和源代碼拿過來用即可;使用格式:(參考江科大的視頻素材)

  • LCD1602相關重要知識:
    • LCD1602有兩上下兩行顯示屏,每行各有16個小顯示屏,如上圖中的LCD_ShowString(1,3,"Hello"),第一個參數是第一行還是第二行,第2個參數是對應第幾行的第幾個小顯示屏,最后一個是輸出的東西,同理,到LCD_ShowNum(1,9,123,3)里,前三個和前面一樣,最后一個參數是顯示的位數,不夠就在前面補0,例如輸入1,參數為4,顯示就是0001,輸入23,參數為3,顯示就是023

  • 上圖是LCD1602的開發原理模塊圖,由圖可知,P10-P17是控制顯示屏的重點;像矩陣那樣,S1,由P17和P13控制,同理,其他按鍵一樣,由于開發板限制,我們一般使用列遍歷來控制按鍵,例如:S1,S5,S9,S13他們四個共用P13,所以將其為1列,將P13設定為1,P17設定為0,S1就會亮,其他按鍵同理。
?MatrixKey模塊
  • 包含源代碼與頭文件,需要知道怎么實現,會用
  • 如上LCD1602相關知識所言,將P1=0xFF,就可以實現將所有的IO接口設定為1,這時只需要將上述的原理圖拿出來,就可以控制哪個亮了,如下:
//矩陣按鍵第四列P1=0xFF;P10=0;if(P17==0){Delay(20);while(P17==0);Delay(20);KeyNumber=4;}if(P16==0){Delay(20);while(P16==0);Delay(20);KeyNumber=8;}if(P15==0){Delay(20);while(P15==0);Delay(20);KeyNumber=12;}if(P14==0){Delay(20);while(P14==0);Delay(20);KeyNumber=16;}return KeyNumber;

將其他都設置成1之后,又將P10設為0,打開第四列,判斷P17是否按下(看原理圖,也就是第四個按鍵),隨后加上防抖操作(中間那三行),然后按下之后,執行KeyNumber=4;代碼;以此類推即可。

?效果視頻:

(51單片機)矩陣按鍵密碼鎖表白(C語言代碼編撰)(矩陣按鍵

?注:該代碼是本人自己所寫,可能不夠好,不夠簡便,歡迎大家指出我的不足之處。如果遇見看不懂的地方,可以在評論區打出來,進行討論,或者聯系我。上述內容全是我自己理解的,如果你有別的想法,或者認為我的理解不對,歡迎指出!!!如果可以,可以點一個免費的贊支持一下嗎?謝謝各位彥祖亦菲!!!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/75899.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/75899.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/75899.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

檢測手機插入USB后,自動啟動scrcpy的程序

博主寫了一個小工具scrcpyAuto&#xff0c;檢測手機插入電腦USB后&#xff0c;自動啟動scrcpy。 這樣只要程序運行&#xff0c;手機接入主機就會有scrcpy大屏出現&#xff0c;方便了很多。 1、程序會最小化到系統托盤中。 2、博主沒有設計得太復雜&#xff0c;所以程序開機啟動…

使用Scade實現神經網絡算法

在ERTS2022中&#xff0c;ANSYS 發表了使用Scade實現神經網絡AI算法的相關工作。論文題目為《Programming Neural Networks Inference in a Safety-Critical Simulation-based Framework》 背景與挑戰 神經網絡在安全關鍵系統中的應用&#xff1a;隨著嵌入式系統中自主性的引入…

Next.js + SQLite 項目 Docker 生產環境部署方案

以下是完整的 Next.js SQLite 項目 Docker 生產環境部署方案&#xff1a; 1. 項目結構準備 your-project/ ├── prisma/ │ ├── schema.prisma │ └── migrations/ ├── app/ ├── lib/ ├── Dockerfile ├── docker-compose.yml ├── .dockerignore └…

MCU軟件開發使用指針有哪些坑?

目錄 1、空指針訪問 2、野指針&#xff08;未初始化的指針&#xff09; 3、指針越界 4、內存泄漏 5、懸空指針 6、指針類型不匹配 7、多任務環境中的指針訪問 8、對齊問題 在MCU軟件開發中&#xff0c;使用指針雖然可以提高程序的靈活性和性能&#xff0c;但也存在許多…

【SPSS/EXCEl】主成分分析構建__綜合評價指數

學習過程中實驗操作的記錄 1.數據準備和標準化&#xff1a; (1)區分正負相關性:判斷每個因子是正向指標還是負向指標,計算每個的最大值和最小值 (2) 標準化: Min-Max標準化 Min-Max標準化&#xff08;最大最小值法&#xff09;&#xff1a; 將數據映射到指定的區間&#xff…

selenium安裝,以及瀏覽器驅動下載詳細步驟

1.下載谷歌瀏覽器Chromedriver 查看谷歌瀏覽器版本 2.去官網下載Chromedriver 114之前的版本鏈接chromedriver.storage.googleapis.com/index.html 選擇和瀏覽器版本較接近的點擊進行下載 125之后的版本鏈接Chrome for Testing availability (googlechromelabs.github.io)&a…

LabVIEW 油井動液面在線監測系統?

項目背景 傳統油井動液面測量依賴人工現場操作&#xff0c;面臨成本高、效率低、安全風險大等問題。尤其在偏遠地區或復雜工況下&#xff0c;測量準確性與時效性難以保障。本系統通過LabVIEW虛擬儀器技術實現硬件與軟件深度融合&#xff0c;為油田智能化轉型提供實時連續監測解…

C++標準庫 —— round 函數用法詳解

round 是 C/C 標準庫中的一個數學函數&#xff0c;用于對浮點數進行四舍五入取整。以下是它的詳細用法說明&#xff1a; 目錄 1. 基本語法 2. 功能描述 3. 使用示例 示例1&#xff1a;基本用法 示例2&#xff1a;保留小數位 4. 相關函數對比 5. 注意事項 6. 實際應用場景…

嵌入式C語言11(宏/程序的編譯過程)

宏 ? 基本概念 C語言中可以利用宏定義實現文本的快速替換&#xff0c;注意&#xff1a;宏定義是單純的文本替換&#xff0c;不檢查語法是否合法。 C語言標準中提供了很多的預處理指令&#xff0c;比如#include、#pragma…以#開頭的都屬于預處理指令。 預處理指令指的是在…

【湖南大學】2025我們該如何看待DeepSeek

大家好&#xff0c;我是櫻木。 DeepSeek 官方網站&#xff1a;https://www.deepseek.com/ 一、DeepSeek 到底是什么&#xff1f; TA 到底厲害在哪里&#xff1f; 故事從 ChatGPT 說起 去年我們看到 Open AI 發布ChatGPT 后&#xff0c;全球的注意力到了 AI 身上。 我們來拆…

【區塊鏈安全 | 第三十三篇】備忘單

文章目錄 備忘單操作符優先級備忘單ABI 編碼和解碼函數bytes 和 string 的成員Address 的成員區塊與交易屬性校驗和斷言數學和加密函數合約相關類型信息函數可見性說明符修飾符備忘單 操作符優先級備忘單 以下是操作符的優先級順序,按評估順序列出: 優先級描述操作符1后綴遞…

Python----計算機視覺處理(Opencv:道路檢測之車道線顯示)

完整版&#xff1a;Python----計算機視覺處理&#xff08;Opencv:道路檢測完整版&#xff1a;透視變換&#xff0c;提取車道線&#xff0c;車道線擬合&#xff0c;車道線顯示&#xff09; 一、透視變換 將透視變換之后的圖像再繼續透視變換為原圖像 可參考Python----計算機視…

26屆Java暑期實習面經,騰訊視頻一面

短鏈接的生成原理 如何解決短鏈接生成的哈希沖突問題 如何加快從短鏈接到原鏈接的重定向過程 TCP 和 UDP 協議 如何理解 TCP 是面向連接的 為什么 TCP 的握手是 3 次 IO 模式 是否有真正寫過一個底層的 Socket 通信 MySQL 的事務隔離級別 MVCC 機制 什么叫服務的并行 為什么能基…

Windows注冊鼠標鉤子,獲取用戶選中的文本

注冊鼠標鉤子 // 注冊鼠標鉤子 HHOOK hMouseHook; hMouseHook SetWindowsHookEx(WH_MOUSE_LL, MouseProc, GetModuleHandle(NULL), 0);// 取消鼠標鉤子 UnhookWindowsHookEx(hMouseHook); hMouseHook nullptr; 上述代碼中MouseProc方法用于處理系統的鼠標消息 處理鼠標消息…

flink cdc的source數據流如何配置事件時間,如何設置時間語義,分配時間戳并生成水位線

在 Flink CDC 中為 Source 數據流配置事件時間需要結合時間語義設置、時間戳分配和水位線生成三個核心步驟。以下是具體配置方法及注意事項&#xff1a; 1. 設置時間語義 Flink 默認使用處理時間&#xff08;Processing Time&#xff09;&#xff0c;需顯式指定事件時間語義&a…

C++ 指針類型轉換全面解析與最佳實踐

文章目錄 C 指針類型轉換全面解析與最佳實踐1. 隱式轉換基類和派生類指針 2. 顯式轉換(1) static_cast(2) dynamic_cast(3) reinterpret_cast(4) const_cast 3. C 風格轉換4. 常見問題與注意事項5. 總結最佳實踐 C 指針類型轉換全面解析與最佳實踐 在 C 中&#xff0c;指針類型…

批量將 txt/html/json/xml/csv 等文本拆分成多個文件

我們的文本文件太大的時候&#xff0c;我們通常需要對文本文件進行拆分&#xff0c;比如按多少行一個文件將一個大的文本文件拆分成多個小的文本文件。這樣我們在打開或者傳輸的時候都比較方便。今天就給大家介紹一種同時對多個文本文件進行批量拆分的方法&#xff0c;可以快速…

ARM 匯編啟動代碼詳解:從中斷向量表到中斷處理

ARM 匯編啟動代碼詳解&#xff1a;從中斷向量表到中斷處理 引言 在嵌入式系統開發中&#xff0c;ARM 處理器&#xff08;如 Cortex-A 系列&#xff09;的啟動代碼是系統初始化和運行的基礎。啟動代碼通常包括中斷向量表的創建、初始化硬件狀態&#xff08;如關閉緩存和 MMU&a…

4.7學習總結 可變參數+集合工具類Collections+不可變集合

可變參數&#xff1a; 示例&#xff1a; public class test {public static void main(String[] args) {int sumgetSum(1,2,3,4,5,6,7,8,9,10);System.out.println(sum);}public static int getSum(int...arr){int sum0;for(int i:arr){sumi;}return sum;} } 細節&#xff1a…

2023年藍橋杯第十四屆CC++大學B組真題及代碼

目錄 1A&#xff1a;日期統計 解析代碼_暴力_正解 2B&#xff1a;01串的熵 解析代碼_暴力_正解 3C&#xff1a;冶煉金屬 解析代碼_暴力_正解 4D&#xff1a;飛機降落 解析代碼_暴力dfs_正解 5E&#xff1a;接龍數列 解析代碼_dp_正解 6F&#xff1a;島嶼個數 解析代…