蓝桥杯——单片机学习(3——点亮LED灯)_蓝桥杯 y4c-程序员宅基地

技术标签: stm32  物联网  单片机学习  单片机  

注:此单片机型号为 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函数一起用来设置亮与灭的时间,从而设置灯的亮度等级。第二个循环则设置每一个亮度等级的运行时间。
第二个循环内的内容,是将亮与灭的时间分为四份,按照不同搭配组合调节灯的亮度。

我的代码

led.c

/**************************************************************************** 
* Copyright (C), 2022,Moqim
* 文件名: led.c 
* 内容简述:LED初始化、LED控制函数 
* 
* 文件历史: 
* 版本号      日期       作者     说明 
*   01a    2022-04-24   Moqim   创建该文件
* 
* All rights reserved
*/

#include "led.h"

/**************************************************************************** 
* 函数名: LED_Init() 
* 功 能: 关闭全部的LED灯
* 输 入: 无        
* 输 出: 无 
*/
void LED_Init(void)
{
    	
	P0 = 0Xff;            //拉高所有PO端口
	P2 = P2 & 0x1f | 0x80;// P27~P25清零,再定位Y4C  关闭led
	P2 &= 0x1f;           // P27~P25清零,锁存
}

/**************************************************************************** 
* 函数名: LED_Ctrl() 
* 功 能: 关闭全部的LED灯
* 输 入: 无        
* 输 出: 无 
*/
void LED_Ctrl(unsigned char ucLed)//uc 表示 "unsigned char" 类型
{
    
	P0 = ~ucLed;          //ucled取反 0000 0001 -> 1111 1110
	P2 = P2 & 0x1f | 0x80;// P27~P25清零,再定位Y4C
	P2 &= 0x1f;           // P27~P25清零,锁存
}

led.h

//为了防止头文件被重复引用,应当用 ifndef/define/endif结构产生预处理块

#ifndef __LED_H
#define __LED_H

#include "stc15f2k60s2.h"

void LED_Init(void);
void LED_Ctrl(unsigned char ucLed);

#endif /*__LED_H*/

main.c

/**************************************************************************** 
* Copyright (C), 2022,Moqim
* 文件名: main.c 
* 内容简述:实现十个等级的呼吸灯与向右移动的LED流水灯 
* 
* 文件历史: 
* 版本号      日期       作者     说明 
*   01a    2022-04-24   Moqim   创建该文件 
*
* All rights reserved
*/

//头文件调用区
#include "stc15f2k60s2.h"
#include "led.h"

//变量定义区


//函数声明区
void LED_NotifyLight(void);
void LED_Runningwater(void);
void Delay_ms(unsigned int num);

//Main Body
int main(void)
{
    
	LED_Init();
	while (1)
	{
    
		LED_NotifyLight();
		LED_Runningwater();
	}
	
}

/**************************************************************************** 
* 函数名: LED_NotifyLight() 
* 功 能: 实现10个等级的呼吸灯
* 输 入: 无        
* 输 出: 无 
* 说 明:像油画调色一样,不同比例的亮与暗的搭配,可以实现LED的不同亮度
*/
void LED_NotifyLight(void)
{
    
	int i, j;
	for(i=0; i<10; i++)//划分等级,将LED的亮度划分为十份
		for(j=0; j<100; j++)//为保证肉眼能够观察,将每个时段的时间扩大一百倍
		{
    
			//熄灭时间 + 点亮时间 = 10(按比例理解也是一样的)
			LED_Ctrl(0xff);
			Delay_ms(i+1);//设定LED熄灭的时间
			LED_Ctrl(0);
			Delay_ms(10-i);//设定LED点亮的时间
		}
}

/**************************************************************************** 
* 函数名: LED_Runningwater() 
* 功 能: 实现向右移动的LED流水灯
* 输 入: 无        
* 输 出: 无 
* 说 明:注意蓝桥杯板子上LED灯的排序,是低位在前,~0x01在第一个,~0x02在第二个,~0x04在......
*/
void LED_Runningwater(void)
{
    
	int i = 0;//变量定义放在外面,或者紧挨着函数开头的括号
	
	for (i = 0;i<8;i++)//右移8次 (包括移动0位)
	{
    
		LED_Ctrl(0x01 << i);//取反后为:1111 1110 -> 1111 1101 ->1111 1011 ->......
		Delay_ms(500);
	}
}

/**************************************************************************** 
* 函数名: Delay_ms() 
* 功 能: 延时
* 输 入: unsigned int num:延时num毫秒        
* 输 出: 无 
*/
void Delay_ms(unsigned int num)//软件延时不精确,凑合用吧
{
    
	int i,j;
	for(i = 0;i<num;i++)
	{
    
		for(j = 0;j<625;j++);
	}
}

老师的代码(流水灯)

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,直接交叉点亮。

请添加图片描述

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

智能推荐

瑞芯微RK3288、RK3399、RK3568、RK3368芯片性能介绍与对比分析_rk3288和rk3568对比-程序员宅基地

文章浏览阅读2.1k次,点赞7次,收藏8次。是瑞芯微推出的一款低功耗、高性能的应用处理器芯片,该芯片基于Big.Little架构,即具有独立的NEON协同处理器的双核Cortex-A72及四核Cortex-A53组合架构,主要应用于计算机、个人互联网移动设备、VR、广告机等智能终端设备。RK3399内置多个高性能硬件处理引擎,能够支持多重格式的视频解码,如:4K*2K@60fps 的H.264/H.265/VP9,也支持1080P@30fps的H.264/MVC/VP8 以及高质量的JPEG编解码和图像的前后处理器。_rk3288和rk3568对比

