51单片机基础知识学习

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、笔记主题;

51单片机基础知识学习

二、具体操作;

1.原理;

CPU驱动寄存器,寄存器驱动驱动器来控制引脚电流大小,驱动器起到扩大效果的作用,从而达到控制单片机的目的

2.点亮LED

2.1原理

首先需要知道对应LED的输出引脚,从而控制电流
在这里插入图片描述“0”为底电频,“1”为高电频
当给与的电压为0,电压较小,电压差较大,此时有电流流过,LED被点亮

2.2进制转换

我们需要对相应的寄存器赋值,但c语言在编译时不能直接打二进制数字,最好转化为十六进制

代码如下:

p2=0*fe;//11111110

2.3头文件

此时编译器还不能识别p2口,因此要先添加头文件
代码如下:

#include <REGX52.H>

2.4代码示例

#include <REGX52.H>

void main()
{
	P2=0x55;//0101 0101
	while(1)
	{
		
	}
}

3.闪烁

在之前的基础上加入一个延时器来使其闪烁
代码示例;

#include <REGX52.H>
#include <INTRINS.H>
void Delay500ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 4;
	j = 205;
	k = 187;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
	while(1)
	{
		P2=0xfe;
		Delay500ms();
		P2=0xff;
		Delay500ms();
	}
}

4.流水灯

在之前的基础上不断调节亮的LED位置

void main()
{
	while(1)
	{
		P2=0xfe;
		Delay500ms();
		P2=0xfd;
		Delay500ms();
		P2=0xfb;
		Delay500ms();
		P2=0xf7;
		Delay500ms();
		P2=0xef;
		Delay500ms();
		P2=0xdf;
		Delay500ms();
		P2=0xbf;
		Delay500ms();
		P2=0x7f;
		Delay500ms();
		
		
	}
}

5.延时器进阶

写一个1ms的延时器,需要延时多少就循环多少次

void Delay1ms(unsigned int xms)		//@12.000MHz
{
	while(xms>0){
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
	xms--;
	}
}

6.独立按键

6.1位置

在51单片机的左下方有4个独立按键

6.2控制LED

可以在头文件里找到单独的灯所处的寄存器单元,通过修改其值来控制单独的LED

P2_0=0;

6.3控制原理

按钮会改变对应位置的电频状态,通过寄存器对其状态的检测和判断语句来达到控制电路的目的

while(1)
	{
		if(P3_1==0)
		{
			P2_0=0;
		}
		else{
			P2_0=1;
		}
	}

6.4按钮控制亮灭与按键消抖

6.4.1消抖

按键在按下和松开时都会发生抖动,影响单片机的程序运行,因此需要消抖

6.4.2控制

在检测到按键按下和LED原本状态的两个条件后,进行20ms的延迟进行消抖,随后利用循环检测按键是否松开,松开后再进行20ms延迟进行消抖

if(P3_1==0 && P2_0==1)
		{
			Delay(20);//按下消抖
			while(P3_1==0);
			Delay(20);//松开消抖
			P2_0=0;
		}
		else if(P3_1==0 && P2_0==0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			P2_0=1;
		}

6.5二进制控制和取反字符

"~"为取反字符,将寄存器里的数据取反
二进制控制的初始如果是1111 1111
那么要想让其正常工作,则应该进行取反,毕竟1代表灭,0代表亮

unsigned char LED=0;
	while(1)
	{
		
		if(P3_1==0)
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			
			LED++;
			P2=~LED;
		}
	}

6.6控制LED左右

这里需要用到“<<”来进行移位,同时需要考虑到临界状态,到达最左或者最右之后复位

unsigned char num;
void main()
{
P2=~0x01;

	while(1)
	{
		if(P3_0==0)
		{
			Delay(20);//°´ÏÂÏû¶¶
			while(P3_0==0);
			Delay(20);//ËÉ¿ªÏû¶¶
			
			num++;
			if(num>=8)
				num=0;
			P2=~(0x01<<num);
		}
		if(P3_1==0)
		{
			Delay(20);//°´ÏÂÏû¶¶
			while(P3_1==0);
			Delay(20);//ËÉ¿ªÏû¶¶
			
			if(num==0)
				num=7;
			else
				num--;
			P2=~(0x01<<num);
		}
	}
}

7.静态数码管显示

7.1普通版本

先通过译码器将二进制数转化为十进制数,通过转化后的十进制数来选择点亮哪一位数码管,然后再输入一个二进制数,再放大之后调控选择某一位数码管的哪几个亮,从而显示出数字
在这里插入图片描述

7.2封装

将数码管显示代码进行封装,利用switch case来进行数位的选择,然后将显示不同东西的二进制数放在一个数组里,再进行调用。

unsigned char nixietable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

void nixie(unsigned char location,num)
{
	switch(location){
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=nixietable[num];
}

7.动态数码管显示

动态数码管显示是利用了人眼无法识别过快变化的特点,不断地进行扫描,以达到同时显示多个数字的功能。
需要应用循环进行重复,但为了显示更清楚,需要在各循环数字之间添加1ms的延迟和清零,这里用额外的connect函数来实现这个效果。

void connect()
{
  Delay(1);
	P0=0x00;
}
while(1)
		{
if(P3_0==0)
	{
		Delay(20);
		while(P3_0==0);
		Delay(20);
		
		while(1){
		nixie(1,1);
			connect();
		nixie(2,3);
			connect();
		nixie(3,2);
			connect();
		  }
		}
}

8.矩阵键盘

需要对矩阵键盘进行扫描判定,先列再行,判断其电压变化,然后打出相应的数字

P1=0xFf;
	P1_3=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynum=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynum=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynum=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynum=13;}

	P1=0xFf;
	P1_2=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynum=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynum=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynum=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynum=14;}

	P1=0xFf;
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynum=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynum=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynum=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynum=15;}

	P1=0xFf;
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);keynum=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);keynum=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);keynum=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);keynum=16;}

9.定时器

9.1原理

在这里插入图片描述

9.2逻辑运算

9.2.1按位与

按位与运算符“&”是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位都为1时,结果位才为1。参与运算的两个数均以补码出现。

9.2.1按位或

按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。当参与运算的是负数时,参与两个数均以补码出现。

9.3定时器的初始准备

定时器需要进行初始的准备,包括调整好模式,对tmod进行清零,打开计时器启动项,打开中断允许位,打开cpu接收,调整中断优先级。
然而,在清零的过程中需要进行循环清零,这时就需要逻辑运算了

void Timer0_Init()
{
	//TMOD=0X01;//ģʽ£»¶¨Ê±Æ÷
	TMOD=TMOD&0xF0;//°ÑtmodµÄµÍËÄλÇåÁ㣬¸ßËÄλ²»±ä   
	TMOD=TMOD|0x01;//°ÑtmodµÄµÍËÄλÖÃ1£¬¸ßËÄλ²»±ä   
	TF0=0;//´ò¿ªzhongduanqiÆ÷£¬ÂúÁ˶Á1
	TR0=1;//¿ØÖƶ¨Ê±»òÕß¼ÆÊýÆ÷µÄÆô¶¯Í£Ö¹£¬1ΪÆô¶¯
	TH0=0X66;
	TL0=0XFC;
	ET0=1;//T0µÄÖжÏÔÊÐíλ
	EA=1;//cpu×Ü¿ª¹Ø
	PT0=0;//ÖжÏÓÅÏȼ¶
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值