(51单片机)独立按键控制流水灯LED流向(独立按键教程)(LED使用教程)

news2025/4/9 21:31:42

 源代码

如上图将7个文放在Keli5 中即可,然后烧录在单片机中就行了

烧录软件用的是STC-ISP,不知道怎么安装的可以去看江科大的视频:

【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.bilibili.com/video/BV1Mb411e7re?p=2&vd_source=ada7b122ae16cc583b4add52ad89fd5e

源代码:

头文件要记得宏定义和重定义,避免重复调用:

#ifndef _Timer0_h_//名字根据文件名定义即可
#define _Timer0_h_

//声明函数……

#endif

 main.c

#include <STC89C5xRC.H>
#include <INTRINS.H>
#include "Timer0.h"
#include "Key.h"//调用头文件

unsigned char KeyNum,LEDMode;//定义全局变量KeyNum(获取按键的值),LEDMode(切换流水灯流向)
void main()
{
	P2=0xFE;//初始化灯P20=0,1111 1110(就是让01灯亮)
	Timer0_Init();//初始化定时器/计时器
	while(1)
	{
		KeyNum=Key();//获取按键值
		if(KeyNum){
			if(KeyNum==1){
				LEDMode++;//切换流水灯模式
				if(LEDMode>=2)LEDMode=0;
			}
		}
	}
}
//中断程序函数

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;//局部静态变量
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=1000){
		T0Count=0;
		if(LEDMode==0)P2=_crol_(P2,1);//左移函数,P2每秒左移动一次
		if(LEDMode==1)P2=_cror_(P2,1);//右移函数,P2每秒右移动一次
	}
}

Timer0.c

#include <STC89C5xRC.H>

//void Timer0_Init()
//{
//	TF0=0;TR0=1;//TCON,寄存器
//	//TMOD=0x01;//0000 0001,寄存器
//	TMOD=TMOD&0xF0;//把TMOD的低四位清零,高四位不变,方便使用两个定时器
//	TMOD=TMOD&0x01;//把TMOD的最低位置1,高四位不变,方便使用两个定时器
//	TH0=64535/256;//高电位,寄存器,1毫秒
//	TL0=64535%256;//低电位,寄存器,1毫秒
//	ET0=1;EA=1;PT0=0;//打开中断开关
//	
//}
//定时器0初始化函数
void Timer0_Init()		//1毫秒@11.0592MHz
{
//	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;//允许中断
	EA=1;//允许总中断
	PT0=0;//低优先级
}


中断程序函数
//中断函数模版
//void Timer0_Routine() interrupt 1
//{
//	static unsigned int T0Count;
//	TL0 = 0x66;		//设置定时初值
//	TH0 = 0xFC;		//设置定时初值
//	T0Count++;
//	if(T0Count>=1000){
//		T0Count=0;
//		P20=~P20;
//	}
//}

Timer0.h

#ifndef _Timer0_h_
#define _Timer0_h_

void Timer0_Init();


#endif

Key.c

#include <STC89C5xRC.H>
#include "Delay.h"

unsigned char Key()//获取独立按键
{
	unsigned char KeyNumber=0;
	//进行判断是否摁下按键和防抖操作
	if(P31==0){Delay(20);while(P31==0);Delay(20);KeyNumber=1;}
	if(P30==0){Delay(20);while(P30==0);Delay(20);KeyNumber=2;}
	if(P32==0){Delay(20);while(P32==0);Delay(20);KeyNumber=3;}
	if(P33==0){Delay(20);while(P33==0);Delay(20);KeyNumber=4;}
	return KeyNumber;
}

 Key.h

#ifndef _Key_h_
#define _Key_h_

unsigned char Key();

#endif

Delay.c 

//Delay.c

#include <STC89C5xRC.H>
#include <INTRINS.H>