使用esp 8266物联网开发板 + Mqtt制作远程控制LED小灯_esp8266 mqtt 控制灯亮灭-程序员宅基地

文章浏览阅读1.5k次。如何30快钱以内制作一个手机控制的led小灯_esp8266 mqtt 控制灯亮灭

Ansys Zemax | 如何模拟光学相干层析成像系统_nsdd操作数-程序员宅基地

文章浏览阅读291次,点赞2次,收藏4次。聚焦透镜的坐标(0,20,40),使聚焦透镜与扫描镜保持水平,并保持20mm的距离(该距离在两者的水平位置距离中是任意的),聚焦透镜的材料为N-BK7。_nsdd操作数

流式处理中的文本聚类:探索Apache Beam在文本数据处理中的应用-程序员宅基地

文章浏览阅读5.7k次。作者:禅与计算机程序设计艺术 流式处理中的文本聚类:探索Apache Beam在文本数据处理中的应用引言1.1. 背景介绍随着互联网与物联网的发展,大量的文本数据在各个领

基于微服务架构的分布式系统:如何设计和实现高效的微服务系统_基于微服务的系统-程序员宅基地

文章浏览阅读4.7k次。随着互联网的发展,分布式系统在大型企业应用中越来越普遍。微服务架构作为一种新兴的分布式系统架构,以其灵活性和可扩展性吸引了越来越多的开发者。在微服务架构中,每个服务都是独立的,具有完整的功能和数据职责。本文旨在探讨如何设计和实现高效的微服务系统,以应对现代应用中日益增长的需求。服务注册和发现:服务注册表和反向代理服务。服务路由:服务发现和路由器。服务安全:访问控制、加密和认证。分布式事务:分布式事务工具,如乐观锁。消息队列:异步处理和消息传递。_基于微服务的系统

全网最有效解决centos7 安装MySQL报错No package mysql-server available_no package mod_auth_mysql available.-程序员宅基地

文章浏览阅读856次。今天想在centos7上面装一个mysql,但是无论我yum就还是wget都装不上,提示No package mysql-server…,然后又度娘又各种查资料,试了好多种方法都没有用,最后了解Centos7系统后发现,Centos7带有MariaDB而不是MySQL,MariaDB和MySQL一样也是开元的数据库,同样可以使用yum命令安装,只不过安装使用的并不是老方式的MySQL,而是默认的MariaDB,并且还需要安装的是mariadb-server,如果想继续使用老方式的MySQL,那么需要清_no package mod_auth_mysql available.

随便推点

TensorFlow及其在自然语言处理中的应用_python tensorflow文本理解-程序员宅基地

文章浏览阅读2k次。作者:禅与计算机程序设计艺术 1.简介自然语言处理(Natural Language Processing,NLP)是人工智能领域的一个重要方向。NLP是利用计算机处理及分析文本、语音、图像等各种媒体形式的信息的一门学科。自然语言处理最主要的任务就是把输入的文本进行解析、理解、整合成有意义的信息。可以_python tensorflow文本理解

rocketmq集群安装配置说明-程序员宅基地

文章浏览阅读343次。2019独角兽企业重金招聘Python工程师标准>>> ..._rocketmq 添加集群

构造一个银行账户类(Java)_java定义一个银行账户类,建立账户id为001,姓名张三-程序员宅基地

文章浏览阅读4.4k次。class Bank{ private String name; private float money; public String getName() { return name; } public void setName(String name) { this.name = name; } public float getMoney() { return mone..._java定义一个银行账户类,建立账户id为001,姓名张三

Docker和DockerMachine的对比-程序员宅基地

文章浏览阅读295次,点赞5次,收藏7次。1.背景介绍1. 背景介绍Docker和Docker-Machine都是在容器化技术的基础上发展出来的,它们在软件开发和部署方面发挥了重要作用。Docker是一个开源的应用容器引擎,它使用容器化技术将软件应用与其依赖包装在一起,以便在任何环境中快速部署和运行。Docker-Machine是一个用于管理Docker主机的工具,它可以创建和管理远程Docker主机,以便在不同的环境中运行Doc...

CCF CSP 201703-1 分蛋糕(Java-100分)_ccfcsp分蛋糕-程序员宅基地

文章浏览阅读787次。试题编号: 201703-1试题名称: 分蛋糕时间限制: 1.0s内存限制: 256.0MB问题描述: 问题描述  小明今天生日,他有n块蛋糕要分给朋友们吃,这n块蛋糕(编号为1到n)的重量分别为a1, a2, …, an。小明想分给每个朋友至少重量为k的蛋糕。小明的朋友们已经排好队准备领蛋糕,对于每个朋友,小明总是先将自己手中编号最小的蛋糕分_ccfcsp分蛋糕

前端访问性:实现可访问性与易用性-程序员宅基地

文章浏览阅读902次,点赞22次,收藏14次。1.背景介绍前端访问性是一种设计理念,它关注于为所有用户提供相同或类似的体验,无论他们的能力、年龄、技能水平或其他因素。可访问性和易用性是前端访问性的关键组成部分,它们确保了网站或应用程序对所有用户都是友好的。在过去的几年里,前端访问性变得越来越重要,因为互联网已经成为了人们生活和工作的重要组成部分。因此,确保所有用户都能够轻松地使用网站或应用程序变得至关重要。在本文中,我们将讨论前端...

推荐文章

热门文章

相关标签