51单片机编程开发(四)之完转LED 点灯是不是太简单了 上一篇的编程内容中我们点亮了LED,肯定有朋友会说点灯是不是太简单了,文章后方留言还有朋友催我更新呢,哈哈哈,我当然也想快点更新,只是各位朋友都是来自祖国大地的五湖四海,基础肯定不一样,所以为了照顾一些基础稍微差一点的朋友必须要把问题点讲得明白一些,把基础原理解释清楚,这有助于他们在初学阶段能够形成良好的编程思维,所以前期更新速度会慢一些。到后期我倒是希望大家都能够跟得上哈。但是大家如果有需求照样可以大胆在后台留言的,我会在教程计划内尽力满足各位需求,如果不好意思留言,也可以选择后台私信。但是话说回来迟早要出社会混的,还在乎啥面子?你现在在乎的那点面子迟早会被社会“收拾干净”哈,所以有啥不好意思的呢? 因为本人自带的一点“逗比”气质,有时写文章可能会戳到你的心窝子,到时千万别较真,一定要记得我肯定是在开玩笑,提醒我再戳狠一点,我真的会戳更狠哟。 另外,我今天也想了一个方案,希望在这里能够让不同基础的朋友快速提高编程能力。在今后的推送消息中我会添加一篇文章,文章内容可能涉及编程题目,经典程序分享,或者一些编程经验,并且难度也会由低到高循序渐进,这样以后新来的朋友也可以快速入门。当然内容中所涉及到的编程语言暂时限定为C语言。后面再视情况添加其他语言,例如C++,JAVA,Python,JS甚至dos,Shell脚本等等,还希望大家可以一起来玩转。 现在先回到最初的LED话题,你是不是想说,就这?这点知识内容还不够下饭吃呢?那接下来我们再玩点不一样的。 延时的概念 前面的程序中我们只是点一下灯,熄一下灯,或者点亮另几个灯,再熄灭,有这编程的功夫还不如装个开关吧。你还想咋地?“宝宝想看那种五颜六色还能一闪一闪亮晶晶的”。如果你的女朋友(或男朋友)看到你学单片机只会点灯时这么对你说,你该咋办?毫无疑问,咱无论如何也要满足她(他)呀,还不止只给她看一闪一闪亮晶晶呢,你应该要给她看星星,看月亮,看整个宇宙的。毕竟现在这社会竞争这么大,你不给她,另一个朋友能给她,到时你该怎么办?都到谈恋爱这份上了,为了这点小事难道你要“善罢甘休”,真不想以后交换戒指的是你和她? 想清楚了吧,为了未来的那一大幕,我们现在是不是要先来研究研究LED怎么一闪一闪这一小步呢? 我们要让单片机控制的LED一闪一闪要怎么做呢,是不是让它亮一会再灭一会?那要怎么让它亮了再灭呢?难道写一个点亮程序,再写一个熄灭程序不停交替下载这两程序?要是这样,你女朋友早跟楼下小王跑了。 前面的内容中我们说了数字芯片大多都是需要时序来控制的吧,单片机是数字芯片的集合体,它的时钟源就是我们上节课说的晶振电路,晶振电路产生的时钟信号输入到其内部,然后其内部电路就根据这个信号按照一定的规律进行运行,如果给到的程序有什么功能它内部就随着这个时钟一步一步实现我们的功能,如果我们给了一个”空白”程序(空白不是什么都没有,用无意义来形容可能更贴切,就是不处理正经事单纯消耗系统时钟的命令,实现这一点的原理是因为单片机中任何命令执行都会消耗时间,类比人休息但时间也在流失道理一样),那它内部在这一段时钟信号内就保持原样什么都不变动。就像我们人一样,当我们在走路时,大脑控制我们的神经,带动肌肉往复运动,我们休息时就让肌肉放松下来。那我们要怎么控制芯片让它暂停一下呢,看完上面内容是不是就有答案了?给它一段“空白”命令,不行就2段,或者N段。 那在程序中要怎么实现让单片机执行一段空白命令呢? 前面接收C语言基础时我们是不是讲到了循环语句?我们在循环语句中不执行任何功能,这样就可以解决这个问题了吧。一个“暂停”功能的程序在脑海中应该有了吧。这种情况我们一般称为延时,和暂停是一个意思,但不这不是意味着单片机就真的是停下来的吧,就像我们休息的时候心跳也要照样跳动一样,“暂停”都是假象。 下面来看一下我们平时常用的延时代码: while(n<100) { n–; } 我们也可以改写成for循环的方式吧。 for(n=0;n<100;n++) { ; } 当然,以上程序还可以进行嵌套,如果你需要设置的延时时间很久的话。另外,熟练编程之后我们也可以把大括号对{}省略不写,至于为什么?自己思考一下。 这里我们在“暂停”时用一个变量n来控制“空白”命令的次数,如果短了就把n加大,如果长了就减小。但到底多少合适呢,也就是我们要怎样实现可控的延时时间呢,这里我们需要来了解几个关于51单片机的新概念,即时钟周期,机器周期,指令周期。 时钟周期就是指晶振振荡的周期,它是晶振频率的倒数,我们仿真电路中使用的是12MHz的晶振那它就是(1/12M)秒。 机器周期在51单片机中机器周期就是12个时钟周期,即(1/1M)秒,也就是1微秒(us)。 指令周期就是单片机执行一条指令的时间,它由若干个机器周期组成,在单片机中一些简单指令是1个机器周期,一部分复杂指令需要2个或多个机器周期。 当然我们项目开发时这些内容需要参考芯片数据手册,因为这不是固定的定义,现在很多增强型51单片机的时钟都不是这样的了,其他更高级的芯片就不用说了。 那我们到底要怎么确定我们延时程序中的n,能延时多久呢?我们可以通过程序的调试功能进行仿真确定(毕竟是仿真与实际会有一些出入)。最死板的办法是我们可以把程序下载到单片机中进行测试分析呀,用示波器测量单片机引脚电平变化周期就不出来了,然后大概记住一些典型时间,如0.1s,0.5s,1s等延时n的值,以后直接使用也可以。但我们肯定还有更简单又准确的延时办法,因为设计到定时器的使用,所以今天就先不讲解,后面学习定时器是在做具体介绍。 写了这么多内容,终于把基础写完了,老司机们是不是早就迫不及待的发车了?那我们先上车开起来吧 闪灯程序 看了以上原理,现在我们想来实现让一个灯闪起来吧。我们来看看程序内容,跟着注释看一遍是不是就很明了了。 #include <reg52.h> //这是52单片机的头文件 #include <intrins.h> //这也是编译器的一个头文件后面会用到 typedef unsigned char u8; //typedef 是别名关键字 typedef unsigned int u16; void main() { u8 i,j; //定义变量 P1 = 0xfe;//点亮第一个灯 for(i=0;i<200;i++) //第一段延时 { for(j=0;j<200;j++) { ; } } P1 = 0xff;//熄灭第一个灯 for(i=0;i<200;i++)//第二段延时 { for(j=0;j<200;j++) { ; } } } 这个代码里我新引入一个头文件#include <intrins.h>,它也是编译软件自带的一个头文件,里面包含对寄存器的循环操作接下来的程序中我们会使用到。 typedef这个关键字就是取别名的意思,就是把一长串名称给一个简短的名字,编程时可以巧用它来简化某些程序。 使用上一节内容中对P1端口整体赋值的方式进行点灯。 点完灯后延时一会,接下来讲灯熄灭,熄灭后再进行一个延时,这样就实现了我们的闪灯效果。 创建函数,制作配件 如果我们把延时程序打包成一个函数以后就可以重复使用了,这是不是爽歪歪? 再来看看修改好的代码: #include <reg52.h> //这是52单片机的头文件 #include <intrins.h> //这也是编译器的一个头文件 typedef unsigned char u8; typedef unsigned int u16; //void delay();//声明函数 void delay(u8 ms); void main() { P1 = 0xfe;//将LED1点亮 delay(50);//调用函数 P1 = 0xff; //将LED1关闭 delay(50); } void delay(u8 ms) //定义函数 { u8 i,j;//定义这个延时函数中的i,j变量 for(i=0;i<ms;i++) { for(j=0;j<200;j++) { ; } } } 还是同样的意思,这么一对比是不是可以看出程序有层次感就出来了,代码瞬间就好看了很多吧。当然把延时函数打包成void delay()还是void delay(u8 ms)就看个人了,要想使用更灵活那当然是后者咯。 循环流水灯 只是知道闪灯未免太单调,也打动不了人心吧,接下来我们再整点复杂的,使用循环位移操作实现流水灯变化,现在先来看看程序。 #include <reg52.h> #include <intrins.h> typedef unsigned char u8; typedef unsigned int u16; void delay(u8 ms); void main() { u8 rol = 0xfe; u8 i; for(i=0;i<8;i++) { //先将P1端口初始化,先设定P1.0点亮 P1 = rol; //延时一会 delay(100); //将变量移位 rol = _cror_(rol,1); //移位完成在下一个循环,rol的值将重新赋值给P1寄存器 } } void delay(u8 ms) //定义函数 { u8 i,j;//定义这个延时函数中的i,j变量 for(i=0;i<ms;i++) { for(j=0;j<200;j++) { ; } } } 这个程序对着视频仿真效果一起看是不是还好理解呢? _cror_函数相当于一个环形位移 向右移动一位就变成 0,其高位是将末位补充过来。 如果换成_iror_结果就不一样了。 _iror_是单向位移, 向右移动一位变成0,其高位是补0。 当然左移就和右移刚好相反了。 _crol_函数是环形移动, 移动一位就变成 ,其末尾是将最高位补充过来。 _irol_中 向左移动一位变成,其末尾是补0。 这两种循环反方式在编程时各有用途,所以要区分得开来,如果觉得不好掌握就多编程尝试一下。 视频中程序注释部分写错了,_cror_和_iror_的功能写成_crol_和_irol_的功能了,大家留意一下! 小结 相信看完这几个例子有朋友应该知道可以尝试做些什么东西出来了吧,比如DIY一个电子爱心,或者光立方方,广州塔,不妨自己动手试试,如果有遇到问题也可以在这里交流。 当然要打动心仪对象的芳心,只有上面这点技能肯定是还不够,楼下小王都会做跳动的旋律了,你这都没竞争力,要多加强练级呀,争取有朝一日超过小王,摘得星星月亮回,也抱得美人归。后面的内容我们再接着介绍更深层的一些知识,敬请期待,下期再见。
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/43624.html