51入门之LED

        

目录

1.配置文件

2.点亮一个LED

2.1单个端口操作点亮单个LED

2.2整体操作点亮LED

3.LED闪烁

4.LED实现流水灯

        4.1使用for循环和移位实现

4.1.1移位操作符       

4.1.2使用移位操作和for循环实现

        4.2使用移位函数实现LED流水灯


        众所周知,任何一个硬件工程师都是从点亮一个LED开始的,点亮一个LED,相当于软件中的第一个Hello World,都是一个最基础的东西,今天就开始点亮一个LED,探寻单片机的奥秘,

1.配置文件

        首先,我们需要使用的开发板是普中的51单片机开发板,其次,我们使用的编写程序的软件是Keil5,使用C语言编程。现在就来开始点亮一个LED吧!

        首先我们需要建立一个项目,我们的项目建立之后会有很多的散乱的小文件,所以我们就要建立一个大文件夹,再在里面建立一个子文件夹,把我们的项目放在里面。

        首先,打开Keil5

然后把我们的项目建立到刚刚的子文件夹里面就行了。

保存之后,会出现下面的这样的窗口:

        我们使用的51单片机型号是STC89C52,这里找不到,但是我们可以找到型号匹配的,就是AT89C52,我们可以使用AT89C52来创建我们的新项目

我们可以像这样点击Atmel里面找到AT89C52,也可以在上面的搜索框里面直接搜索AT89C52,点击OK,会弹出一个页面

点击否就行了。

我们左边的窗口就出现了我们的项目

鼠标右击Source Group1

点击Add New Item

选择C语言,然后命名即可 

成功创建之后,我们的左边就会出现这样的东西

这说明我们的文件已经常见成功,可以开始写代码了。 

2.点亮一个LED

        GPIO(general purpose intput output)是通用输入输出端口的简称,可 以通过软件来控制其输入和输出。

这就是我们芯片的引脚图,一共有40个引脚,这些引脚可以用分为下面几个大类:

  1. 电源引脚:引脚图中的 VCC、 GND 都属于电源引脚。
  2. 晶振引脚:引脚图中的 XTAL1、XTAL2 都属于晶振引脚。
  3. 复位引脚:引脚图中的 RST/VPD 属于复位引脚,不做其他功能使用。
  4. 下载引脚:51 单片机的串口功能引脚(TXD、RXD)可以作为下载引脚 使用。
  5. GPIO 引脚:引脚图中带有 Px.x 等字样的均属于 GPIO 引脚。

我们需要使用的就是P2端口

        在开发板上,我们的LED就是这样排列的,P20到P27我们可以统称为P2端口,我们只需要给P2端口赋值就可以得到我们想要的LED效果。

        我们都知道,LED是一个二级管一样的东西,就上面的图片而言,我们的迪纳留只能从VCC流向P2端口,所以我们如果想要LED发光,我们就需要保证LED左右有电位差,左边是正极,右边是我们控制的P2端口,我们就需要在软件中给它们一个数字0表示低电平,这样我们的LED才会点亮。

        现在我们只想要D1点亮,我们就可以把其它的几个P2端口全部设置为高电平,P20端口设置为低电平(也可以只设置P20端口,因为引脚默认都是上拉的,也就是所有端口默认都是高电平)。

        这里我们可以有两种方式点亮这个D1,一个是单个操作,一个是整体操作:

2.1单个端口操作点亮单个LED

        

        在所有操作之前,我们要包含一个头文件,我们可以右键单击点击直接插入头文件,也可以自己写一个出来,总之就要包含整个头文件,因为这个头文件里面有我们所有的关于引脚的定义。头文件里的名字也可以写成reg52.h,大小写不会造成影响

        然后我们需要使用一个关键词sbit,就可以定义单个引脚,sbit LED1 = P2^0;这样就完成了对一个引脚的重定义,我们就可以直接对LED1赋值间接对P20端口赋值。当然,只要你喜欢,这里的LED1只是一个名字,你可以换成任何非关键字的名字,然后使用。

        这里就得到代码:

