蓝桥杯——单片机学习(3——点亮LED灯)

文章目录[隐藏]

注:此单片机型号为 STC15F2K60S2.

原理图片来源:我自己:)

如图,发光二极管L1—L8 共阳接法,VCC为电源正极,高电平。
已知发光二极管正向导通反向截至,要使得二极管发光,就要让Q1—Q8为低电平。可控管脚为P00—P07,所以要输入P00—P07为低电平。为了让P0能够影响到Q1—Q8,就要使得锁存器 M74HC573M1R 导通,即要让管脚LE为高电平。又管脚LE与Y4C连接,所以Y4C也为高电平。
图片来源:我自己:)
图片来源:我自己:)
又Y4C连接了一个或非门,或非门的输入端为Y4和WR。因为WR已用跳线帽与GND连接在了一起,GND为接地,所以WR为0(低电平)。
根据或非门逻辑表格:

Y4	      WR	   Y4C
0	       0	     1
0          1   	     0
1	       0	     0
1	       1	     0

所以,当Y4C为0时,Y4为1;当Y4C为1时,Y4为0.
所以,要使得Y4C为高电平,Y4就要为低电平,即Y4为0.
图片来源:我自己:)
又Y4是由 74HC138 位译码器的输入端A、B、C来控制,以 C、B、A 为逻辑顺序,CBA组成二进制数,来选中Y0—Y7,被选中者即为低电平。

所以,要使得 Y4 为低电平,CBA 要为 100.

另外,由于 P0 口是复用的,意味着也要控制别的器件,所以如果一直让 LE 为高,那么就在控制别的器件的时候就会影响到 LED,所以在锁存器导通后,应该截止保存住它的状态。

整理逻辑

点亮LED:
Q1—Q8为低电平 —> P00-P07为低电平 -> 导通锁存器,LE为高电平 ->
Y4C为高电平 -> 或非门,Y4为低电平 -> 译码器,CBA组合为100 ->
锁存状态,断开锁存器,LE为低电平,Y4C为低电平 -> 
或非门,Y4为高电平 -> 译码器,CBA组合为000.(不为100即可)

同理,熄灭LED:
Q1—Q8为高电平 —> P00-P07为高电平 -> 导通锁存器,LE为高电平 ->
Y4C为高电平 -> 或非门,Y4为低电平 -> 译码器,CBA组合为100 ->
锁存状态,断开锁存器,LE为低电平,Y4C为低电平 -> 
或非门,Y4为高电平 -> 译码器,CBA组合为000.(不为100即可)

代码

来源:蓝桥杯官方资料。

#include "reg52.h"
// #include "absacc.h"
// 关闭外设
void Cls_Peripheral(void)
{ // IO模式(J13-2和J13-3相连)
  P0 = 0xFF;
  P2 = P2 & 0x1F | 0x80;			// P27~P25清零,再定位Y4C
  P2 &= 0x1F;						// P27~P25清零
  P0 = 0;
  P2 = P2 & 0x1F | 0xA0;			// P27~P25清零,再定位Y5C
  P2 &= 0x1F;						// P27~P25清零
//XBYTE[0x8000] = 0xFF;				// MM模式(J13-2和J13-1相连)
//XBYTE[0xA000] = 0;
}
// LED显示
void Led_Disp(unsigned char ucLed)
{ // IO模式(J13-2和J13-3相连)
  P0 = ~ucLed;                      //unsigned char
  P2 = P2 & 0x1F | 0x80;			// P27~P25清零,再定位Y4C
  P2 &= 0x1F;						// P27~P25清零
//XBYTE[0x8000] = ~ucLed;			// MM模式(J13-2和J13-1相连)
}
// 延时函数(最小约1ms@12MHz)
void Delay(unsigned int num)
{
  unsigned int i;
  while(num--)
    for(i=0; i<628; i++);
}
// 主函数
void main(void)
{
  unsigned char i, j;

  Cls_Peripheral();

  while(1)
  { // 4个亮度等级
    for(i=0; i<4; i++)
      for(j=0; j<100; j++)
      {
        Led_Disp(0xff);
        Delay(i+1);
        Led_Disp(0);
        Delay(4-i);
      }
  }
}

第一段:关闭外设
因为C51单片机默认P口为高电平,所以LED和蜂鸣器等等在程序运行前就会工作。具体原理看这个@我的头绝不是面团捏的 —— 蓝桥杯单片机比赛系列 1 初探关闭外设
代码就直接放这了:

// 关闭外设
void Cls_Peripheral(void)
{ // IO模式(J13-2和J13-3相连)
  P0 = 0xFF;
  P2 = P2 & 0x1F | 0x80;			// P27~P25清零,再定位Y4C
  P2 &= 0x1F;						// P27~P25清零
  P0 = 0;
  P2 = P2 & 0x1F | 0xA0;			// P27~P25清零,再定位Y5C
  P2 &= 0x1F;						// P27~P25清零
//XBYTE[0x8000] = 0xFF;				// MM模式(J13-2和J13-1相连)
//XBYTE[0xA000] = 0;
}