//延时函数
void Delay(unsigned int xms)		//@11.0592MHz
{
	unsigned char i, j;
	while(xms){
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

 Delay.h

//Delay.h

#ifndef __Delay_H__
#define __Delay_H__

//延时函数头文件
void Delay(unsigned int xms);
#endif

 代码解析与教程:

main.c
  • 注释解释很清楚,重点来讲解一下中断函数中的左移右移函数
    他们哥俩是依赖头文件<INTRINS.H>的库函数

    会用即可,这是char类型的,里面也有其他类型的,参数一是要移动的数,参数二是移动的位数。
    例如:0000 0001使用左移函数_crol_左移一位就是0000 0010,其他同理,因此,加上中断函数,灯就会每秒移动一次
 Dealy模块
  • 包含源代码与头文件,不需要知道怎么实现的会用即可,后续使用,直接将头文件和源代码拿过来用即可;

xms是定义的毫秒,1000毫秒就是1秒;模版生成的是1毫秒的,因此xms等于1000
 Timer0模块
  • 包含源代码与头文件,需要知道怎么实现,会用
  • 51单片机的定时器和计数器十分重要,要理解怎么用,要知道原理是什么,要结合原理图来分析怎么做,先看代码
#include <STC89C5xRC.H>

//void Timer0_Init()
//{
//	TF0=0;TR0=1;//TCON,寄存器
//	//TMOD=0x01;//0000 0001,寄存器
//	TMOD=TMOD&0xF0;//把TMOD的低四位清零,高四位不变,方便使用两个定时器
//	TMOD=TMOD&0x01;//把TMOD的最低位置1,高四位不变,方便使用两个定时器
//	TH0=64535/256;//高电位,寄存器,1毫秒
//	TL0=64535%256;//低电位,寄存器,1毫秒
//	ET0=1;EA=1;PT0=0;//打开中断开关
//	
//}
//定时器0初始化函数
void Timer0_Init()		//1毫秒@11.0592MHz
{
//	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;//允许中断
	EA=1;//允许总中断
	PT0=0;//低优先级
}


中断程序函数
//中断函数模版
//void Timer0_Routine() interrupt 1
//{
//	static unsigned int T0Count;
//	TL0 = 0x66;		//设置定时初值
//	TH0 = 0xFC;		//设置定时初值
//	T0Count++;
//	if(T0Count>=1000){
//		T0Count=0;
//		//下面是代码区
//	}
//}
  • 最上面注释掉的代码是要求理解的;中间的代码是STC-ISP软件生成的;最下面的代码是中断函数模版,拿到main.c中可直接使用,但是也要了解原理:

大家可以这个博客深度理解定时器计数器和中断,这个是教程博客:(51单片机)计时器时钟(C语言代码编撰)(定时器/中断器、计数器教程)(51单片机重点)-CSDN博客

 Key模块
  • 包含源代码与头文件,不需要知道怎么实现的会用即可,后续使用,直接将头文件和源代码拿过来用即可;

    序号1是按键的防抖操作,不需要理解,有按键的地方直接用即可
    序号2是独立按键控制变量。
    KeyNumber就是返回值,按键K1就返回1,其他同理

 独立按键教程、LED教程

 由于单片机系列版本不一样,单片机核心控制可能会有不同,例如:有些单片机的LED的L1是P21,有些就是P2_1,需要看单片机核心,或者头文件:

 可以看到我的STC89C52RC是P21;

独立按键 
  • 先看原理图:
     

    可以看到控制K1的是P31,同理K2是P30,按键都是高电位,因此只要将P31设置成0,就是按键通电,相当于激活
 LED教程
  • 先看原理图:

    LED是高电位,设定为0就是通电
  • P2就是16进制的LED灯总控制,如:0xFF=1111 1111,就是全关,例如代码中的:
    P2=0xFE,就是1111 1110,就是L1亮,左移一位就是1111 1101,就是L2亮,其他同理,配合中断函数,就可以每秒移动一次

效果视频: 

(51单片机)按键控制流水灯移位

 注:该代码是本人自己所写,可能不够好,不够简便,欢迎大家指出我的不足之处。如果遇见看不懂的地方,可以在评论区打出来,进行讨论,或者联系我。上述内容全是我自己理解的,如果你有别的想法,或者认为我的理解不对,欢迎指出!!!如果可以,可以点一个免费的赞支持一下吗?谢谢各位彦祖亦菲!!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2329807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

react-router children路由报错

项目场景&#xff1a; 写个路由页面&#xff0c;引发的问题 问题描述 报错&#xff1a; An absolute child route path must start with the combined path of all its parent routes. 代码&#xff1a; import { createBrowserRouter } from "react-router-dom";…

Socket编程TCP

Socket编程TCP 1、V1——EchoServer单进程版2、V2——EchoServer多进程版3、V3——EchoServer多线程版4、V4——EchoServer线程池版5、V5——多线程远程命令执行6、验证TCP——Windows作为client访问Linux7、connect的断线重连 1、V1——EchoServer单进程版 在TcpServer.hpp中实…

文件映射mmap与管道文件

在用户态申请内存&#xff0c;内存内容和磁盘内容建立一一映射 读写内存等价于读写磁盘 支持随机访问 简单来说&#xff0c;把磁盘里的数据与内存的用户态建立一一映射关系&#xff0c;让读写内存等价于读写磁盘&#xff0c;支持随机访问。 管道文件&#xff1a;进程间通信机…

代码随想录回溯算法03

93.复原IP地址 本期本来是很有难度的&#xff0c;不过 大家做完 分割回文串 之后&#xff0c;本题就容易很多了 题目链接/文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;回溯算法如何分割字符串并判断是合法IP&#xff1f;| LeetCode&#xff1a;93.复原IP地址_哔哩哔…

批量改CAD图层颜色——CAD c#二次开发

一个文件夹下大量图纸&#xff08;几百甚至几千个文件&#xff09;需要改图层颜色时&#xff0c;可采用插件实现&#xff0c;效果如下&#xff1a; 转换前&#xff1a; 转换后&#xff1a; 使用方式如下&#xff1a;netload加载此dll插件&#xff0c;输入xx运行。 附部分代码如…

【内网安全】DHCP 饿死攻击和防护

正常情况&#xff1a;PC2可以正常获取到DHCP SERVER分别的IP地址查看DHCP SERCER 的ip pool地址池可以看到分配了一个地址、Total 253个 Used 1个 使用kali工具进行模拟攻击 进行DHCP DISCOVER攻击 此时查看DHCP SERVER d大量的抓包&#xff1a;大量的DHCP Discover包 此时模…

10种电阻综合对比——《器件手册--电阻》

二、电阻 前言 10种电阻对比数据表 电阻类型 原理 特点 应用 贴片电阻 贴片电阻是表面贴装元件&#xff0c;通过将电阻体直接贴在电路板上实现电路连接 体积小、重量轻&#xff0c;适合高密度电路板&#xff1b;精度高、稳定性好&#xff0c;便于自动化生产 广泛应用于…

剑指Offer(数据结构与算法面试题精讲)C++版——day6

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day6 题目一&#xff1a;不含重复字符的最长子字符串题目二&#xff1a;包含所有字符的最短字符串题目三&#xff1a;有效的回文 题目一&#xff1a;不含重复字符的最长子字符串 这里还是可以使用前面&#x…

freertos韦东山---事件组以及实验

事件组的原理是什么&#xff0c;有哪些优点&#xff0c;为啥要创造出这个概念 在实时操作系统&#xff08;如 FreeRTOS&#xff09;中&#xff0c;事件组是一种用于任务间同步和通信的机制&#xff0c;它的原理、优点及存在意义如下&#xff1a; 事件组原理 数据结构&#xf…

架构师面试(二十六):系统拆分

问题 今天我们聊电商系统实际业务场景的问题&#xff0c;考查对业务系统问题的分析能力、解决问题的能力和对系统长期发展的整体规划能力。 一电商平台在早期阶段业务发展迅速&#xff0c;DAU在 10W&#xff1b;整个电商系统按水平分层架构进行设计&#xff0c;包括【入口网关…

Java中的同步和异步

一、前言 在Java中&#xff0c;同步&#xff08;Synchronous&#xff09;和异步&#xff08;Asynchronous&#xff09;是两种不同的任务处理模式。核心区别在任务执行的顺序控制和线程阻塞行为。 二、同步&#xff08;Synchronous&#xff09; 定义&#xff1a;任务按顺序执行…

在 Ubuntu24.04 LTS 上 Docker Compose 部署基于 Dify 重构二开的开源项目 Dify-Plus

一、安装环境信息说明 硬件资源&#xff08;GB 和 GiB 的主要区别在于它们的换算基数不同&#xff0c;GB 使用十进制&#xff0c;GiB 使用二进制&#xff0c;导致相同数值下 GiB 表示的容量略大于 GB&#xff1b;换算关系&#xff1a;1 GiB ≈ 1.07374 GB &#xff1b;1 GB ≈ …

NO.64十六届蓝桥杯备战|基础算法-简单贪心|货仓选址|最大子段和|纪念品分组|排座椅|矩阵消除(C++)

贪⼼算法是两极分化很严重的算法。简单的问题会让你觉得理所应当&#xff0c;难⼀点的问题会让你怀疑⼈⽣ 什么是贪⼼算法&#xff1f; 贪⼼算法&#xff0c;或者说是贪⼼策略&#xff1a;企图⽤局部最优找出全局最优。 把解决问题的过程分成若⼲步&#xff1b;解决每⼀步时…

瑞萨RA4M2使用心得-KEIL5的第一次编译

目录 前言 环境&#xff1a; 开发板&#xff1a;RA-Eco-RA4M2-100PIN-V1.0 IDE&#xff1a;keil5.35 一、软件的下载 编辑瑞萨的芯片&#xff0c;除了keil5 外还需要一个软件&#xff1a;RASC 路径&#xff1a;Releases renesas/fsp (github.com) 向下找到&#xff1a; …

数据分析-Excel-学习笔记

Day1 复现报表聚合函数&#xff1a;日期联动快速定位区域SUMIF函数SUMIFS函数环比、同比计算IFERROR函数混合引用单元格格式总结汇报 拿到一个Excel表格&#xff0c;首先要看这个表格个构成&#xff08;包含了哪些数据&#xff09;&#xff0c;几行几列&#xff0c;每一列的名称…

整车CAN网络和CANoe

车载网络中主要包含有Can网络,Lin网络,FlexRay,Most,以太网。 500kbps:500波特率,表示的数据传输的速度。表示的是最大的网速传输速度。也就是每秒 500kb BodyCan车身Can InfoCan娱乐信息Can 车身CAN主要连接的是ESB电动安全带 ADB自适应远光灯等 PTCan动力Can 底盘Can

ChatGPT 的新图像生成器非常擅长伪造收据

本月&#xff0c;ChatGPT 推出了一种新的图像生成器&#xff0c;作为其 4o 模型的一部分&#xff0c;该模型在生成图像内的文本方面做得更好。 人们已经在利用它来生成假的餐厅收据&#xff0c;这可能会为欺诈者使用的已经很广泛的 AI 深度伪造工具包添加另一种工具。 多产的…

JS页面尺寸事件

元素位置 在这里插入图片描述 父元素带有定位时输出相对于父亲元素的距离值

网络协议之基础介绍

写在前面 本文看下网络协议相关基础内容。 1&#xff1a;为什么要有网络协议 为了实现世界各地的不同主机的互联互通。 2&#xff1a;协议的三要素 协议存在的目的就是立规矩&#xff0c;无规矩不成方圆嘛&#xff01;但是这个规矩也不是想怎么立就怎么立的&#xff0c;也…

初识数据结构——Java集合框架解析:List与ArrayList的完美结合

&#x1f4da; Java集合框架解析&#xff1a;List与ArrayList的完美结合 &#x1f31f; 前言&#xff1a;为什么我们需要List和ArrayList&#xff1f; 在日常开发中&#xff0c;我们经常需要处理一组数据。想象一下&#xff0c;如果你要管理一个班级的学生名单&#xff0c;或…