#include <REGX52.H>
sbit LED1=P2^0;
void main()
{LED1 = 0;
}

        我们想要把这个代码烧入到我们的单片机上,我们就要安装驱动,连接数据线,下载软件,这里就不演示了,网上有很多的资料和视频,买开发板的时候商家也会赠送这些东西。

        这里使用的是普中官方的软件使用它就可以把我们电脑上的编译链接生成的文件烧入到开发板上,在此之前,我们还要先生成这个文件。

        左上角有三个按钮,第一个是只编译不生成文件,第二个是只编译最新更改的文件,第三个是编译所有文件,一般来说我们使用第二个用到比较多,因为当我们的代码数量众多的时候,每次全部编译效率就会很慢,所以最好使用中间的。

        

        我们点击一次之后下面就会出现这样的提示, 0 Error(s), 0 Warning(s) 就是让人兴奋的事情,这说明我们的程序没有问题,可以使用了,然后我们需要使用烧入的软件找到生成的hex文件,但是程序默认是不会生成hex文件的,我们就要再配置一下

        点击魔术棒,然后再点击Output,再点击生成hex文件,然后我们再点击一次编译

        我们发现多了这样的一条提示,这样就说明我们的我呢见成功生成了,我们就可以使用烧入软件开始烧入了

点击”打开文件“

找到hex文件之后开始配置其他的东西,比如选择插入了USB线的串口(需要有CH340驱动的标注),还有芯片类型和波特率

        然后就是把板子上电,并点击”程序下载“

出现了这样的程序下载成功就说明我们成功把东西下载到了板子上,你就成功点亮了一个LED!

2.2整体操作点亮LED

        整体操作就是直接对P2端口操作,这样我们只要对P2端口就可以点亮一个LED,或者是多个LED,就不需要我们反复使用sbit定义端口了。

        具体操作就是直接对P2赋值,假设我们想要让第一个灯亮,其他灯不亮,我们就要确保其他的都是高电平,而第一个灯是低电平,表示出来就是 : 0111 1111  但是这里有一个问题就是,我们的软件不会把它当作二进制处理,而是默认当作十进制处理,这样就和我们原本的意愿相悖了。一般我们使用的话,就会把它转化成十六进制:0111当作一位,1111当作一位,处理成为十六进制

        不过这里还有个问题:那就是我们的数据是按照类似数据结构中的栈处理的,也就是它按照0111 1111的顺序进入的话,它拿出来的时候是1111 1110,然后会出现一个问题,就是我们的开发板上亮的就不是我们想要的LED1,而是LED8,所以我们想要LED1亮的话,我们就要使用反向推理,也就是我们需要提前把这个我们想要的数据反抓一下,我们单片机得到的就是正确的数据了,比如我们就可以使用1111 1110输入,转换成十六进制就是0xfe(这里的大小写没有影响),这样我们就得到了LED1亮的情况了。

        所以我们就可以写出代码:

#include <REGX52.H>void main()
{P2 = 0XFE;
}

然后上电烧入程序就行了

3.LED闪烁

        我们想要一个LED闪烁,也就是可以简化成把一个LED在点亮和熄灭之间反复切换,但是单片机操作的速度是很快的,肉眼无法观察到它的闪烁,所以我们就要使用一个暂停函数来让它们之间有一定的时间暂停不动,之后再进行下一个操作,这样我们就可以观察到它的闪烁了。

        我们要实现这样的暂停函数,可以借助另外一个工具

这个也是一个软件,可以用来烧入,而且功能丰富,但是我更喜欢用另外一个,因为操作简单点。

        这个软件也是板子配套的软件,我们可以使用它生成暂停函数

        我们可以在上面找到”软件延时计时器“

        选择好相应的系统频率和定时长度,然后点击生成C代码,再点击复制代码,然后我们在Keil里粘贴这个代码。

        到这里还不能直接使用,我们还要包含一个头文件#include <INTRINS.H>,这样函数里的_nop_函数才能够使用。

        之后,我们就可以把代码放在主函数中使用了。像这样:

