栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

51单片机:与15系列的区别---最简单的几个模块

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

51单片机:与15系列的区别---最简单的几个模块

自从蓝桥杯省赛完成之后,就开始准备学习51单片机。相对于蓝桥杯比赛所用的板子来说,这个单片机还是有所不同的。在管脚,阴阳极上有些区分。因此,开贴做笔记记录一下。

首先介绍几个最为基础的模块。这几个模块改动都不大,原理也相近类似。

目录

一、LED灯

二、蜂鸣器

三、数码管

四、独立按键

五、矩阵按键

一、LED灯

根据原理图,可以看到LED1是P20管脚,与15系列的相同,将其置1就是亮起,置0就是熄灭。写法与15系列的单片机有些类似。

在LED灯的循环点亮的程序,与15单片机也相同。由于移位之后自动补0(亮起),所以我们要通过取反的程序来写。

 

拓展:左移右移通过库函数实现流水灯

我们需要调用另一个头文件:#include “intrins.h”,

在这里面,_cror_函数是右移;_crol_函数是左移。

注意:此函数与我们自己写的移位语句不同的是:移位语句左右移位之后,丢掉的位自动补0;而这两个函数在移位之后,移出去的位将会补在数的后面。

对于这两个函数的使用:_crol_(要移动的变量,移动几位)

例如:LED=_crol_(LED,1); 我们要提前规定LED的值是0xFE,从0xFE向左开始逐渐移动1位。(后面的数字改成2之后,就是移动两位,隔一个灯移动一次)。

程序:LED灯循环,间隔1秒。

#include "reg52.h"
#include "intrins.h"

#define uchar unsigned char
#define uint unsigned int
	
#define LED		P2//采用宏定义的方法,将P2端口进行定义

uchar i=0;

void Delayms(uint ms);//1毫秒 

void main()
{
	while(1)
	{
		LED=0xFE;
		for(i=0;i<8;i++)
		{
			LED=_crol_(LED,1);
			Delayms(1000);
		}
	}
}

void Delayms(uint ms)//1毫秒延时函数
{
	uint i,j;
	for(i=ms;i>0;i--)
	for(j=115;j>0;j--);
}

二、蜂鸣器

有源蜂鸣器:内部频率不可改变,因此音色不可改变(15单片机上的,此类蜂鸣器控制简单,只需要置1或置0即可关闭或打开)。

无源蜂鸣器:可改变内部频率、改变音色(改变延时的时间);改变占空比(改变声音大小)。(51单片机上的,需要持续输出波形才可以使用蜂鸣器)。

通过原理图可以看出,与蜂鸣器相连接的是五线四项步进电机里的P25口。打开蜂鸣器:让蜂鸣器输出持续的波形信号(时刻发生改变);关闭蜂鸣器:让蜂鸣器输出高或低的脉冲信号(不改变)

波形信号的频率:1.5—5KHZ;我们可以使用频率1KHZ的,周期T=1ms(500微秒高电平,500微秒低电平)。

注意:蜂鸣器响的时间由i和延时的时间共同控制。

           延时的时间越长,声音就越低沉;延时的时间越短,声音就越尖细。

            占空比越大,声音越大。

程序:可改变占空比来改变蜂鸣器声音大小   延时程序复制的stc软件里的。

#include "reg52.h"

#define uchar unsigned char
#define uint unsigned int
	
sbit BEEP=P2^5;

uint i=2000;

void delay_10us(uint ten_us);//延时10微秒程序


void delay_10us(uint ten_us)//延时10微秒程序
{
	while(ten_us--);
}

void main()
{
	uint i=2000;//控制蜂鸣器发出声音的时间,
	            //蜂鸣器响的时间由i和延时的时间共同控制
	while(1)
	{
		while(i--)
		{
			BEEP=0;//蜂鸣器低电平
			delay_10us(10);
			BEEP=1;//蜂鸣器高电平
			delay_10us(190);
		}
		i=0;BEEP=0;//关闭蜂鸣器
	}
}

三、数码管

1、共阳共阴极数码管:

共阳极数码管是指将所有发光二极管的阳极接到一起形成公共极(COM)的数码管,共阳极数码管在应用时应将公共极 COM 接到+5V(低电平点亮)

共阴极数码管(本单片机)是指将所有发光二极管的阴极接到一起形成公共极(COM)的数码管,共阴极数码管在应用时应将公共极 COM 接到地线GND上。(高电平点亮)

