当前位置: 首页 > news >正文

51单片机LED闪烁编程实战

一,  LED的闪烁

本学习采用的华中科大开发板

首先需要学习的是LED模块和51单片机的主板模块:
从原理图可以每一个LED所连接的GPIO接口,由于这里需实现D1灯泡闪烁,观察原理图,可知写代码需要设置P20接口,由于这里需实现点亮第一个LED灯,那么就是对P20进行赋值1,给予高电平操作。然后,可以看到旁边是有一个VCC的,那么就是那边提供一个高平,低电平是GND,所以我们这里就要把这个接口设置为低电平,0就是低电平,1就是高电平。

#include <STC89C5xRC.H>void main(){P20 = 0;while(1);
}

1 代码解析

这个P20到底是一个什么东西?我们可以右击看这个头文件,查看这个变量的类型和含义

sfr P2   = 0xA0;
sbit P20 = P2^0;
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;

sfr为Keil C51编译器所提供的扩展数据类型,用于声明单片机的特殊功能的寄存器特殊功能的寄存器用于控制和配置单片机中的各种硬件操作,如:GPIO,定时器,串口等,每组GPIO(P0,P1,P2,P3,P4)均有一个对应的8位寄存器

sfr类型

(1)  sfr的定义

sfr是 特殊功能寄存器 的声明关键字。它告诉编译器,声名的变量名 P2 并不是一个普通的内存变量,而是对应着单片机内部一个具有特殊功能的寄存器的地址0xA0 是特殊功能寄存器 P2 在单片机内存地址空间中的硬件地址。

(2)  对应的作用

是单片机的一个8位并行输入/输出端口。它由8个物理引脚(P2.0 到 P2.7)组成,可以用于控制外部设备(如LED、按键、数码管等)或读取外部信号,这里每一个位对应着一个引脚的电平控制。

sbit类型

(1)  sbit的定义

sbit是 位寻址 的声明关键字。它用于定义一个特殊功能寄存器中的某一位。

(2)  变量的的定义
P00为该位的名称,可以自己定义

(3)  ^的作用
^ 左边必须是一个已经定义好的 sfr 变量(比如 P2,它代表整个端口)。右边是一个0到7的数字,指定要访问这个8位寄存器中的哪一位(0是最低位LSB,7是最高位MSB)


通过sbit可变量赋值可以修改寄存器对应的某一个值,入P0^0表示为寄存器的0位

后面while就是卡死,让LED持续点亮

2 GPIO内部的电路结构

(1)  n形mos管的做作用

如上图的一个像n的一个玩意就是n形mos管,如果经过反门为高电平,此路就导通,如果为低电平,此路就不导通。

(2)  GPIO的工作原理

端口寄存器就是用来存储0-1数据的,当端口寄存器为0,这个时候有一个反门,然后设置为1为高电平,这个时候mos管导通,引脚接地,此时引脚就变成了低电平,如果端口寄存器为0的时候,此时输出高电平1,则接上面的电压,就是一个电阻上面一个杠的就是一个电源,然后此时引脚就是高电平。

3 扩展其他LED模块

下面是一个其他51单片机的LED模块

这里主要讲述的为这个三极管的作用,这个三极管我们可以看到是连接P34端口的
这个三极管是npn类型,当上面出现高电平的时候,才可以导通,这个时候我们有了这个就可以控制这整个电路了

二,  流水灯

1 设计需求

从P20到P27的LED灯依次进行点亮,间隔为100ms,不断地进行循环

2 软件设计

首先我们要知道二进制和十六进制和移位运算符

#include<STC89C5xRC.H>void Delay100ms(void)	//@11.0592MHz
{unsigned char data i, j;i = 180;j = 73;do{while (--j);} while (--i);
}int main(){while(1){//直接对P2进行操作,那么就是对P2全部进行操作了;//P2 = 1111 11110;//由于C语言不支持二进制写法,所以要转为16进制P2 = 0xFE;Delay100ms();P2 = 0xFD;Delay100ms();P2 = 0XFB;Delay100ms();}
}

首先C语言是不允许存储二进制地,那么我们就要转换为十六进制
但是这压根是一个一个写的,十分的麻烦,所以我们就要进行简化代码

#include <STC89C5xRC.H>
#include <intrins.h>void Delay100ms(void)	//@11.0592MHz
{unsigned char data i, j, k;_nop_();_nop_();i = 5;j = 52;k = 195;do{do{while (--k);} while (--j);} while (--i);
}void main(){// 流水灯代码unsigned char temp = 0x01;// 测试1:所有LED全亮P2 = 0x00;  // 共阴接法,全亮Delay100ms();Delay100ms();Delay100ms();// 测试2:所有LED全灭  P2 = 0xFF;  // 共阴接法,全灭Delay100ms();Delay100ms();Delay100ms();while(1){P2 = ~temp;Delay100ms();temp <<= 1;if(temp == 0x00){temp = 0x01;}}
}

首先我们进行一个0000 0001的赋值,然后我们对这个进行取反,那么我们就可以获得1111 1110,这个就是第一个流水灯的点亮信号,然后我们在对这0000 0001进行左移变成0000 0010,然后再对这个进行取反就是第二个流水灯的信号...,以此类推就可以得到每一次都精准对每一位赋值。

3  左移的操作
左移的基本概念
左移操作用符号<<表示。
对于一个二进制数x,左移n位的操作可以表示为x << n。
左移时,左边的n位会被丢弃,右边会补上n个0。

三, 闪烁LED

1  基于点亮LED修改

思路:就是不断的为把这个P20的状态在0和1中进行反复调整
那么我们只需要进行调整就好了

代码1

#include <STC89C5xRC.H>
#include <INTRINS.H>void main(){unsigned char i;unsigned char j;//255为该类型的最大值while(1){P20 = 0;for(i = 1; i < 255; i++){for(j = 1; j < 255; j++){}}P20 = 1;for(i = 1; i < 255; i++){for(j = 1; j < 255; j++){}}}
}

