【51单片机】萌新持续学习中《矩阵 密码锁 点阵屏》
前言:
大家好!!!
今天继续分享51单片机的有关知识,小萌新学到哪就得小小的分享一下,鼓励自己,总结复习一下,也希望对大家有所帮助。
在上一章节说的单片机的组成和原理,也分享了一些简单的案例如:led的点亮 流动等等。都是比较简单的,今天分享一些高级货色,有趣的。如矩阵密码锁,秒表,矩阵点阵屏的画面显示 动画显示。
欧克 废话不多说直接上正题。。
这里主要写出主函数,其他的头文件会在另一篇文章中完整体现。
有实物视频演示,大家可以进入主页看看奥!!!
一·矩阵密码锁
-
硬件连接:
采用4×4矩阵键盘,- 消抖与松手检测:必须添加延时函数(
Delay(10ms)
)和while(P1!=0xf0)
循环,避免误触发。
- 消抖与松手检测:必须添加延时函数(
-
密码逻辑:
- 输入:S1-S10为数字键,输入时通过
Password = Password*10 + KeyNum%10
实现密码左移存储(例:输入\"12\"即0001×10+2=0012)。 - 验证:循环比较输入值与预设密码,若完全匹配则置标志位
Flag=1
,触发开锁;否则显示\"ERR\"。 - 功能键:S11(确认)、S12(取消/清零)。
- 输入:S1-S10为数字键,输入时通过
这里主要写出主函数,其他的头文件会在另一篇文章中完整体现。
代码如下:
逻辑很简单的,学过写C语言的应该都可以理解的。
#include #include \"Delay.h\"//包含Delay头文件#include \"LCD1602.h\"//包含LCD1602头文件#include \"MatrixKey.h\"//包含矩阵键盘头文件unsigned char KeyNum;unsigned int password,count;void main(){LCD_Init();//LCD初始化LCD_ShowString(1,1,\"password:\");//LCD显示字符串while(1){KeyNum=MatrixKey();if(KeyNum)//如果有按键按下{if(KeyNum<=10){if(count<4){password*=10;//左移数字password+=KeyNum%10;//获取密码count++;}LCD_ShowNum(2,1,password,4);//更新显示}if(KeyNum==11){if(password==2005)//{LCD_ShowString(1,14,\"ok \");password=0;count=0; LCD_ShowNum(2,1,password,4);//更新显示}else{LCD_ShowString(1,14,\"err\");LCD_ShowNum(2,1,password,4);//更新显示password = 0; // 重置密码count = 0; // 重置计数}}if(KeyNum==12){password=0;count=0;LCD_ShowNum(2,1,password,4);//更新显示LCD_ShowString(1,14,\" \");}}}}
分析:
LCD_ShowString(1,1,\"password:\"); 这里是库函数类似于C语言中的printf
LCD_ShowString 显示字符串
LCD_ShowNum 显示数字
password*=10;//左移数字,二进制储存 乘10 会向前进一位 如0101 ->0110
password+=KeyNum%10;//获取密码
count++; 次数加加 4次以后会截至储存
if(KeyNum==11) //按下按键11会确定设置答案与所输入的是否一样
{
if(password==2005) //这里设置答案为2005
{
LCD_ShowString(1,14,\"ok \");//如果一样就会显示ok
password=0;
count=0;
LCD_ShowNum(2,1,password,4); //更新显示}
else
{
LCD_ShowString(1,14,\"err\");
LCD_ShowNum(2,1,password,4); //更新显示
password = 0; // 重置密码
count = 0; // 重置计数
}
}
视频:
按键密码锁
二·秒表计时
-
实现基础:使用单片机内部的定时器
-
工作模式:将T0设置为16位定时器模式。
-
计时逻辑:
-
在中断服务程序中,对中断次数进行计数。
-
秒变量满60,分钟变量加1,秒变量清零,以此类推。
-
秒表的启动、暂停、清零功能通过按键来控制状态机。
-
这里可以直接得到定时计算器的完整代码。
代码如下:
#include #include \"Delay.h\"#include \"LCD1602.h\"#include \"Timer0.h\"unsigned char Sec=55,Min=59,Hour=23;void main(){LCD_Init();Timer0Init();LCD_ShowString(1,1,\"Clock:\");LCD_ShowString(2,1,\" : : \");while(1){LCD_ShowNum(2,1,Hour,2);LCD_ShowNum(2,4,Min,2);LCD_ShowNum(2,7,Sec,2);}}void Timer0_Routine() interrupt 1{static unsigned int T0Count;TL0 = 0x18;//设置定时初值TH0 = 0xFC;//设置定时初值T0Count++;if(T0Count>=1000){T0Count=0;Sec++;if(Sec>=60){Sec=0;Min++;if(Min>=60){Min=0;Hour++;if(Hour>=24){Hour=0;}}}}}
分析:
if(T0Count>=1000) //这里是时间的演示,{T0Count=0;Sec++;if(Sec>=60)//秒60分加1{Sec=0;Min++;if(Min>=60)//分满60时加1{Min=0;Hour++;if(Hour>=24){Hour=0;}}}}
视频:
三·矩阵点阵屏图形
原理:
一个8x8 LED点阵屏由64个发光二极管组成,排列成8行×8列的矩阵。它有16个引脚:
-
行引脚 (Anodes - 阳极): 通常对应内部LED的阳极。当某一行被给予高电平(+5V),一列被给予低电平(0V/GND)时,对应位置的LED就会点亮。
-
列引脚 (Cathodes - 阴极): 通常对应内部LED的阴极。
共阳和共阴是两种主要类型,驱动逻辑相反:
-
共阳 (Common Anode): 所有LED的阳极连接在一起作为行线。要点亮一个LED,对应的行给高电平,列给低电平。
-
共阴 (Common Cathode): 所有LED的阴极连接在一起作为列线。要点亮一个LED,对应的行给低电平,列给高电平。
具体图形绘制:
可以画一个8*8的正方形,在里面画出自己的图形(1表示亮 0表示熄灭)
如
juzhen(0,0x3C);
juzhen(1,0x42);
juzhen(2,0xA9);
juzhen(3,0x85);
juzhen(4,0x85);
juzhen(5,0xA9);
juzhen(6,0x42);
juzhen(7,0x3C);
图形为笑脸
完整代码:
#include #include \"Delay.h\"#include \"juzhen.h\"sbit RCK=P3^5;sbit SCK=P3^6;sbit SER=P3^4;void _74HC595_WriteByte(unsigned char Byte){unsigned char i;for(i=0;i>i);SCK=1;SCK=0;}RCK=1;RCK=0;}void juzhen(unsigned char lie,Data){_74HC595_WriteByte(Data);P0=~(0x80>>lie);Delay(1);P0=0xFF;}void chushi(){SCK=0;RCK=0;}void main(){ chushi();while(1){juzhen(0,0x3C);juzhen(1,0x42);juzhen(2,0xA9);juzhen(3,0x85);juzhen(4,0x85);juzhen(5,0xA9);juzhen(6,0x42);juzhen(7,0x3C);}}
视频:
点阵屏图形
四·矩阵点阵屏动画
LED点阵屏采用动态扫描技术,其基本原理是:
-
每次只点亮一列(共阴)或一行(共阳)的LED
-
以极快的速度(通常>100Hz)循环扫描所有列/行
-
利用人眼的\"视觉暂留\"效应(Persistence of Vision),形成稳定的图像感知
#include #include \"Delay.h\"#include \"MatrixLED.h\"//动画数据unsigned char code Animation[]={0x3C,0x42,0xA9,0x85,0x85,0xA9,0x42,0x3C,0x3C,0x42,0xA1,0x85,0x85,0xA1,0x42,0x3C,0x3C,0x42,0xA5,0x89,0x89,0xA5,0x42,0x3C,};void main(){unsigned char i,Offset=0,Count=0;MatrixLED_Init();while(1){for(i=0;i15){Count=0;Offset+=8;//偏移+8,切换下一帧画面if(Offset>16){Offset=0;}}}}
视频
动画
总结:
单片机是一个比较复杂的学科,综合性极强,这个就需要我们更勤快的学习,总结,多运用。
原理图一定要翻好,不然有点无从下手。