蓝桥杯----锁存器、LED、蜂鸣器、继电器、Motor

(七)、锁存器

1、原理

蓝桥杯中数据传入口都是P0,也就是数码管段选、位选数据、LED亮灭的数据、蜂鸣器启动或禁用的数据,外设启动或者关闭都需要通过P0写入数据,那么如何这样共用一个端口会造成冲突嘛,答案是肯定的。所以蓝桥杯加入了锁存器---通过P2高三位(22、21、20)操作。如图 三十LED锁存器对应地址为Y4C,凑成高三位数据100,后五位自动补零,P2对应数据1000 0000(用十六进制表示0x80)。Y5C对应数据就是1010 0000(0xa0)...

2、代码示范与解读

如 图 三十一,首先定义一个temp临时变量,再在P0口传入数据

P2 & 0x1f就是保留低五位,单独使高三位全为0,因为高三位才是锁存器的选择位。

再单独改变temp = temp | 0x80,0x80是刚刚推出来的数据,这样|上,就是单独修改了高三位,低五位 保持不变。再将数据放入P2中,此时P0中数据就已经传入了。

最后我们temp = P2 & 0x1f就是清空高三位,P2 = temp关闭锁存器。注意如果此时不关闭锁存器,那么一旦有数据传入P0就会被立即写入。

对这个代码进行推广,只需改变0x80那个位置的数据即可,假设想操作数码管位选的锁存器Y6C,可知为1100 0000(即为0xc0),将0x80改成0xc0就可以传入数码管位选数据了。

图 三十 LED 原理图

图 三十一 借助锁存器写入数据

(八)、LED

1、原理(图 三十)

在P00-P07口传入数据,对应第一盏灯到第八盏灯,打开锁存器,就可以实现LED亮灭了。由原理图可知,**为共阳极接法,当P0端口传入低电平数据时,就点亮LED了。**注意51单片机LED亮灭可能不同。

2、代码解读(图 三十二)

定义一个数组,传入LED亮灭的数据,1为亮表示使能,0为灭表示失能

定义两个变量,temp_1与temp_1_old,只有这两者不相等时操作寄存器(改变)写入,temp_1存放亮灭的八位数据。

LED_Buf[0]<<0就是将第一个灯数据左移0位,放在temp_1的最低位,就是操作P00第一个灯。LED_Buf[1]<<1就是把第二个灯数据按二进制左移1位,放在temp_1的Bit2位...

有改变发生,两者不同了,写入数据,记住低电平点亮灯,所以要取反,在打开LED的锁存器,更新temp_1_old的值。

在主程序中我们可以打开定时器0,写一个1ms中断函数,在中断中扫描这个函数。

图 三十二 LED 代码解读

(九)、继电器、蜂鸣器、Motor

1、原理(图 三十三)

最左边P01~P07是数据输入端口,最右边Relay就是对应继电器,Motor就是发动机,Buzz对应蜂鸣器,低电平0就是打开这个设备,但是ULN2003设备在中间会对数据进行取反,所以打开Relay数据为 空一位011 1111,对应最左边数据为 0001 0000,即为0x10。同理打开蜂鸣器即为0x40,打开Motor即为0x20。

图 三十三 外设原理图

2、代码解读(图 三十四 )

开局必须定义两个全局变量为蜂鸣器、继电器、发动机共用,防止不同变量操作对其他设备影响。

当Flag为1时,必须单独变化第四位为1,其余的不变,用 | 操作符来实现,|上0这一位就是保持不变,|上1就是强制为1。当Flag为1时,第四位为0,其余的不变,用 & 符来实现。

temp_2就是临时数据值,temp_2_Old就是记录上一个状态的值,不相同说明状态发生了改变,将数据传入P0端,打开锁存器即可。

图 三十四 代码解读(继电器)

3、代码推广(图 三十五、图 三十六)

将0x10改为0x40就是单独打开蜂鸣器代码,改成0x20就是启动Motor电机代码,电机适用于设计PWM波形的。一般来说只考继电器在特定条件下打开与关闭。

图 三十五 蜂鸣器推广代码

图 三十六 Motor 推广代码

4、提供参考代码,希望对读者有帮助

cs 复制代码
#include <STC15F2K60S2.H>