void main()
{P2 = 0XFE;//点亮LED1Delay500ms();P2 = 0XFF;//熄灭LED1Delay500ms();
}

        然后就可以看到板子上LED1在不停闪烁了。

        但是这个代码还不完善,在单片机内部,其实是在不断调用main函数的,这并不太规范,我们可以加上一个while(1) 的死循环使它进入了main函数就不退出,并且能一直执行我们的闪烁指令。从某种意义上,提高了一点效率。

        完整代码就是这样:

#include <REGX52.H>
#include <INTRINS.H>
void Delay500ms()		//@11.0592MHz
{unsigned char i, j, k;_nop_();_nop_();i = 22;j = 3;k = 227;do{do{while (--k);} while (--j);} while (--i);
}void main()
{while(1){P2 = 0XFE;Delay500ms();P2 = 0XFF;Delay500ms();}
}

        但是我们突然想要把闪烁频率加快怎么办呢?再重新生成代码吗?

        我们可以生成一个1ms的函数,然后再通过形参调控我们想要的时间。

#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int xms)		//@11.0592MHz
{while(xms--){unsigned char i, j;_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);}
}void main()
{while(1){P2 = 0XFE;Delay1ms(500);P2 = 0XFF;Delay1ms(500);P2 = 0XFE;Delay1ms(100);P2 = 0XFF;Delay1ms(100);}
}

        这样我们就可以十分灵活使用暂停函数控制闪烁时间和频率了。

4.LED实现流水灯

        LED实现流水灯其实就是上面实现闪烁的改版,我们只要计算出每个灯亮的时候它的对应的指令,然后闪烁,延时,再下一个,反复循环就得到了流水灯。

        但是这样的写法很是费劲,难道我们每次都要这样生成吗?那样多麻烦!

        这个写法很好理解,但是肯定不是最好的写法。

        4.1使用for循环和移位实现

4.1.1移位操作符       

        我们C语言中有一个操作符:<<(左移位)和 >>(右移位),移位左边是一个数,右边是需要移动的位数。

        而移位又分为算数移位和逻辑移位,移位是对一个二进制数的操作,这里讲一下基础的知识。

        首先:二进制中比如1000 1111 这个数如果是有符号整型的话,它的第一位1就是它的符号位,1表示负,0表示正。

        这里的逻辑位移就不考虑符号位,只是单纯的进行移位操作。比如1010 0101进行逻辑左移一位之后,把首位1移除后在最后面补0,得到0100 1010,再左移2位,得到0010 1000,我们发现,它并不会管我们的移除的数字是什么,它只知道移除之后补上0就行了,右移也是同样的道理。

        算数位移很相似,但是有一点不一样,算数位移的首位(符号位)不变,其他的遵循逻辑位移的规律,比如1100 1111右移1位,得到的就是1010 0111,符号位不变,其他位就按照逻辑位移的操作。

        在C51使用的时候,默认的是逻辑位移,就是没有符号位的位移,而且我们还要把它们转化成十六进制,再使用移位操作符。

4.1.2使用移位操作和for循环实现

        这里有一点不好实现的就是,我们使用P2端口定义的时候,比如我们想让它从LED1流水到LED8,这样的话我们初始的就是1111 1110,左移位一次会变成1111 1100,这样就不是只有LED2亮了,所以我们就要换个思路:假如我们的数只有一个1,其他位都是0是不是会更好处理?

        我们就可以把1111 1110取反,得到0000 0001,这样我们控制的时候就可以很精确的控制位了,取反操作符是~,加在我们需要取反的数的前面,比如~(0000 0001)得到的就是1111 1110这样,我们就可以使用取反和移位操作符实现流水灯了。

        我们把初始设定成P2 =~(0x01<<0)(即P2=~0000 0001)),下一个就是P2 = ~(0x01<<1)(即P2 = ~0000 0010),直到LED1到LED8都进行了一次闪烁,回归原位,就完成了流水灯循环。这里我们使用for循环实现。

