蓝桥杯week1

LED的电路图

先通过38译码器选择Y4C位,再给P0引脚赋值-----共阳极的LED灯,给相应位号提供低电平即可点亮该位号的LED灯,闪烁使用延时,流水灯使用延时+移位

打开锁存器P2=0x80(记忆方法有8个LED灯)

LED的控制方法

1.字节/位赋值

(实现点亮L1 L3 L7 L8四个LED,其余熄灭)

#include <STC15F2K60S2.H>
#include <intrins.h>
#include "Delay.h"
#include "Device.h"


void vSystem_Init(void)
{
	vDevice_Ctrl(0xa0,0); 		/* 关闭蜂鸣器、继电器*/
}

void vDevice_Ctrl(unsigned char p2data,unsigned char p0data)
{
	P0 = p0data;
	P2 = p2data;
	P2 = 0;
}                               /*后面有优化的代码*/

void main(void)
{
	vSystem_Init();
	vDevice_Ctrl(0x80,0x3a);    /* 点亮L1 L3 L7 L8四个LED,其余熄灭 */
	vDevice_Ctrl(0x80,0xaa);	/* 点亮L1 L3 L5 L7四个LED,其余熄灭 */
	while(1)
	{
		
	}
}

2.标志位控制

(实现点亮L1 L3 L7 L8四个LED)

先设一数组变量,大小为9位,为了方便和不易出错,1~8分别对应8个LED。

再把需控制位置1,P2口是取反。

#include <STC15F2K60S2.H>
#include <intrins.h>
#include "Delay.h"
#include "Device.h"

unsigned char led_ctrl[9];

void vDevice_Ctrl(unsigned char p2data,unsigned char p0data)
{
	P0 = p0data;
	P2 = p2data;
	P2 = 0;
}

void vSystem_Init(void)
{
	vDevice_Ctrl(0xa0,0); 		/* 关闭蜂鸣器、继电器*/
}

void main(void)
{
	vSystem_Init();
	led_ctrl[1]=1;led_ctrl[3]=1;led_ctrl[7]=1;led_ctrl[8]=1;	/* 点亮L1 L3 L7 L8四个LED */
	vDevice_Ctrl(0x80,~(led_ctrl[8]<<7 | led_ctrl[7]<<6 | led_ctrl[6]<<5 | led_ctrl[5]<<4 | 
							led_ctrl[4]<<3 | led_ctrl[3]<<2 | led_ctrl[2]<<1 
                                                          |led_ctrl[1]));
	while(1)
	{
		
	}
}

结果和上图一样,不占用篇幅赘述。

流水灯的实现

L1~L8 流水形式亮

#include <STC15F2K60S2.H>
#include <intrins.h>
#include "Delay.h"
#include "Device.h"

unsigned char led_ctrl[9];
/**
  * @brief  系统初始化函数:关闭继电器、蜂鸣器
  * @param  None
  * @retval None
  * @author dianshe.taobao.com
  */

void vSystem_Init(void)
{
	vDevice_Ctrl(0xa0,0); 		/* 关闭蜂鸣器、继电器*/
}


void vLED_Running_L1_L8(void)
{
	static unsigned char led_shift=0;
	vDevice_Ctrl(0x80,~(0x01<<led_shift));
	led_shift++;
	if(led_shift==8)	led_shift=0;
}

void vLED_Running_L8_L1(void)
{
	static unsigned char led_shift;
	vDevice_Ctrl(0x80,~(0x80>>led_shift));
	led_shift = (led_shift + 1) % 8;
}

void vLED_Running_L2_L4_L6_L8(void)
{
	static unsigned char led_shift;
	vDevice_Ctrl(0x80,~(0x02<<led_shift));
	led_shift = (led_shift + 2) % 8;
}      //%8 让它循环

void main(void)
{
	vSystem_Init();
	led_ctrl[1]=1;led_ctrl[3]=1;led_ctrl[7]=1;led_ctrl[8]=1;	/* 点亮L1 L3 L7 L8四个LED */
	vDevice_Ctrl(0x80,~(led_ctrl[8]<<7 | led_ctrl[7]<<6 | led_ctrl[6]<<5 | led_ctrl[5]<<4 | 
							led_ctrl[4]<<3 | led_ctrl[3]<<2 | led_ctrl[2]<<1 | led_ctrl[1]));
	while(1)
	{
		vLED_Running_L2_L4_L6_L8();
		vDelay_Ms(200);				/* 仅作练习用,在while(1)不要使用大于20ms的延时!会造成CPU资源浪费! */
									/* 学完定时器,即可把长时间Delay给优化掉! */
	}
}

