单片机相应功能代码程序以及解释(针对A2)

复位按钮在液晶显示的情况下无法进行复位,只有在LED闪烁实验的时候可以实现复位。

晶振电路:

KEIL软件编程时头文件的存放路径:找到C51文件夹(下载KEIL时自带的文件夹),INC文件夹下。如果在这里没有被定义直接运行会报错。

直接打开KEIL4软件的时候无法直接编程,要打开项目才可以,在project--》open project

三态门的三种状态:高电平、低电平、高阻态。

多路开关的作用是选择作为I/O口使用还是选择作为存储地址使用。

MOS管是场效应晶体管。

漏极开路无法直接接上拉电阻,需要额外接入。

P0口可以作为内部总线的输入

P1口仅仅作为数据输入和输出即(I/O口的使用),内部本身含有上拉电阻,输出信息仅仅来自于内部总线,经过锁存反向之后输出到管脚。准双向口:P1、P2、P3都是准双向口。

电压式蜂鸣器(无源蜂鸣器,需要提供一定频率的脉冲信号),电磁式蜂鸣器(振荡器+电磁)。

不可以直接绑定I/O口去驱动,因为驱动所需的电流要达到30mA,需要连续的输出。

#include "reg52.h"

typedef unsigned char u8;
typedef unsigned int u16;

sbit BEEP=P2^5;

void delay_10us(u16 ten_us)
{
 while(ten_us--);
}
void main()
{
	u16 i=2000;

   while(1)
	{
	while(i--)
	{
//	  BEEP=!BEEP;
//	  delay_10us(100);	 
	BEEP=0;
	delay_10us(50);
	BEEP=1;
	delay_10us(150);	
	//这里的延时相加须等于200	
	}
	}
	i=0;
	BEEP=0;
}

按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管。 

A2采用共阴极数码管,需要外加专业驱动电路,共阴极和共阳极的编码区别是取反。

将二进制转换为16进制时,将要从高位到低位排列,即P7~P0口,例如:原本的P0口对应1,P7口对应0,且从0~7口一一对应为:1111 1100;现在将其反转0011 1111,得到16进制数为0x3F。

共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。

共阴数码管在应用时应将公共极COM 接到地线GND 上。

通过外部驱动芯片来增加I/O口使其不用直接连接到单片机上的I/O口上。

CMOS管:CMOS 工艺的低功耗和高集成度使得这些芯片能够在提供强大计算能力的同时,保持较低的能耗。CMOS 工艺有助于提高存储器的密度和性能。CMOS 图像传感器在这些设备中广泛应用,实现了高质量的图像捕捉功能。CMOS 工艺的芯片用于实现信号处理、调制解调等功能,为通信系统的高效运行提供支持。

宽电压工作范围:3.0V-5.0V是什么意思?即使电压在 3.0V-5.0V 之间有一定的波动,设备也不会受到太大影响,电子设备、电路或器件能够正常工作的输入电压范围在 3.0 伏特到 5.0 伏特之间。

输出具有三种状态,分别是逻辑 “0”、逻辑 “1” 和高阻态。逻辑 “0” 和逻辑 “1” 是常规的数字信号状态,用来表示不同的信息或电平;高阻态则相当于输出处于悬空或断开的状态,此时输出端对外部电路呈现出极高的阻抗,几乎没有电流通过,也不会对总线上的信号产生影响。

八线双向收发器?:有八个独立的信号通道,每个通道都能独立地进行数据传输,可同时处理八路数据信号,能满足多个信号源或接收端之间的通信需求,提高了数据传输的并行性和效率。

在工业控制系统中,可实现连接传感器与中央处理器之间的双向通信,确保信息的快速传递与反馈,还可用于可编程逻辑控制器(PLC)与外部设备之间的数据传输。内部通常由多个双向三态缓冲器组成,每个通道对应一个双向三态缓冲器。部分八线双向收发器还具有电平转换功能,可在不同电压电平的设备或总线之间进行数据传输,确保信号在不同电平标准下的正确传输和识别,解决了不同电压系统之间的接口问题。

