嵌入式学习--江协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;
			}
		}
	}
}

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

相关推荐
STLearner4 小时前
AI论文速读 | U-Cast:学习高维时间序列预测的层次结构
大数据·论文阅读·人工智能·深度学习·学习·机器学习·数据挖掘
阿容1234565 小时前
stm32两轮平衡小车 -04
stm32·嵌入式硬件
黑客思维者5 小时前
LLM底层原理学习笔记:Adam优化器为何能征服巨型模型成为深度学习的“速度与稳定之王”
笔记·深度学习·学习·llm·adam优化器
kk哥88996 小时前
Swift底层原理学习笔记
笔记·学习·swift
AA陈超8 小时前
Lyra学习004:GameFeatureData分析
c++·笔记·学习·ue5·虚幻引擎
zkl_zkl_8 小时前
地理信息系统学习笔记——第六章 空间数据采集与处理
笔记·学习·数据处理·数据质量·空间数据
光头程序员8 小时前
学习笔记——主攻 vite
笔记·学习
零匠学堂20258 小时前
移动学习系统,如何提升企业培训效果?
java·开发语言·spring boot·学习·音视频
TL滕9 小时前
从0开始学算法——第四天(题目参考答案)
数据结构·笔记·python·学习·算法
Hoshino.419 小时前
从0开始学习Linux——第七部分:DNS(1)
linux·网络·学习