单片机学习(二)开发板LED灯的控制 |
您所在的位置:网站首页 › led跑马灯什么意思呀 › 单片机学习(二)开发板LED灯的控制 |
文章目录
开发板上LED灯相关的电路图点灯LED闪烁LED流水灯其他效果灯光二进制计数器进阶版流水灯
开发板上LED灯相关的电路图
这里我们尝试先点亮从左到右数第一个LED灯,从电路图上看我们只需要将P20引脚的输出置为0(即设为低电平)即可,代码如下: #include sbit led = P2^0; int main() { while (1) { led = 0; } }代码说明:首先我们需要引入单片机的头文件REG52.H,里面包含了许多寄存器的地址: 我们先设置一个延时函数deley(): void deley(u16 x) { while (x--) {} }即在这里面一直执行x–操作,按照这个型号单片机的执行速度,大概一个基本语句的执行为10μs,则若输入参数为x,则该函数可以延时 10 μ s ∗ x = x ∗ 1 0 − 5 s 10μs*x=x*10^{-5}s 10μs∗x=x∗10−5s,故若我们希望延时0.5s,我们需要填入50000。 代码(约1s闪烁一次): #include typedef unsigned int u16; typedef unsigned char u8; sbit led = P2^0; void deley(u16 x) { while (x--) {} } int main() { while (1) { led = 0; deley(50000); led = 1; deley(50000); } }运行结果: tips: 推荐一个GIF制作网站:https://www.tutieshi.com/video/,免费制作GIF,为良心网站点赞! LED流水灯 #include #include typedef unsigned int u16; typedef unsigned char u8; #define LED P2 void deley(u16 x) { while (x--) {} } void defaultDeley() { deley(50000); } int main() { u8 i = 0; LED = 0xfe; // 1111 1110 defaultDeley(); while (1) { for(i=0;i LED >>= 1; LED+=0x80; defaultDeley(); } // 1111 1110 } }这里我们直接操作P2寄存器,我们希望一开始第一个灯点亮,因此设置P2的值为0b1111 1110,即0xfe,然后我们可以进行移位操作使0位不断变化,即: 1111 1110 1111 1101 1111 1011 … 所以循环的代码应为: LED = 1; LED+=0x80;于是这样就完全实现了流水灯。 运行效果: 核心代码: int main() { u8 full = 0xff; u8 cnt; while (1) { cnt = -1; while (1) { // cnt: 0000 0000 -> 0000 0001 // LED: 1111 1111 -> 1111 1110 cnt +=1; LED = full - cnt; defaultDeley(); if (cnt == 0xff) { break; } } } }思路是让一个变量从0开始计数到0xff,LED对应的bit是0发光1熄灭的,这刚好是和我们的计数变量的二进制位模式相反,因此使用LED = 0xff - cnt进行取反,进而使LED显示与计数变量的变化对应起来。 运行效果: 那么我们仍然使用cnt作为计数变量,它将从0x00变化到0xff,然后我们再思考建立cnt到LED的映射关系: 看前面的变化规律: cnt: 0000 0000 -> 0000 0001 -> 0000 0010 LED: 1111 1111 -> 0111 1111 -> 1011 1111 可以发现,LED的值应为cnt的二进制位模式反转后的补码, 即LED = 0xff - reverse(cnt); 这样,我们很容易就可以写出控制代码: int main() { u8 full = 0xff; u8 cnt = 0; while (1) { cnt = -1; while (1) { // cnt: 0000 0000 -> 0000 0001 -> 0000 0010 // LED: 1111 1111 -> 0111 1111 -> 1011 1111 // LED = full - (reverse(cnt)); cnt +=1; LED = full - (reverse(cnt));; defaultDeley(); if (cnt == 0xff) { break; } } } }其中二进制位模式的翻转函数为(输入一个数,返回它二进制位模式反转值): u8 reverse(u8 x) { int cnt = 8; int res = 0; while (cnt--) { res = 1; } return res; }运行效果: 效果: 这样我们操作时可以看做是两个变化的东西,一个是左边的“1”,代表已经到达终点的1,另一个是右边不断左移的“1”,因此这两个部分可以放在两个变量中分别存储,这里设为leftPart和rightPart。 这样我们设计外层循环中leftPart每次的变化为:leftPart>>=1; leftPart+=0x80;,而内层循环中rightPart变化,为:rightPart u8 rightPart , res, i; u8 leftMoveTimes; u8 leftPart; start: LED = 0xff; leftPart = 0; leftMoveTimes = 7; rightPart = 0; res = leftPart | rightPart ; showAndDeley(res); while (1) { // 外循环 rightPart = 1; res = leftPart | rightPart ; showAndDeley(res); for(i = 0; i goto start; // 重新开始运行 } leftPart>>=1; leftPart+=0x80; leftMoveTimes--; } } |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |