51單片機50個實例代碼_【附代碼】51單片機電子密碼鎖教程

簡介

大家好,這篇文章的內容是關于如何用51單片機來制作一個電子密碼鎖的教程,通過這篇教程可以讓剛入門的朋友了解矩陣鍵盤、LCD1602的使用方法,以及密碼輸入和修改的程序介紹,我會對每個部分進行詳細的介紹。
首先我們來看一下這個密碼鎖要實現哪些功能:
可通過矩陣鍵盤進行密碼的輸入和修改。
可通過LCD1602進行界面的顯示。
在了解了我們需要實現的功能后我們就可一開始進行軟硬件的設計了。本次密碼鎖的硬件部分我使用Proteus來進行仿真。

硬件設計

首先我們進行硬件的設計,密碼鎖的硬件部分還是很簡單的,首先我們需要一個51單片機的最小系統,在Proteus中芯片并不需要外接晶振,直接放上芯片就可以使用,我選擇AT89C52單片機,并給P0口外接一排上拉電阻來提升驅動能力,c299ec978332e6ac66e3440c97e4cf8b.png
接下來是界面顯示部分,之前說過顯示部分使用的是LCD1602,LCD的電路如下圖,5fdd9b469da314052394f4a77df0c757.png
首先我來簡單介紹一下LCD1602的引腳功能:
VSS:接地
VDD:接電源
V0:對比度調整端,使用時可接電位器接地進行對比度調節
RS:寄存器選擇,高電平選擇數據寄存器,低電平選擇指令寄存器
RW:讀寫信號線,高電平讀,低電平寫
E:使能端,下降沿寫操作,高電平讀操作
DB0:數據總線最低位
DB1:數據總線1位
DB2:數據總線2位
DB3:數據總線3位
DB4:數據總線4位
DB5:數據總線5位
DB6:數據總線6位
DB7:數據總線7位
A:背光電源正極
K:背光電源負極
我們可以看到LCD1602一共有上述16個引腳,我來根據圖中的接法來介紹一下各個引腳的用法。
VDD和A分別用于給LCD和背光板供電,VSS和K為負極接地,仿真里面我們不需要接A、K引腳。
V0腳就是圖中的VEE,這個腳使用來調節LCD的字符對比度,直接接地的時候對比度最高,不過容易出現鬼影,在實際使用的時候我們可以將這個腳通過一個10K的電位器接地來進行對比度的調節,在仿真里我就直接接地了。
RS腳是寄存器選擇腳,這個腳我接到單片機的P3.5腳上,我們通過改變這個腳的高低電平可以選擇給LCD發送數據還是發送指令。
RW腳是用來設置對LCD的讀寫操作的,因為在這里我們不需要對LCD進行讀取操作,所以我就直接將這個腳接地了,也可以通過IO口來對RW進行設置。
E腳是LCD的使能端,仿真中接的單片機的P3.4腳。
最后的D0~D7腳就是LCD的數據腳,我們將這8個腳接到單片機接了上拉電阻的P0腳,這樣就可以給LCD發送指令或數據了。
然后我們需要一個鍵盤進行密碼的輸入和修改,在Proteus里我們可以直接搜索KEYPAD來添加矩陣鍵盤,在這里我們使用一個3*4的鍵盤就夠了,引腳與單片機的連接如下,ec0e32478c8ec5b1500cc6f04f164f90.png
也可以使用按鍵自己連接一個矩陣鍵盤有助于對程序的理解。

軟件設計

在介紹完硬件部分的設計后,我們就可以開始編寫程序了,首先講一下矩陣鍵盤的程序,

    int keyboard()            //鍵盤掃描    {        P2 = 0xf7;        k = P2;        k = k & 0xf0;        if(k == 0xf0)        {            kf = 0;        }        if(k != 0xf0)        {            delay(4);            k = P2;            k = k & 0xf0;            if(k != 0xf0)            {                switch(k)                {                    case 0xe0:                        key = 88;mod = 1;kf = 1;                        break;                    case 0xd0:                        key = 0;kf = 1;                        break;                    case 0xb0:                        key = 88;kf = 1;                        break;                    case 0x70:                        key = 88;kf = 1;                        break;                     }            }            }        P2 = 0xfb;        k = P2;        k = k & 0xf0;        if(k != 0xf0)        {            delay(4);            k = P2;            k = k & 0xf0;            if(k != 0xf0)            {                switch(k)                {                    case 0xe0:                        key = 7;kf = 1;                        break;                    case 0xd0:                        key = 8;kf = 1;                        break;                    case 0xb0:                        key = 9;kf = 1;                        break;                    case 0x70:                        key = 88;kf = 1;                        break;                }            }        }        P2 = 0xfd;        k = P2;        k = k & 0xf0;        if(k != 0xf0)        {            delay(4);            k = P2;            k = k & 0xf0;            if(k != 0xf0)            {                switch(k)                {                    case 0xe0:                        key = 4;kf = 1;                        break;                    case 0xd0:                        key = 5;kf = 1;                        break;                    case 0xb0:                        key = 6;kf = 1;                        break;                    case 0x70:                        key = 88;kf = 1;                        break;                }            }        }        P2 = 0xfe;        k = P2;        k = k & 0xf0;        if(k != 0xf0)        {            delay(4);            k = P2;            k = k & 0xf0;            if(k != 0xf0)            {                switch(k)                {                    case 0xe0:                        key = 1;kf = 1;                        break;                    case 0xd0:                        key = 2;kf = 1;                        break;                    case 0xb0:                        key = 3;kf = 1;                        break;                    case 0x70:                        key = 88;kf = 1;                        break;                }            }        }            return key;         }

上面這一段是矩陣鍵盤的程序,通過改變P1口的值來進行行列檢測,同時增加一個標志位kf來判斷按鍵是否松開。有了按鍵驅動下面就可以編寫密碼輸入的函數了:

    void input()    //密碼輸入函數    {        keyboard();        if(key!=88)        {            while(kf)            {                keyboard();            }            s = (char)key;            s = s | 0x30;            lcd_pos(d);            write_date(s);            in[i] = key;            i++;            d++;                    key = 88;        }            }

51ec01d6327eb4fb45075d8711239bed.png
在密碼輸入函數里我們調用鍵盤掃描函數,當有按鍵按下時我們就將對應的鍵值保存到輸入密碼的數組里,然后將每一個輸入的按鍵的鍵值顯示在LCD的顯示屏上。LCD的驅動程序會在下面講解。
現在要開始編寫LCD的驅動用來顯示輸入的數字,我們首先需要兩個函數,分別給LCD發送數據和指令,程序如下:

    void write_com(uchar com)        //LCD寫指令    {        P0=com;        rs=0;        lcden=0;        delay(10);        lcden=1;        delay(10);        lcden=0;    }    void write_date(uchar date)        //LCD寫數據    {        P0=date;        rs=1;        lcden=0;        delay(10);        lcden=1;        delay(10);        lcden=0;    }

我們可以通過寫數據的函數發送給LCD要顯示的數據,可以通過寫命令函數向LCD發送指令來對LCD進行相應的設置,相關的指令大家可以自行到網上查閱,以下列出的函數分別用來改變光標位置,LCD初始化設置和清屏。

    void lcd_pos(uchar pos)        //設置LCD顯示位置    {                                write_com(pos | 0x80);      }    void init()        //LCD初始化    {        write_com(0x38);        delay(20);        write_com(0x0f);        delay(20);        write_com(0x06);        delay(20);        write_com(0x01);        delay(20);            write_com(0x0c);        delay(20);    }    void clear()        //LCD清屏    {        write_com(0x01);        delay(20);    }

接下來我們可以對輸入的密碼進行判斷,

    void judge()        //密碼判斷函數    {        if(i==6)        {            for(f = 0;f<6;f++)            {                if(password[f] == in[f])                m++;                }            if(m==6)            {                es = 0;                clear();                lcd_pos(0x03);                write_dates("Welcome!");                delay(1200);                clear();                lcd_pos(0x00);                write_dates("Password:");                lcd_pos(0x45);                write_dates("******");                }            else            {                es++;                clear();                lcd_pos(0x04);                write_dates("Error!");                delay(1200);                if(es == 3)                {                    lcd_pos(0x45);                    write_dates("WARNING");                    delay(5000);                    es = 0;                        clear();                }                lcd_pos(0x00);                write_dates("Password:");                lcd_pos(0x45);                write_dates("******");                                    }            m = 0;            i = 0;            d = 0x45;        }    }

bf59ffc262a9a7c2ab37b0eb97aa477a.pngaac37c41897d46669b1bd82239f007f7.png
密碼鎖的密碼為6位,當輸入6位密碼后我們就可以對密碼進行判斷,判斷過程就是將輸入密碼的數組與保存的密碼的數組通過循環進行比較,當輸入密碼正確后就會顯示歡迎界面,等待一段時間再返回密碼輸入界面,如果密碼輸入錯誤則進入錯誤界面,然后返回密碼輸入界面,我們可以檢測錯誤的次數如果錯誤次數太多可以進行類似延長等待時間等操作。
最后就是密碼修改的操作。

    void change()        //修改密碼函數    {        if(mod==1)        {            lcd_pos(0x00);            write_dates("OldPassword:");            input();            if(i==6)            {                for(f = 0;f<6;f++)                {                    if(password[f] == in[f])                    m++;                    }                if(m==6)                {                    mod=2;                    clear();                    lcd_pos(0x45);                    write_dates("******");                    }                else                {                    clear();                    lcd_pos(0x04);                    write_dates("Error!");                    delay(1200);                    lcd_pos(0x00);                    write_dates("Password:");                    lcd_pos(0x45);                    write_dates("******");                        mod=0;                                    }                m = 0;                i = 0;                d = 0x45;            }            }        if(mod==2)        {            lcd_pos(0x00);            write_dates("NewPassword:");            input();            if(i==6)            {                for(f = 0;f<6;f++)                {                    password[f] = in[f];                }                    lcd_pos(0x44);                write_dates("success!");                delay(1200);                clear();                lcd_pos(0x00);                write_dates("Password:");                lcd_pos(0x45);                write_dates("******");                i = 0;                mod = 0;                d = 0x45;            }        }    }

d3040d861f609b913963986891183be1.pngc5a75feb261e38dbcb95e39f2a4546ab.png893c8fde392f54bf45198b75988f9ce6.png
修改密碼需要我們先輸入正確密碼,然后會進入修改界面,再次輸入新密碼就可以保存了。過程就是用循環來更新數組內的值,這樣一個簡單的密碼鎖就做好了,不過這樣的鎖有一個缺點,就是設置的密碼不會保存,等單片機再次上電后就會恢復到最初始的密碼,要想在斷電后繼續保存密碼,我們可以使用EEPROM來進行密碼的保存,由于篇幅原因,我會在之后單獨介紹EEPROM的讀寫操作。感謝各位的觀看。

b2c1f1ea8d67fc0316ecf85361f0bfe6.gif

點“閱讀原文”,文章!

相關產品推薦:樹莓派4B 現貨,268元起!

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

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

相關文章

旋轉的正方體

<!DOCTYPE html><html lang"zh-cmn-Hans"><head><meta charset"utf-8" /><title>backface-visibility_CSS參考手冊_web前端開發參考手冊系列</title><meta name"author" content"Joy Du(飄零霧雨),…

8數據提供什么掩膜產品_博碩能為你提供什么產品?