可编程逻辑控制器(PLC)与外部设备之间的数据传输。

 74HC245 芯片用作驱动只会让其在一个方向输出,即DIR 管脚
为高电平,传输方向是A->B。

A0、A1、A2 输入就相当于3 位2 进制数,A0 是低位,A1 是次高位,A2 是高位。而Y0-Y7 具体哪一个输出有效电平,就看输入二进制对应的十进制数值。比如输入是101(A2,A1,A0),其对应的十进制数是5,所以Y5 输出有效电平(低电平)。

#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口
//共阴极数码管显示0~F 的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void main()
{
SMG_A_DP_PORT=gsmg_code[0];//将数组第1 个数据赋值给数码管段选口
while(1)
{
}
}

这里的数组留了17位,但实际只定义了16位,原因是要预留一位未显示的0X00;

 #include "reg52.h"

typedef unsigned int u16;
typedef unsigned char u8;

#define SMG_A_DP_PORT	P0

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

//将LSA、LSB、LSC对应的I/O口改变,则会影响数码管上的数字呈现规律
u8 gsmg_code[17]={0X3f,0X06,0X5b,0X4f,0X66,0X6d,0X7d,
07,0X7f,0X6f,0X77,0X7c,0X39,0X5e,0X79,0X71};

//如果将0X6d错输入为0x6b则原本应该显示的数字5不会显示5

void delay_10us(u16 ten_us)
{
 while (ten_us--);
}

void smg_display(void)
{
 	u8 i=0;
	for(i=0;i<8;i++)
	{
	 	switch(i)
		 {
		  case 0:	LSC=1;LSB=1;LSA=1;break;
		  case 1:	LSC=1;LSB=1;LSA=0;break;
		  case 2:	LSC=1;LSB=0;LSA=1;break;
		  case 3:	LSC=1;LSB=0;LSA=0;break;
		  case 4:	LSC=0;LSB=1;LSA=1;break;
		  case 5:	LSC=0;LSB=1;LSA=0;break;
		  case 6:	LSC=0;LSB=0;LSA=1;break;
		  case 7:	LSC=0;LSB=0;LSA=0;break;
		 }
//这里面的case语句,每一个对应数码上8个位中的一个


	   SMG_A_DP_PORT=gsmg_code[i];
//这里写P0=gsmg_code[i+1]则数码管上显示数字1~8

	   delay_10us(100);
//这里的延时设置时间够长且不超过65536,则显示的数字会轮流出现
	   SMG_A_DP_PORT=0X00;//这一行可以不写,对于代码的编译没有任何影响

	}
}

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

u8 gsmg_code[17]这个数组里面的16进制数,一一对应着数码管的显示位置。

控制数码管的段选信号:

  • 共阴极数码管:其所有阴极(负极)连接在一起并接地,通过给各个阳极(段)施加高电平来点亮相应的段。
  • 共阳极数码管:所有阳极连接在一起并接电源,通过给各个阴极(段)施加低电平来点亮相应的段。

当需要显示某个数字时,单片机通过向 P0 端口输出相应的段选码来控制数码管显示。锁存器可以在单片机输出段选码后将其锁存,这样单片机就可以释放 I/O 端口去处理其他任务,而数码管仍然能保持显示。

  • #define SMG_A_DP_PORT P0:将P0端口定义为SMG_A_DP_PORT,用于控制数码管的段选信号,即决定数码管显示什么数字或字符。
  • sbit语句:分别将P2.2P2.3P2.4引脚定义为LSALSBLSC,这三个引脚用于控制数码管的位选信号,通过不同的组合来选择要显示的数码管位。

通过开发板上的独立按键K1 控制D1 指示灯亮灭:

#include "reg52.h"

typedef unsigned int u16;
typedef unsigned char u8;

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

sbit LED1=P2^0;

#define KEY1_PRESS		1
#define KEY2_PRESS		2
#define KEY3_PRESS		3
#define KEY4_PRESS		4
#define KEY_UNPRESS		0


void delay_10us(u16 ten_us)
{
 	while(ten_us--);
}

