嵌入式学习--江协51单片机day3

今天学的东西挺多的,包括:自己设计的小应用,矩阵键盘,矩阵键盘密码锁,控制按键led流水灯,定时器时钟

(那个视频真的煎熬,连续两个1小时的简直要命,那个时钟也是听的似懂非懂....)

小应用

这个是朋友问我能不能用51单片机实现类似红绿灯的效果,我大体做了一下,到周末回顾的时候还会进行填充(每周末会先复习前面的知识,包括之前没有弄懂的地方,如果时间不够就不学新知识了,也会利用已经学过的知识尝试创建小的应用,巩固学过的知识)

复制代码
#include <REGX52.H>
#include "Delay.h"
#include "Nixie.h"
//设置红绿灯的等待时间为45s,由于设备限制仅
//实现红灯部分
void main()
{
	while(1)
	{
			unsigned int time=45;
			P2_7=0;
			while(time>=10)
			{
				int a,b;
				a=time/10;
				b=time%10;
				Nixie(1, 0xFF); 
       				Nixie(2, 0xFF); 
				Nixie(1,a);
				Nixie(2,b);
				time--;
				Delay(1000);
			}
			while(time>=0)
			{
				Nixie(2,time);
				time--;
				if(time<=5)
				{
					P2_7=1;
					Delay(500);
					P2_7=0;
					Delay(500);
				}
			}
	}
}

没搞明白为什么数码管没有达到红绿灯那种常亮的效果,一直在闪....

矩阵键盘

矩阵键盘由于内部电路的设计是先列后行进行设置。

先对p1初始化,设置为0表示选中当前列,若是当前列的某一行的按键被按下,就显示这个数字。

在同一时刻只能选中一个按钮

复制代码
​
#include <REGX52.H>
#include "Delay.h"
/**
  * @brief  矩阵键盘读取按键键码
  * @param  无
  * @retval KeyNumber 按下按键的键码值
  如果按键按下不放,程序会停留在子函数,松手瞬间,返回按键键码
  没有按键按下时,返回0
  */
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	P1=0xFF;
	P1_3=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	P1=0xFF;
	P1_2=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	return KeyNumber;
	
}

​

矩阵键盘

这个是实现键盘对应键位显示对应的数字

如果不加if判断,会一直显示00,但实际上是显示了被按下的按键的数字的,只是在循环体里面进行的比较快,被刷新成了0,肉眼就看不出来了

复制代码
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"
unsigned char KeyNum;
void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"MatrixKey");
	while(1)
	{
		KeyNum=MatrixKey();
		if(KeyNum)
		{
			LCD_ShowNum(2,1,KeyNum,2);
		}
	}
}

矩阵键盘密码锁

这应该算是一个小项目了吧。

复制代码
#include <REGX52.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:");
	while(1)
	{
		KeyNum=MatrixKey();
		if(KeyNum)
		{
			if(KeyNum<=10)//如果s1-s10按键按下,输入密码
			{
				if(Count<4)//如果输入次数小于4
				{
					Password*=10;//密码左移一位
					Password+=KeyNum%10;//获取一位密码
					Count++;//计次加一
				}
				LCD_ShowNum(2,1,Password,4);//更新显示
			}
			if(KeyNum==11)//如果s11按键按下,确认
			{
				if(Password==2345)//如果密码等于正确密码
				{
					LCD_ShowString(1,14,"OK ");
					Password=0;//密码清零
					Count=0;//计次清零
					LCD_ShowNum(2,1,Password,4);//更新显示
				}
				else
				{
					LCD_ShowString(1,14,"ERR");
					Password=0;//密码清零
					Count=0;//计次清零
					LCD_ShowNum(2,1,Password,4);//更新显示
				}
			}
			if(KeyNum==12)//如果s12按键按下,回退(优化直接删除)
			{
				Password/=10;
				Count--;
				LCD_ShowNum(2,1,Password,4);//更新显示
			}
		}
	}
}

时钟

时钟的内部实现还是比较复杂的,这个可能看视频听的比较迷糊,自己私下可以看使用手册的原理图帮助理解。

这个TMOD设值的方法挺巧的

计数器65535溢出,1次是一微妙,所以设置的初值是64535,使它每次清零是一毫秒

计数器一共八位,TH0是高位TL0是地位

复制代码
#include <REGX52.H>
/**
  * @brief  定时器0初始化
  * @param  
  * @retval 
  */

void Timer0Init()
{
	//TMOD=0x01;//0000 0001
	TMOD &= 0xF0;//把TMOD的低四位清零,高四位保持不变
	TMOD |= 0x01;//把TMOD的最低为置一,高四位保持不变
	TL0 = 0x18;	//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
	PT0=0;
}
/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=1000)
	{
		T0Count=0;
	}
}
*/

控制按键led流水灯

复制代码
#include <REGX52.H>
#include	"Timer0.h"
#include "Key.h"
#include <INTRINS.H>

unsigned char KeyNum,LEDMode;
void main()
{
	P2=0x0FE;
	Timer0Init();
	while(1)
	{
		KeyNum=Key();
		if(KeyNum)
		{
			if(KeyNum==1)
			{
				LEDMode++;
				if(LEDMode>=2)
					LEDMode=0;
			}

		}
	}
}
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=1000)
	{
		T0Count=0;
		if(LEDMode==0)
			P2=_crol_(P2,1);
		if(LEDMode==1)
			P2=_cror_(P2,1);
	}
}

定时器时钟

复制代码
#include <REGX52.H>
#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;
			}
		}
	}
}

江协老师讲的东西都很细致,很明白,虽然时间很长,但是有着弹幕先辈的陪伴还是能坚持下来的

相关推荐
moxiaoran57531 小时前
Python学习笔记--Django的安装和简单使用(一)
笔记·python·学习
小昭dedug2 小时前
功能安全的关键——MCU锁步核技术全解析(含真实应用方案)
单片机·嵌入式硬件
riri19192 小时前
学习笔记:数据库——事务
数据库·笔记·学习
-Camellia007-3 小时前
TypeScript学习案例(1)——贪吃蛇
javascript·学习·typescript
海尔辛3 小时前
学习黑客网络安全法
网络·学习·web安全
kovlistudio3 小时前
《零基础学机器学习》学习大纲
人工智能·学习·机器学习
负里553 小时前
STM32-模电
嵌入式硬件
BW.SU4 小时前
单片机 + 图像处理芯片 + TFT彩屏 指示灯控件
单片机·嵌入式硬件·人机交互·控件·触摸屏设计·指示灯·液晶屏
-Camellia007-4 小时前
HTTP学习
网络协议·学习·http
朝九晚五ฺ4 小时前
【算法学习】递归、搜索与回溯算法(二)
数据结构·学习·算法·深度优先