#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int xms)		//@11.0592MHz
{while(xms--){unsigned char i, j;_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);}
}void main()
{unsigned int i = 0;while(1){for(i = 0;i<8;i++){P2 =~(0x01<<i);Delay1ms(300);}}
}

        这样我们就完成了对流水灯的实现。

        4.2使用移位函数实现LED流水灯

        除了使用 for 循环语句实现移位,KEIL C51 软件内还有对应的移位库函数, 左移函数是_crol_(),右移函数是_cror_(),而且这里要注意它们需要包含头文件#include <INTRINS.H>才可以使用,这两个函数和左移右移操作符的区别就是它们移位之后不会让多余的位补上0,而是顺延移出位的数,比如1001 1100左移一位,得到的是0011 1001,相当于我们把整体的数字往前推了一位,把推出的数字放回到末尾,这样的函数使得我们对流水灯的理解更加简便,我们不再需要使用取反符号,只要使用移位操作就好了。

        我们原本的数字是1111 1110,只要使用左移函数_crol_()就可以实现流水灯效果,即使用P2接收P2左移一位的返回值,直接改变P2,循环反复即可

#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int xms)		//@11.0592MHz
{while(xms--){unsigned char i, j;_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);}
}void main()
{P2 = 0xfe;Delay1ms(100);while(1){P2 = _crol_(P2,1);Delay1ms(100);}
}

        这样就实现了流水灯,还是比较简单的。

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

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

相关文章

基于机器学习的木马检测模型的设计与实现(论文)_kaic

摘 要 科技的发展带来了人们生活的改变&#xff0c;近年来我国网民已突破十亿人口&#xff0c; 而且在后疫 情时代&#xff0c; 经历了疫情时期的一系列线上活动&#xff0c; 人们对网络的依赖比以往任何时期都要高 得多。高频次的上网行为也带来了一系列安全问题&#xff…

Cisco路由器配置IPv6 Manual隧道

Cisco路由器配置IPv6 Manual隧道 IPv6与IPv4共存的方式 IPv6与IPv4共存方式大致有三种&#xff1a; 双栈&#xff1a;要求网络中所有设备均同时支持IPv4和IPv6转换&#xff1a;转换这种方式将IPv6协议的报头转换成IPv4协议报头。隧道&#xff1a;假定两个IPv6节点要使用IPv6…

flink源码编译-job提交

1、启动standalone集群的taskmanager standalone集群中的taskmanager启动类为 TaskManagerRunner 2 打开master启动类 通过 ctrln快捷键&#xff0c;找到、并打开类&#xff1a; org.apache.flink.runtime.taskexecutor.TaskManagerRunner 3 修改运⾏配置 基本完全按照mas…

NIUSHOP完美运营版商城 虚拟商品全功能商城 全能商城小程序 智慧商城系统 全品类百货商城

完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城 干干净净 没有一丝多余收据 还没过手其他站 还没乱七八走的广告和后门 后台可以自由拖曳修改前端UI页面 还支持虚拟商品自动发货等功能 挺不错的一套源码 前端UNIAPP 后端PHP 一键部署版本 源码免费…

腾讯云4核8G服务器性能怎么样?能用来干什么?

腾讯云4核8G服务器多少钱&#xff1f;腾讯云4核8G轻量应用服务器12M带宽租用价格646元15个月&#xff0c;活动页面 txybk.com/go/txy 活动链接打开如下图所示&#xff1a; 腾讯云4核8G服务器优惠价格 这台4核8G服务器是轻量应用服务器&#xff0c;详细配置为&#xff1a;轻量4核…

ros小问题之rosdep update time out问题

在另外一篇ROS 2边学边练系列的文章里有写碰到这种问题的解决方法&#xff08;主要参考了其他博主的文章&#xff0c;只是针对ROS 2做了些修改调整&#xff09;&#xff0c;此处单拎出来方便查找。 在ROS 2中执行rosdep update时&#xff0c;报出如下错误&#xff1a; 其实原因…

elsint报错Delete `␍`eslintprettier/prettier

一&#xff0c;原因 这篇博客写得很清楚&#xff1a;解决VSCode Delete ␍eslint(prettier/prettier)错误_vscode 删除cr-CSDN博客 还有这篇文章&#xff0c;解决办法很详细&#xff1a;滑动验证页面 二&#xff0c;解决办法 根目录下新建.prettierrc.js文件 module.exports…

谷歌AI搜索革新:探索高级搜索服务背后的未来趋势

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