自動噴漆設備應用于線條、木門、櫥柜、樓梯、套房家具、辦公家具、木飾面板、外墻保溫裝飾一體板板等產品領域&#xff0c;針對NC、PU、UV、水性漆和氟碳漆等不同種類的油漆&#xff0c;進行自動化噴涂和干燥作業。自動噴漆設備有多種規格型號&#xff0c;分為不同的噴涂方式。…

python3 實現對比conf 文件差異

用法&#xff1a; ./conf.py nginx1.conf nginx2.conf > diff.htmlconf.py#!/usr/bin/python import difflib import sys #### Usage: compare_nginx.conf.py filename1 filename2 >diff.html try:textfile1 sys.argv[1]textfile2 sys.argv[2] except Exception as…

mysql----innodb統計信息

對innodb 統計信息的控制可以通過如下幾個常用的variables 來實現 1、innodb_stats_persistent&#xff1a; 這個參數控制著innodb的統計信息是否持久化到磁盤&#xff0c;先說明一下持久化到磁盤是什么意思&#xff1b;通常來說統計信息只保存在內存中&#xff0c;也就是說如果…

linux pid t 頭文件_linux系統調用相關頭文件

Linux C 一些函數 所屬的頭文件 2011-03-07 10:25:07分類&#xff1a; LINUX在編寫程序時&#xff0c;有時總是不記得所使用的函數在哪個庫函數中。現在先把自己以前經常用到的函數頭文件總結一下。 有不對的地方還請指教。1&#xff0c;系統調用 文件的操作函數#inlclude &…

jsp頁面驗證碼(完整實例)

項目結構如下&#xff0c;MyEclipse中新建一個Web Project&#xff0c;取名servlet 1、src下new一個servlet類 package com.servlet;import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOExcept…

開源oa_圈子哥推薦一款基于 Spring Boot 開發 OA 開源產品,學習/搞外快都是不二選擇!...

點擊上方藍字關注「程序員的技術圈子」今天圈子哥給大家推薦一套Spring Boot 開發 OA系統&#xff0c;系統功能齊全&#xff0c;不管是用來學習或者搞外快都是不錯的選擇&#xff0c;clone下來吧&#xff01;辦公自動化(OA)是面向組織的日常運作和管理&#xff0c;員工及管理者…

iOS網絡編程實踐--NSStream實現TCP Socket iPhone客戶端

客戶端我們使用iPhone應用程序&#xff0c;畫面比較簡單。點擊發送按鈕&#xff0c;給服務器發送一些字符串過去。點擊接收按鈕就會從服務器讀取一些字符串&#xff0c;并且顯示在畫面上。 有關客戶端應用的UI部分不再介紹了&#xff0c;我們直接看代碼部分&#xff0c;Socket客…

Mocha 和 Chai 入門初探

轉載自樓主個人博客 Mocha 和 Chai 入門初探Chai 在和 jest 作比較的時候, 兩者主要的不同就是 jest 的集成度比較高內置斷言庫, 而 mocha 需要搭配額外的斷言庫, 在此選擇了比較流行的 chai 作為斷言庫. 風格的選擇 其中 chai 又有好幾種斷言風格, 我們經常見到的其實就是 BDD…

ios把數據傳遞到另一個頁面_IOS 應用之間的跳轉和數據傳遞詳解

說明&#xff1a;本文介紹app如何打開另一個app,并且傳遞數據。一、簡單說明新建兩個應用&#xff0c;分別為應用A和應用B.實現要求:在appA的頁面中點擊對應的按鈕&#xff0c;能夠打開appB這個應用。1.新建兩個應用&#xff0c;分別為A和B.142354418874108[1].png150002248248…

Libevent初探

Libevent 是一個用C語言編寫的、輕量級的開源高性能網絡庫&#xff0c;主要有以下幾個亮點&#xff1a;事件驅動&#xff08; event-driven&#xff09;&#xff0c;高性能;輕量級&#xff0c;專注于網絡&#xff0c;不如 ACE 那么臃腫龐大&#xff1b;源代碼相當精煉、易讀&am…