LED流水灯(简版)

运用共用体实现优化

1.共用体(Union)是一种特殊的数据类型
它允许在同一个内存位置存储不同的数据类型。
共用体的所有成员共享同一块内存空间,
因此同一时间只能存储其中一个成员的值。

共用体的定义和结构体类似,使用关键字union,后面跟着成员列表。
每个成员可以是不同的数据类型,
但共用体的所有成员都共享同一块内存空间,大小取决于最大的成员

2.在LED中就可以使用

#include <STC15F2K60S2.H>
#include <intrins.h>
#include "Delay.h"
#include "Device.h"

/* 用typedef定义一个叫bits的结构体“数据类型”, 从而可以用 bits b; 定义b为结构体的“变量”*/
typedef struct
{
	unsigned char b0 : 1;
	unsigned char b1 : 1;
	unsigned char b2 : 1;
	unsigned char b3 : 1;
	unsigned char b4 : 1;
	unsigned char b5 : 1;
	unsigned char b6 : 1;
	unsigned char b7 : 1;
}bits;

/* 用typedef定义一个叫HexToBin的共用体“数据类型”, 从而可以用 HexToBin led_ctrl; 定义led_ctrl为共用体的“变量”*/
typedef union
{
	unsigned char hex;		
	bits b;
}HexToBin;

HexToBin led_ctrl,buzzer_ctrl;

/**
  * @brief  系统初始化函数:关闭继电器、蜂鸣器
  * @param  None
  * @retval None
  * @author dianshe.taobao.com
  */
void vSystem_Init(void)
{
	vDevice_Ctrl(0xa0,0); 		/* 关闭蜂鸣器、继电器*/
}

void main(void)
{
	vSystem_Init();
	led_ctrl.hex = 0x55;				/* 对led_ctrl进行“字节赋值”,希望L2 L4 L6 L8点亮 */
	vDevice_Ctrl(0x80,led_ctrl.hex);	/* 选通Y4C锁存器,并在P0口输出一个字节数据,完成点亮L2 L4 L6 L8操作 */
	
	buzzer_ctrl.b.b4 = 1;					/* 对buzzer_crtl进行“位赋值”,希望吸合继电器 */
	vDevice_Ctrl(0xa0,buzzer_ctrl.hex);	/* 选通Y5C锁存器,并在P0口输出一个字节数据,完成吸合继电器操作 */
	while(1)
	{
		led_ctrl.b.b1 = 1;					/* led_ctrl进行“位赋值”,希望熄灭L2 */
		vDevice_Ctrl(0x80,led_ctrl.hex);	/* 选通Y4C锁存器,并在P0口输出一个字节数据,完成熄灭L2操作 */
		
		buzzer_ctrl.b.b4 = 1;					/* 对buzzer_crtl进行“位赋值”,希望吸合继电器 */
		vDevice_Ctrl(0xa0,buzzer_ctrl.hex);		/* 选通Y5C锁存器,并在P0口输出一个字节数据,完成吸合继电器操作 */		
		vDelay_Ms(200);							/* 仅作练习用,在while(1)不要使用大于20ms的延时!会造成CPU资源浪费!学完定时器,即可把长时间Delay给优化掉! */
		
		led_ctrl.b.b1 = 0;						/* led_ctrl进行“位赋值”,希望点亮L2 */
		vDevice_Ctrl(0x80,led_ctrl.hex);		/* 选通Y4C锁存器,并在P0口输出一个字节数据,完成点亮L2操作 */
		
		buzzer_ctrl.b.b4 = 0;					/* 对buzzer_crtl进行“位赋值”,希望关闭继电器 */
		vDevice_Ctrl(0xa0,buzzer_ctrl.hex);		/* 选通Y5C锁存器,并在P0口输出一个字节数据,完成关闭继电器操作 */
		vDelay_Ms(200);
	}
}

使用共用体可以清晰的知道LED的运作原理,也方便后续的代码查错。强力推荐使用,后面的代码量会比较大,使用它不用重复定义变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值