vulhub中Apache Solr RemoteStreaming 文件读取与SSRF漏洞复现

Apache Solr 是一个开源的搜索服务器。在Apache Solr未开启认证的情况下&#xff0c;攻击者可直接构造特定请求开启特定配置&#xff0c;并最终造成SSRF或任意文件读取。 访问http://your-ip:8983即可查看Apache Solr后台 1.访问http://your-ip:8983/solr/admin/cores?indexI…

一致性hash问题(负载均衡原理)

一致性哈希问题 简介 一致性Hash是一种特殊的Hash算法&#xff0c;由于其均衡性、持久性的映射特点&#xff0c;被广泛的应用于负载均衡领域&#xff0c;如nginx和memcached都采用了一致性Hash来作为集群负载均衡的方案。 本文将介绍一致性Hash的基本思路&#xff0c;并讨论其…

gpt国内怎么用?最新版本来了

claude 3 opus面世后&#xff0c;这几天已经有许多应用&#xff0c;而其精确以及从不偷懒&#xff08;截止到2024年3月11日还没有偷懒&#xff09;的个性&#xff0c;也使得我们可以用它来首次完成各种需要多轮对话的尝试。 今天我们想要进行的一项尝试就是—— 如何从一个不知…

正则表达式完全指南:语法、用法及JavaScript实例

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

认识 Redis 与 分布式

Redis 官网页面 Redis官网链接 Redis 的简介 Redis 是一个在内存中存储数据的中间件 一方面用于作为数据库&#xff0c;另一方面用于作为数据缓存&#xff0c;适用于分布式系统中 Redis 基于网络&#xff0c;进行进程间通信&#xff0c;把自己内存中的变量给别的进程&#xf…

Leetcode 300. 最长递增子序列

心路历程&#xff1a; 经典的子串/子序列的DP问题&#xff0c;这道题需要按照最后一个元素包含在子序列的角度去建模比较好做。 状态&#xff1a;以nums[i]为结尾的最长严格递增子序列的长度 动作候选集&#xff1a;每一个[0, i)之间满足比nums[i]小的元素 返回值&#xff1a…

C#/WPF Inno Setup打包程序

Inno Setup介绍 Inno Setup 是一个免费的 Windows 安装程序制作软件。第一次发表是在 1997 年&#xff0c;现在已经更新到Inno Setup 6了。Inno Setup是一个十分简单实用的打包小工具&#xff0c;可以按照我们自己的意愿设置功能&#xff0c;稳定性也很好。 官方网址&#xff1…

F - 创新型机器猫 高性能战斗机器人(遇到过的题,做个笔记)

我的代码&#xff1a; #include <iostream> #include <vector> using namespace std; int main() {string str;cin >> str;int dxy[][2] { {0,1},{1,0},{0,-1},{-1,0} }; //设置偏移量&#xff0c;按照右转顺序&#xff1a;北->东->南->西int now…

RabbitMQ3.7.8集群分区(脑裂现象)模拟及恢复处置全场景测试

测试环境准备: MQ服务器集群地址&#xff0c;版本号为3.7.8&#xff1a; 管理控制台地址:http://173.101.4.6:15672/#/queues 集群状态 rabbitmqctl cluster_status 集群操作相关命令: 创建一个RabbitMQ集群涉及到如下步骤&#xff1a; 安装RabbitMQ&#xff1a; 在每台要在集…

【opencv】教程代码 —photo

将彩色图像转换为去色图像&#xff08;灰度图像&#xff09;和 颜色增强图像 HDR 图像合成&#xff0c;并同时执行色调映射和曝光融合非真实感渲染&#xff08;NPR&#xff09;正常克隆、混合克隆、单色传递、局部颜色改变、局部照明改变和纹理平滑 1. decolorization将彩色图像…

微信小程序 电影院售票选座票务系统5w7l6

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言&#xff1a;pythonjavanode.jsphp均支持 运行软件…

竞赛 Yolov安全帽佩戴检测 危险区域进入检测 - 深度学习 opencv

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; Yolov安全帽佩戴检测 危险区域进入检测 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&am…