ServerSocketChannel API用法

java.nio.channels 類 ServerSocketChannel java.lang.Objectjava.nio.channels.spi.AbstractInterruptibleChanneljava.nio.channels.SelectableChanneljava.nio.channels.spi.AbstractSelectableChanneljava.nio.channels.ServerSocketChannel所有已實現的接口&#xff1a; C…

jq分頁 不刷新頁面_jQuery無刷新分頁完整實例代碼

本文實例講述了jQuery無刷新分頁實現方法。分享給大家供大家參考&#xff0c;具體如下&#xff1a;這款jQuery分頁示例&#xff0c;是分頁經典形式&#xff0c;兼容性也做的好&#xff0c;網頁上的分頁代碼&#xff0c;分享給大家。運行效果截圖如下&#xff1a;在線演示地址如…

為什么要寫年終總結

2016只剩下不到百分之一的時間了&#xff0c;網上陸續看到各種企業或個人的總結或盤點&#xff0c;公司也必須規定每個員工要做年度工作總結&#xff0c;或許是環境釋然&#xff0c;心里也有無數次要做總結的念頭&#xff0c;尤其是月末年末這種感覺更重&#xff0c;但卻沒靜下…

特別慢_背什么都特別慢,該怎么提高記憶力?

考研是一項全方位的比拼&#xff0c;除了每天進行知識點的復習&#xff0c;還要做題、總結&#xff0c;最后還得進行背誦記憶&#xff0c;其實什么科目都需要背的&#xff0c;就算數學&#xff0c;該記的概念和公式也是要記憶的&#xff0c;因為會做題更快&#xff0c;提高效率…

tiny4412u-boot燒寫及根文件系統制作(不進入終端問題)

http://m.blog.csdn.net/article/details?id51400196&#xff08;轉&#xff09; VMware12 環境&#xff1a;ubuntu12.4 開發板&#xff1a;tiny4412 首先燒寫bootloader&#xff0c;我用一個8G的內存卡&#xff0c;現在不說sd卡的制作過程了&#xff0c;網上可以參考。 現在就…

第三章 中間件,3.1 萬億級數據洪峰下的分布式消息引擎(作者:馮嘉、誓嘉、塵央、牟羽)...

3.1 萬億級數據洪峰下的分布式消息引擎 前言 通過簡單回顧阿里中間件(Aliware)消息引擎的發展史&#xff0c;本文開篇于雙11消息引擎面臨的低延遲挑戰&#xff0c;通過經典的應用場景闡述可能會面臨的問題 - 響應慢&#xff0c;雪崩&#xff0c;用戶體驗差&#xff0c;繼而交易…

Linux目錄結構和常用命令

一、Linux目錄結構 你想知道為什么某些程序位于/bin下&#xff0c;或者/sbin&#xff0c;或者/usr/bin&#xff0c;或/usr/sbin目錄下嗎&#xff1f;例如&#xff0c;less命令位于/usr/bin目錄下。為什么沒在/bin中&#xff0c;或/sbin&#xff0c;或/usr/sbin目錄中&#xff1…

掛載nfs文件系統_綜合架構-day38-NFS服務補充

1.如何讓nfs永久掛載-2種方法開機自啟動文件1.vim /etc/rc.d/rc.local需要修改執行權限chmod x /etc/rc.d/rc/localmount -t nfs 172.16.1.31:/upload/ /mnt/2.vim /etc/fstab172.16.1.31:/upload /mnt nfs defaults 0 02.exportfs 加載配置生效&#xff0c;等價于優雅重啟[15:…

A Neural Algorithm of Artistic Style

本系列文章由 yhl_leo 出品&#xff0c;轉載請注明出處。 文章鏈接&#xff1a; http://blog.csdn.net/yhl_leo/article/details/53931536 1. 資源 Paper: A Neural Algorithm of Artistic StyleTensorFlow version in GitHub: anishathalye/neural-styleCaffe version in GitH…