u8 key_scan(u8 mode)
{
 	static u8 key=1;
	if(mode)key=1;
	if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))
	 {
	   delay_10us(1000);
	   key=0;
	   if(KEY1==0)
	   		return KEY1_PRESS;
		else if(KEY2==0)
			return KEY2_PRESS;
		else if(KEY3==0)
			return KEY3_PRESS;
		else if(KEY4==0)
			return KEY4_PRESS;
		
	 }
	 else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)
	 {
	 	key=1;
	 }
	 return KEY_UNPRESS;
} 

void main()
{
 	u8 key=0;
	while(1)
	{
	 	key=key_scan(0);
		 if(key==KEY1_PRESS)
	 		LED1=!LED1;
	}
}

 软件消抖:

1,先设置IO 口为高电平(由于开发板IO 都有上拉电阻,所以默认IO 为高
电平)。
2,读取IO 口电平确认是否有按键按下。
3,如有IO 电平为低电平后,延时几个毫秒。
4,再读取该IO 电平,如果仍然为低电平,说明按键按下。
5,执行按键控制程序。

使用独立按键: 

#include "reg52.h"

typedef unsigned int u16;
typedef unsigned char u8;

#define KEY_MATRIX_PORT	P1

#define SMG_A_DP_PORT	P0

u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void delay_10us(u16 ten_us)
{
 while(ten_us--);//延时设计
}

u8 key_matrix_ranks_scan(void)
{
 	u8 key_value=0;
	P1=0xf7;
	if(P1!=0xf7)
	{
	 	delay_10us(1000);
		switch(P1)
		{
		 	case 0x77:key_value=1;break;
  			case 0xb7:key_value=5;break;
			case 0xd7:key_value=9;break;
			case 0xe7:key_value=13;break;
		}
	}
	 while(P1!=0xf7);
	 P1=0xfb;
	 if(P1!=0xfb)
	 {
	  	delay_10us(1000);
		switch(P1)
		{
		 	case 0x7b:key_value=2;break;
			case 0xbb:key_value=6;break;
			case 0xdb:key_value=10;break;
			case 0xeb:key_value=14;break;
		}
	 }
	 while(KEY_MATRIX_PORT!=0xfb);
	 KEY_MATRIX_PORT=0xfd;
	 if(KEY_MATRIX_PORT!=0xfd)
	 {
	  	delay_10us(1000);
		switch(KEY_MATRIX_PORT)
		{
		 	case 0x7d:key_value=3;break;
			case 0xbd:key_value=7;break;
			case 0xdd:key_value=11;break;
			case 0xed:key_value=15;break;
		}
	 }
	 while(KEY_MATRIX_PORT!=0Xfd);
	 KEY_MATRIX_PORT=0xfe;
	 if(KEY_MATRIX_PORT!=0xfe)
	 {
	  	delay_10us(1000);
		switch(P1)
		{
		 	case 0x7e:key_value=4;break;
			case 0xbe:key_value=8;break;
			case 0xde:key_value=12;break;
			case 0xee:key_value=16;break;
		}
	 }
	 while(P1!=0xfe);
	 return key_value;
}	 
u8 key_materix_flip_scan(void)
{
 	static u8 key_value=0;
	P1=0x0f;
	if(P1!=0x0f)
	{
	 	delay_10us(1000);
		if(P1!=0x0f)
		{
		 	P1=0x0f;
			switch(P1)
			{
			 	case 0x07:key_value=1;break;
				case 0x0b:key_value=2;break;
				case 0x0d:key_value=3;break;
				case 0x0e:key_value=4;break;
			}
		
		P1=0xf0;
		switch(P1)
		{
		 	case 0x70:key_value=key_value;break;
			case 0xb0:key_value=key_value+4;break;
			case 0xd0:key_value=key_value+8;break;
			case 0xe0:key_value=key_value+12;break;
		}
		 while(P1!=0xf0);
	}
}
 else
 	key_value=0;
 return key_value;
}
void main()
{
 	u8 key=0;
	while(1)
	{
	 	key=key_matrix_ranks_scan();
		if(key!=0)
			SMG_A_DP_PORT=gsmg_code[key-1];
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值