(注:这个IO模式还是不懂诶,懂了我再填上,先放个参考博客——liu_endong——51 单片机 ——IO 口工作模式及配置

第二段:LED 显示

// LED显示
void Led_Disp(unsigned char ucLed)
{ // IO模式(J13-2和J13-3相连)
  P0 = ~ucLed;                      //unsigned char
  P2 = P2 & 0x1F | 0x80;			// P27~P25清零,再定位Y4C
  P2 &= 0x1F;						// P27~P25清零
//XBYTE[0x8000] = ~ucLed;			// MM模式(J13-2和J13-1相连)
}

先设置 P0 口,选择要点亮的灯的编码 ucled ,再选中 Y4 导通锁存器,在 LED 点亮后再锁存。

第三段:延时函数

// 延时函数(最小约1ms@12MHz)
void Delay(unsigned int num)
{
  unsigned int i;
  while(num--)
    for(i=0; i<628; i++);
}

这个就不用说了吧,应该都懂。

第四段:主函数

void main(void)
{
  unsigned char i, j; //设置无符号char型参数  i,j.

  Cls_Peripheral();   //关闭外设

  while(1)            //循环
  { // 4个亮度等级
    for(i=0; i<4; i++)
      for(j=0; j<100; j++)
      {
        Led_Disp(0xff);//1111 1111,全灭
        Delay(i+1);    //设置延迟时间
        Led_Disp(0);   //0000 0000  全亮
        Delay(4-i);    //
      }
  }
}

呼吸灯其实就是以不同的亮度点亮led灯,关键就在于如何以不同的亮度来点亮led灯,也就是改变led灯的亮度。简单的方法就是在肉眼观察不到的时间范围内,改变 led 点亮时间的占比,从而形成不同亮度的视觉效果。

// 4个亮度等级
for(i=0; i<4; i++)
      for(j=0; j<100; j++)
      {
        Led_Disp(0xff);//1111 1111,全灭
        Delay(i+1);    //设置延迟时间
        Led_Disp(0);   //0000 0000  全亮
        Delay(4-i);    //
      }

两个循环,第一个循环和Delay函数一起用来设置亮与灭的时间,从而设置灯的亮度等级。第二个循环则设置每一个亮度等级的运行时间。
第二个循环内的内容,是将亮与灭的时间分为四份,按照不同搭配组合调节灯的亮度。

跑马灯代码

参考:@图灵小跟班 ——1.51 单片机_关于 LED 点亮 / 闪烁 / 跑马灯 / 呼吸灯_零基础_基于某单片机 A6。

#include<reg51.h>
#include<intrins.h>	//该库里面有关于左右移函数
#define  led P0

typedef unsigned int u16;
typedef unsigned char u8;


void delay(u16 i)
{
	while(i--);
}

void main()	//方式1
{
	u8 i;
	led = ~0x01;//取反   0000 0001
	delay(50000);
	while(1)
	{
		for(i=0; i<8; i++)//左移使得LED从左往右亮
		{
			led = ~(0x01<<i);  //0000 0001
			delay(50000);
		}

		for(i=0; i<8; i++)//右移使得LED从右往左亮
		{
			led = ~(0x80>>i);  //1000 0000
			delay(50000);
		}
	}
}
		
/***************方式2*****************************/
 /*
void main()
{
	u8 i;
	led = ~0x01;
	delay(50000);
	while(1)
	{
		for(i=0; i<7; i++)
		{	
			led=_crol_(led,1);	 //char rotate left 字符串类型,向左移动,(字符串型变量,移动位数)
			delay(50000);
		}						 

		for(i=0; i<7; i++)
		{
			led=_cror_(led,1);//right
			delay(50000);
		}

	}
}  */

老师的代码:

int i;
while(1){
	
  for(i=0;i<8;i++){
    P0 = ~(1<<i);//从右往左
		//从左往右   P0 = ~(0x80>>i);
		P2 = P2 & 0x1F | 0x80;
		P2& = 0x1F;
	}

}

注:

跑马灯连续左移右移可能会导致有一个灯闪烁两次,为了解决这个问题,可以使得左移 1-7,右移也 1-7,直接交叉点亮。

请添加图片描述

版权声明:本文为CSDN博主「Moqim Flourite.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_55374353/article/details/120335717

生成海报
点赞 0

Moqim Flourite.

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

4路红外循迹模块使用教程

4路红外循迹模块使用教程 个人原创博客:点击浏览模块详细信息: 工作电压:DC 3.3V~5V 工作电流:尽量选择1A以上电源供电 工作温度:-10℃~50℃ 安装孔

拉绳位移传感器在接线时需要注意哪几点?

拉绳位移传感器在接线时需要注意哪几点? 1、拉绳位移传感器在接线时务必确认在电源关闭的情况下进行接线,接线应采用锡焊工艺,各引脚应焊接牢固,避免虚焊情况发生。焊接各引脚时应严格按照传感器厂

实验一 stm32F407VETx点亮流水灯

二、设计指标 使电路板上的8个LED轮流点亮,并按键控制点亮速度。 三、操作 1、CubeMX操作 1.1依据开发板LED引脚设置CubeMX中8个LED的引脚为GPIO_Output模式, 2、按键设置