我们只现需要在while循环里面进行嵌套两个for循环就好了,unsigned char的最大值为255,所以我们只可以设置到255,要不然无法出循环,因为又进行从0开始了
如此反复就可以实现这个灯光的闪烁了。

优化代码2

但是上面的代码还是不够号,我们要优化我们的代码才可以

void main(){unsigned char i;unsigned char j;//255为该类型的最大值while(1){P20 = ~P00;//取反for(i = 1; i < 255; i++){for(j = 1; j < 255; j++){}}}
}

我们在此基础上取了一个取反操作,但是我们无法估计这个时间开销了多少,所以这个是ISP出了一个软件延迟计算机。

优化代码3

然后我们只需要把这个代码复制到里面就好了

void Delay500ms(void)	//@11.0592MHz
{unsigned char data i, j, k;_nop_();//这个为no  operator---空操作//因为下面的操作无法精确这个时间//所以我们需要这个进行微调来精确时间i = 4;j = 129;k = 119;do{do{while (--k);} while (--j);} while (--i);
}void main(){while(1){P20 = ~P00;Delay500ms();}
}

这个_nop_( )函数是在#include <INTRINS.H>这个头文件里面的


文章转载自:

http://2Bkkp51f.trtxt.cn
http://AdvuANdQ.trtxt.cn
http://xqRymgFZ.trtxt.cn
http://76ukQBJo.trtxt.cn
http://TqEmpaUe.trtxt.cn
http://wxBFxOiv.trtxt.cn
http://8NqAcMZh.trtxt.cn
http://uoRP0XIF.trtxt.cn
http://9Il1yiOj.trtxt.cn
http://CNhguGBl.trtxt.cn
http://71428sPM.trtxt.cn
http://iG96exk3.trtxt.cn
http://F3jKu19T.trtxt.cn
http://hakBXcFJ.trtxt.cn
http://PzQAB3sr.trtxt.cn
http://SRpOdaon.trtxt.cn
http://yvyaYrco.trtxt.cn
http://YTppWS0z.trtxt.cn
http://TDU4sMDl.trtxt.cn
http://7KUvVrig.trtxt.cn
http://QxYalhAM.trtxt.cn
http://dVnzo0vm.trtxt.cn
http://WyTsisPa.trtxt.cn
http://pBSINzDa.trtxt.cn
http://71776kpu.trtxt.cn
http://DUE487vh.trtxt.cn
http://2gT9PxsF.trtxt.cn
http://AptNLVA9.trtxt.cn
http://UvnyKwAQ.trtxt.cn
http://yHvGsprh.trtxt.cn
http://www.dtcms.com/a/385836.html

相关文章:

  • 字符数组与字符串
  • ⸢ 肆-Ⅱ⸥ ⤳ 风险发现体系的演进(上):背景与现状
  • [js解密分析]方仔照相馆:用3D电子说明书重塑定制积木体验
  • 【Vue3 ✨】Vue3 入门之旅 · 第一篇:Vue3 简介与新特性概览
  • docker 容器中导出pg数据库
  • 【软考】笔记总结一
  • 云望无人机图传16公里原理:云端成像的新纪元,远距离传输不再难
  • OpenHarmony包管理子系统核心源码深度解读:从BundleManager到AMS,彻底打通应用安装、卸载与沙箱机制全链路
  • 10套政务类BI可视化大屏案例:原型设计思路拆解
  • 从零开始的云计算生活——第六十四天,志存高远,性能优化模块
  • 从C++开始的编程生活(10)——string类基本语法和auto自动推导类型
  • 深入理解MySQL主从架构中的Seconds_Behind_Master指标:并行复制优化与云原生实践
  • LAS点云格式转3DTiles全攻略:GISBox的高效实现与技术解析
  • AWS网站访问慢?CloudFront CDN加速配置教程 (2025)
  • AWS Certified AI Practitioner
  • Thomson Reuters 如何通过 AWS转型推动NET现代化
  • TDengine IDMP 基本功能——数据可视化(1. 趋势图)
  • 改进后的 Highcharts for React:更直观、更现代、更高效!
  • 运维安全05,iptables规则保存与恢复
  • 数据可视化 | 热力图理论与案例分析
  • 游戏开发公司应该要注意哪些网络安全问题
  • python 自动化从入门到实战-开发一个接口get post管理请求工具(9)
  • 认知语义学中的意象图式对AI自然语言处理中隐喻分析的影响与启示
  • Edge浏览器的自动化点击系统
  • 达梦数据库巡检常用语句
  • 基于Spring Cloud Gateway的全链路限流策略对比与实践指南
  • ​Oracle存储的实现:一个8KB块能存储多少行数据?​​一个块存不下一行数据会出现什么情况?
  • React学习教程,从入门到精通,React 组件事件处理语法知识点及使用方法(21)
  • ChatGPT 辅助重构:老旧 jQuery 项目迁移到 React 的协作日志
  • 嵌入式数据结构笔记五——循环链表内核链表