内蒙古地区做推广网站,永康新站优化,wordpress杂志,百度网站管理员工具51单片机项目基础篇 LED流水灯1、硬件电路设计和原理分析2、软件设计2.1、利用循环和移位操作符功能实现#xff1a;LED流水灯2.2、利用利用封装好的库函数功能实现#xff1a;LED流水灯 3、编译结果4、结束语 LED流水灯
前言#xff1a; 前几篇学会了LED驱动原理#xff… 51单片机项目基础篇 LED流水灯1、硬件电路设计和原理分析2、软件设计2.1、利用循环和移位操作符功能实现LED流水灯2.2、利用利用封装好的库函数功能实现LED流水灯 3、编译结果4、结束语 LED流水灯
前言 前几篇学会了LED驱动原理并且成功点亮了一颗LED和实现了LED的闪烁那么这篇紧接着就来解锁LED的新功能LED流水灯。当然这里前提是基于肉眼余晖可见光达成的效果。
1、硬件电路设计和原理分析
开发板上 LED 模块电路原理图如下图所示 看上图中 LED 采用共阳接法D1-D8 连接到单片机的 P20-P27 口即所有LED 阳极管脚接电源 VCC阴极管脚通过一个 470 欧的限流电阻接到 P2 口上。 原理分析 根据前面篇章 点亮一颗LED 的介绍我们知道要让 LED 发光即对应的阴极管脚应该为低电平若为高电平则熄灭。 根据前面篇章 LED闪烁 的介绍我们知道要让 LED 闪烁主要引用延时函数。
所以如果要想 51 单片机控制 LED实现流水灯的效果就必须通过单片机管脚在 P2 口上反复循环的调用寄存器控制对应D1~D8引脚的高低电平当第一颗LED点亮则其它LED处于熄灭状态当第二颗LED点亮时其它LED处于熄灭状态同理其余的LED都是这个逻辑其次MCU执行程序语句都会有一定的时间为了达到人肉眼的余晖效应因此只需编写一个循环函数让CPU 不干其它事专门在那循环运行即可实现延时功能。
2、软件设计
程序这边主要介绍两种思路的写法 (1)、利用循环和移位操作符实现反复改写对应LED端口高低电平的改写。实验效果单向流水灯 (2)、利用封装好的库函数左移_crol_、右移_cror_函数实现流水灯效果。实验效果双向流水灯
2.1、利用循环和移位操作符功能实现LED流水灯
//1.利用循环和移位操作符
/**/
#include reg52.h#define LED_PORT P2//使用宏定义--- P2端口
typedef unsigned int u16;void delay_10us(u16 ten_us)
{while(ten_us--);
}void main()
{int i 0;//LED_PORT 0xfe;//LED_PORT 0x01;while(1){for(i0;i8;i){LED_PORT ~(0x01i);//i0时D1灯亮,i依次点亮//移位后自动补0当7次移位后高位的1被移走低位就自动补0//导致同时会亮两个灯那么就采取取反操作符。以移动1然后取反来解决移位补0的这个问题delay_10us(50000);}}
}解释说明 前面章节已经介绍了的内容这里的 delay_10us延时函数 和 typedef 类型重命名就一笔带过了。具体参考前面篇章 点亮一颗LED 的介绍 然后这里简单说一下#define关键字是C语言中的一个宏定义预处理指令(“#”开头的均为预处理命令)命令它用来将一个标识符定义为一个字符串语法格式如#define LED_PORT P2该LED_PORT标识符被称为宏名被定义的字符串P2称为替换文本。 大概描述一下主要的作用就是在遇见大量重复又需要经常改变的参数常常用宏定义一个新的字符串替换标识符从而实现便捷的更换程序参数。 最后主函数main进入 main 函数后首先定义一个变量 i然后进入 while 循环由于要实现 8个 LED 从 D1-D8 循环点亮因此可以使用 for 循环语句循环 8 次每循环一次点亮的小灯向右移动一个而 D1-D8 是连接到 P2.0-P2.7 的因此输出的低电平要左移一位因此可以使用 LED_PORT~(0x01i);语句实现。 主要解释一下~(0X01i) 表示 i 循环 1 次则0x01 中的 1 就移动多少位。另外因为 1高电平不会让 LED 点亮需要取反后变为低电平 0 才能点亮所以最后的结果需要取反后给 LED_PORT 口并且每次循环都要延时一段时间这样才能分辨出来 LED 在流水形式显示。 如果不取反这里以二进制表示就是 0000 0001 1 得到 0000 0010 左移1位后最低位自动补0当7次移位后1000 0000第八次最高位的1被移走最低位就自动补0则为0000 0000又根据开发板的LED硬件原理图LED 采用共阳接法给0为亮所以最后的移位后的值需要取反使得对应的灯亮其它灯灭。
2.2、利用利用封装好的库函数功能实现LED流水灯
//2.利用_crol_库函数
/**/
#include reg52.h
#include intrins.h
//当调用_cror_右移库函数和_crol_左移库函数时需调用头文件intrins.h
//注意库函数的移位不会自动补0是最高位向最低位进行移位的
//了解函数的参数extern unsigned char _crol_ (unsigned char, unsigned char);
//第一个参数是移动的值第二个参数是移动的位数
#define LED_PORT P2typedef unsigned int u16;
typedef unsigned char u8;void delay_10us(u16 ten_us)
{while(ten_us--);
}void main()
{u8 i 0;LED_PORT 0xfe;//1111 1110delay_10us(50000);//LED_PORT ~0x01;//等价while(1){for(i0;i7;i)//当我们给LED_PORT赋初值0xfe时只需要循环7次即可{LED_PORT _crol_(LED_PORT,1);delay_10us(50000);}//右移同理for(i0;i7;i)//当我们给LED_PORT赋初值0xfe时只需要循环7次即可{LED_PORT _cror_(LED_PORT,1);delay_10us(50000);}}解释说明 以库函数的写法就相对更简单了因为只需要会用就行直接调用已经封装好的左移_crol_、右移_cror_函数然后查阅对应的用法和参数以及对应的头文件即可。 以左移_crol_函数为例其主要作用就是 实现的移位功能就相当于一个队列内循环移动如果是左移那么最高位就被移到最低位了次高位变为最高位依次类推的循环排列。 最后主函数main进入 main 函数后首先定义一个变量 iLED_PORT~0x01因为 LED 是低电平 点亮所以 0X01 取反后的结果是 0XFE对应二进制数为 1111 1110即最低位为 0因此最开始的 D1 指示灯会点亮然后进入 while 循环使用 for 循环_crol_和_cror_移位函数实现 LED 左右流水显示。
注意到的是此处每个 for 循环只有 7 次为什么不是 8 次呢这是因为在进入 main 开始就已经将 LED_PORT 端口设置了一次状态即让 D1 点亮并且我们是想让 LED 从左至右依次点亮然后继续又从右至左依次点亮这样形成左右流水效果。 假如将循环次数改为 8 次我们列举下第一个 for 循环的LED_PORT 端口状态值如下所示 初始状态LED_PORT1111 1110 i0LED_PORT1111 1101 i1LED_PORT1111 1011 i2LED_PORT1111 0111 i3LED_PORT1110 1111 i4LED_PORT1101 1111 i5LED_PORT1011 1111 i6LED_PORT0111 1111 i7LED_PORT1111 1110 可以很直观的查看到当i 7时再次回到了初始状态的显示可这里我们是想实现的是LED从左流动过来又从右流动回去的流水灯效果。所以i 6只需要for循环7次即可。
3、编译结果
至此两个程序就编写完成我们编译一下如下图所示
从上图编译信息可以看出我们的代码占用FLASH 大小为code 65 字节所用的 SRAM 大小为data 9 个字节9.0xdata指是扩展的外部存储XSRAM所占的大小并没有使用XSRAM所以为0。 从上图编译信息可以看出我们的代码占用FLASH 大小为code 98 字节所用的 SRAM 大小为data 9 个字节9.0xdata指是扩展的外部存储XSRAM所占的大小并没有使用XSRAM所以为0。
硬件实验效果如图所示 C51基础实验 LED流水灯实验效果展示1 C51基础实验 LED流水灯实验效果展示2 4、结束语
写这篇文章记录作为自己学习的笔记笔者水平有限希望有错误的地方还请多多指教各抒己见交流学习同时希望笔者的内容有帮助到你。如果有所帮助还请点点赞表示支持哦。最后感谢各位的阅读不喜勿喷。