idata unsigned char temp_1 = 0x00;
idata unsigned char temp_old_1 = 0xff;
void LED_Disp(unsigned char *LED_Buf)   //传入LED数据数组,1亮、0灭
{
	unsigned char temp; 
	temp_1 = 0x00;
	temp_1 = (LED_Buf[0]<<0) | (LED_Buf[1]<<1) |(LED_Buf[2]<<2) |
	(LED_Buf[3]<<3) |(LED_Buf[4]<<4) |(LED_Buf[5]<<5) |(LED_Buf[6]<<6) |
	(LED_Buf[7]<<7);    //通过一个数组传入8个LED灯的数据  
	//LED_Buf[0]<<0,假设第一个数据为1,数据<<(按位左移)0就是让Bit1为1
	//LED_Buf[1]<<1,假设第一个数据为1,数据<<(按位左移)1就是让Bit2为1
	
	if(temp_1 != temp_old_1)  //数据改变
	{
		P0 = ~temp_1;    //一定记得取反
		temp = P2 & 0x1f;
		temp = temp | 0x80;   //操作Led灯的锁存器
		P2 = temp;
		temp = P2 & 0x1f;
		P2 = temp;
		
		temp_old_1 = temp_1;   //更新temp_old_1
	}
}


idata unsigned char temp_2 = 0x00;
idata unsigned char temp_2_old = 0xff;

//继电器操作函数
void Relay_Disp(unsigned char Flag)
{
	unsigned char temp;
	if(Flag)
	temp_2 |= 0x10;
	else
	temp_2 &= ~0x10;
	
	if(temp_2 != temp_2_old)
	{
		P0 = temp_2;
		
		temp = P2 & 0x1f;
		temp = temp | 0xa0;
		P2 = temp;
		temp = P2 & 0x1f;
		P2 = temp;
		
		temp_2_old = temp_2;
	}
}

//蜂鸣器操作函数
void Beep_Disp(unsigned char Flag)
{
	unsigned char temp;
	if(Flag)
	temp_2 |= 0x40;
	else
	temp_2 &= ~0x40;
	
	if(temp_2 != temp_2_old)
	{
		P0 = temp_2;
		
		temp = P2 & 0x1f;
		temp = temp | 0xa0;
		P2 = temp;
		temp = P2 & 0x1f;
		P2 = temp;
		
		temp_2_old = temp_2;
	}
}


//Motor操作函数
void Motor_Disp(unsigned char Flag)
{
	unsigned char temp;
	if(Flag)
	temp_2 |= 0x20;
	else
	temp_2 &= ~0x20;
	
	if(temp_2 != temp_2_old)
	{
		P0 = temp_2;
		
		temp = P2 & 0x1f;
		temp = temp | 0xa0;
		P2 = temp;
		temp = P2 & 0x1f;
		P2 = temp;
		
		temp_2_old = temp_2;
	}
}

5、提供定时器1代码与中断

cs 复制代码
//定时器一初始化,自己加上EA = 1;ET1 = 1;
void Timer1_Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xBF;			//定时器时钟12T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0x18;				//设置定时初始值
	TH1 = 0xFC;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
	EA = 1;                 //打开总中断
	ET1 = 1;                //打开定时器一中断允许位
}

void Timer1_Routine() interrupt 3
{
LED_Disp(LED_Buf);         //LED扫描
}
相关推荐
猫猫的小茶馆4 小时前
【STM32】HAL库中的实现(二):串口(USART)/看门狗(IWDG/WWDG)/定时器(TIM)
arm开发·驱动开发·stm32·单片机·嵌入式硬件·mcu·智能硬件
zhmc4 小时前
MCU程序的编译与链接及格式转换
arm开发·单片机·嵌入式硬件
普中科技5 小时前
【普中STM32精灵开发攻略】--第 10 章 STM32位带操作
stm32·单片机·嵌入式硬件·物联网·arm·普中科技·位带操作
HW-BASE5 小时前
C语言的结构体与联合体
c语言·单片机·嵌入式·编程·c
FightingFreedom6 小时前
GPIO交换矩阵和IO_MUX
单片机·嵌入式硬件·esp32·arduino·esp32s3
HW-BASE7 小时前
C语言控制语句练习题1
c语言·开发语言·单片机·算法·嵌入式·c
zhmc9 小时前
MCU程序段的分类
单片机
智者知已应修善业12 小时前
【51单片机6位数码管密码锁】2022-10-15
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
JasmineX-117 小时前
STM32的SPI通信(硬件读取W25Q64)
c语言·stm32·单片机·嵌入式硬件