所以这个板子上的数码管显示与15系列的正好相反。

2、74HC245芯片和74HC138芯片

   要学会阅读芯片手册。

      74HC245芯片是有个DIR管脚的,该管脚控制了电流的输出方向,高电平的时候是从A-B输出的;低电平是从B-A输出的。我们需要的是高电平。

      74HC138芯片俗称38译码器,三个输入端(A0、A1、A2),8个输出端(Y0、Y1、Y2、Y3、Y4、Y5、Y6、Y7)。通过阅读芯片手册中的真值表来了解如何通过输入端控制输出端(即控制哪个数码管位选的打开)。

真值表如下:L是低电平,H是高电平。当8个端口为低电平的时候,该数码管的位选就会打开。

 

注意:LED8和Y7都表示的板子上最左边第一个数码管。

LSA、LSB、LSC是对38译码器的三个输入管脚的定义,用来控制数码管的位选。

在显示一个数码管之后,就要对数码管进行消隐的操作(让段选为0x00),目的是让数码管的显示更加清晰,清除数码管底部的暗红色痕迹。

程序:8个数码管依次显示1-8

#include 

#define uchar unsigned char
#define uint unsigned int
	
#define SMG_duanxuan   P0//对整个P0端口进行定义 用宏定义
                         //是对整个段选端口进行定义


sbit LSA=P2^2;//对单个管脚进行定义用sbit
sbit LSB=P2^3;
sbit LSC=P2^4;

uchar code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40,0x00};//0-9,横线,关闭
uchar Smg[8]={0};
uchar Smg_num=0;

void Delayms(uint ms);//1毫秒延时
void Smg_display();//数码管显示函数

void main()
{
	while(1)
	{
		Smg_display();
	}
}

void Smg_display()//数码管显示函数
{
	uchar Smg_num=0;
	
	for(Smg_num=0;Smg_num<8;Smg_num++)
	{
		switch(Smg_num)
		{
			case 0:LSA=1;LSB=1;LSC=1;break;//数码管1
			case 1:LSA=0;LSB=1;LSC=1;break;
			case 2:LSA=1;LSB=0;LSC=1;break;
			case 3:LSA=0;LSB=0;LSC=1;break;
			case 4:LSA=1;LSB=1;LSC=0;break;
			case 5:LSA=0;LSB=1;LSC=0;break;
			case 6:LSA=1;LSB=0;LSC=0;break;
			case 7:LSA=0;LSB=0;LSC=0;break;//数码管8
		}
		SMG_duanxuan=tab[Smg[Smg_num]];
		//P0=tab[Smg[Smg_num]];//直接控制P0口也行
		Smg[0]=1;Smg[1]=2;Smg[2]=3;Smg[3]=4;Smg[4]=5;Smg[5]=6;Smg[6]=7;Smg[7]=8;
		Delayms(1);
		SMG_duanxuan=0x00;//消隐,让数码管的显示更加清晰
	}
}

void Delayms(uint ms)//1毫秒延时
{
	uint i,j;
	for(i=ms;i>0;i--)
	for(j=114;j>0;j--);
}

四、独立按键

I/O口作为输入的实例   按键按下,I/O口为低电平。

按键的抖动:通常是5-10ms的范围,所以无论是按下还是松手,我们都要进行一个软件延时。一般延时5毫秒即可。

         

 

在这里要注意的是,不同于15单片机的地方在于按键的顺序,P31管脚是按键1,P30管脚是按键2.

程序:按下第一个按键,LED1亮起;按下第二个按键,LED2亮起;按下第三个按键,数码管1显示8;按下第四个按键,数码管2显示8;

#include 

#define uchar unsigned char
#define uint unsigned int

uchar code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40,0x00};//0-9,横线,关闭
uchar Smg[8]={2,1,10,0,6,10,8,8};
uchar Smg_num=0;
	


sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;



sbit LED1=P2^0;
sbit LED2=P2^1;



sbit LSA=P2^2;   //对单个管脚进行定义用sbit
sbit LSB=P2^3;
sbit LSC=P2^4;
#define SMG_duanxuan   P0//对整个P0端口进行定义 用宏定义
                         //是对整个段选端口进行定义

void Keyscan();
void Smg_display();//数码管显示函数
void Delayms(uint ms);//1毫秒延时

void main()
{
	
	while(1)
	{
		Smg_display();
		Keyscan();
	}
}

void Smg_display()//数码管显示函数
{
	uchar Smg_num=0;
	
	for(Smg_num=0;Smg_num<8;Smg_num++)
	{
		switch(Smg_num)
		{
			case 0:LSA=1;LSB=1;LSC=1;break;//数码管1
			case 1:LSA=0;LSB=1;LSC=1;break;
			case 2:LSA=1;LSB=0;LSC=1;break;
			case 3:LSA=0;LSB=0;LSC=1;break;
			case 4:LSA=1;LSB=1;LSC=0;break;
			case 5:LSA=0;LSB=1;LSC=0;break;
			case 6:LSA=1;LSB=0;LSC=0;break;
			case 7:LSA=0;LSB=0;LSC=0;break;//数码管8
		}
		SMG_duanxuan=tab[Smg[Smg_num]];
		//P0=tab[Smg[Smg_num]];
		Delayms(1);
		SMG_duanxuan=0x00;//消隐,让数码管的显示更加清晰
	}
}

void Keyscan()
{
	if(KEY1==0)
	{
		Delayms(5);//软件消抖
		if(KEY1==0)
		{
			LED1=0;
		}
		while(!KEY1);//软件消抖
	}
	else if(KEY2==0)
	{
		Delayms(5);
		if(KEY2==0)
		{
			LED2=0;
		}
		while(!KEY2);
	}
	else if(KEY3==0)
	{
		Delayms(5);
		if(KEY3==0)
		{
			Smg[0]=8;
		}
		while(!KEY3);
	}
	else if(KEY4==0)
	{
		Delayms(5);
		if(KEY4==0)
		{
			Smg[1]=8;
		}
		while(!KEY4);
	}
}

void Delayms(uint ms)//1毫秒延时
{
	uint i,j;
	for(i=ms;i>0;i--)
	for(j=114;j>0;j--);
}

五、矩阵按键

根据原理图,我们可以看出我们可以看出:矩阵按键的管脚在P10—P17,

我们宏定义矩阵按键的管脚          #define KEYSCAN16   P1

程序的架构与15系里的基本类似,第一列是:让P1=0xF7,判定第一列是否被下,进行消抖检测,再次判断是否被按下,根据P1的值来进行程序的实现,抬手消抖。

不同之处在于列数和行数的表示方法有所不同,

第一列:0xF7;第二列:0xFB;第三列:0xFD,第四列:0xFE。

检测这一列中第几行被按下:第一行:0X7列;第二行:0XB列 第三行:0XD列;第四行:0XE列。

程序:

void Keyscan16()
{
	KEYSCAN16=0xF7;
	if(KEYSCAN16!=0xF7)
	{
		Delayms(5);
		if(KEYSCAN16!=0xF7)
		{
			switch(KEYSCAN16)
			{
				case 0x77:Smg[0]=1;break;
				case 0xB7:Smg[1]=2;break;
				case 0xD7:Smg[2]=3;break;
				case 0xE7:Smg[3]=4;break;
			}		
			while(KEYSCAN16!=0xF7);
		}
	}
	
	KEYSCAN16=0xFB;
	if(KEYSCAN16!=0xFB)
	{
		Delayms(5);
		if(KEYSCAN16!=0xFB)
		{
			switch(KEYSCAN16)
			{
				case 0x7B:Smg[4]=5;break;
				case 0xBB:Smg[5]=6;break;
				case 0xDB:Smg[6]=7;break;
				case 0xEB:Smg[7]=8;break;
			}		
			while(KEYSCAN16!=0xFB);
		}
	}
	
	KEYSCAN16=0xFD;
	if(KEYSCAN16!=0xFD)
	{
		Delayms(5);
		if(KEYSCAN16!=0xFD)
		{
			switch(KEYSCAN16)
			{
				case 0x7D:Smg[0]=6;break;
				case 0xBD:Smg[1]=6;break;
				case 0xDD:Smg[2]=6;break;
				case 0xED:Smg[3]=6;break;
			}		
			while(KEYSCAN16!=0xFD);
		}
	}
	
	KEYSCAN16=0xFE;
	if(KEYSCAN16!=0xFE)
	{
		Delayms(5);
		if(KEYSCAN16!=0xFE)
		{
			switch(KEYSCAN16)
			{
				case 0x7E:Smg[0]=8;break;
				case 0xBE:Smg[1]=8;break;
				case 0xDE:Smg[2]=8;break;
				case 0xEE:Smg[3]=8;break;
			}		
			while(KEYSCAN16!=0xFE);
		}
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/923508.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号