c语言delay_单片机很好玩3,使用C语言编程,实现类似手机上“呼吸灯”的效果...

上一节为了解决单片机 IO 电流驱动能力不足,导致 LED 小灯亮度不高的问题,借助了三极管。单片机的 IO 通过三极管开关 LED 小灯的电流,最后的确明显让小灯的亮度更高了。

使用电路模拟软件

还记得上一节的这张图吗?

bda1dd2fe0e1f137de725bf034fb2939.png

这个是我手绘的原理图,看着很丑。我还记得一年前发现了一款比较轻量级的模拟软件,非常好用,所以今天又找出来了,推荐初学者使用。现在将上面的原理图画出:

b0071e66e42d4f67409a408ee37400eb.png

画好原理图后,就可以模拟了。

e6c0ed90cd9f48251b35da694aa6af2b.png

现在将开关拨向高电平,模拟单片机 IO 输出高电平,可以看出此时 LED 小灯的阳极电压只有 54.64 mV,这显然不能驱动LED小灯,所以小灯没有亮。现在再将开关拨向地:

75574576976bde78b9f9bfdef673a976.png

此时,LED 小灯的阳极电压达到 4.83V,所以小灯亮起来了。

虽然不能迷信模拟软件,但是它(DesignSoft Tina 9 – Industrial)的确是一个不错的参考,尤其对于和我一样的初学者朋友来说。

呼吸灯

现在既然 LED 小灯足够亮,那么就能做些更好玩的东西了。相信不少朋友使用过带“呼吸灯”的手机,指示灯慢慢的变暗,再慢慢的变亮,看起来就跟动物呼吸一样,所以称为“呼吸灯”。

2a05d0aaaa89cc9f8be08c36d95b26f3.png

那么,它是怎么实现的呢?我们的使用的普通 LED 小灯也能实现吗?当然是可以的,纯硬件电路就不说了,这里主要介绍下如何使用 C语言编程控制单片机实现“呼吸灯”。

C语言控制小灯亮度

“呼吸灯”其实就是小灯的亮度是逐渐变化的。也就是说,只要能够使用单片机控制我们的 LED 小灯的亮度,“呼吸灯”效果也就实现了。

上一节使用 C语言控制单片机 IO 交替输出高低电平,实现了 LED 小灯的闪烁效果,核心代码如下:

 while(1){ P20 = 0; delay(10); P20 = 1; delay(10); }

IO 输出的高低电平持续时间都是 10 个单位,一个完整的周期内,LED 小灯的亮灭时间都是相等的。那么,现在有下面这两种情况:

  • 一个周期内,LED 小灯亮的时间比灭的时间持续时间长。
  • 一个周期内,LED 小灯亮的时间比灭的时间持续时间短。

想象一下,哪种情况下的小灯更亮呢?答案是显而易见的,所以使用 C语言编程单片机控制小灯亮度的思路就有了,就是控制一个周期内,LED 小灯的亮灭持续时间长短而已。如此一来,假设一个亮灭周期为 100 个时间单位,就可以写出下面这个函数:

void twinkle_once(unsigned char darkTime){ P20 = 0; delay(100-darkTime); P20 = 1; delay(darkTime);}

现在在 main 函数里测试一下该函数,分两次,一次传入的参数为 10,一次为 90:

int main(){ while(1){ twinkle_once(10); // 分别测试 //twinkle_once(90); // 分别测试 } return 0;}

可以看出,twinkle_once() 函数的确会因为参数不同,驱动小灯的亮度也不同。

7dba00643c7ca9623e7565121d695ca8.png

实现“呼吸灯”

既然已经能够使用 C语言编程单片机控制 LED 小灯的亮度,实现“呼吸灯”就不难了。只要传递给 twinkle_once() 函数的参数由小变大,再有大变小就可以了。所以可以写出如下控制代码,请看:

int main(){ char darkTime = 0, dir = 1; unsigned int cnt = 0; while(1){ cnt ++; twinkle_once(darkTime); if(cnt == 4){ cnt = 0; if(dir) darkTime += 1; else darkTime -= 1; if(darkTime >= 100) dir = 0; if(darkTime <= 60) dir = 1; } }}

最终完整代码如下:

2086f5d0243908e87b7c48947d7a35c4.png

变量 cnt 可以控制“呼吸灯”的呼吸节奏,cnt 越小,呼吸速度越快,反之呼吸速度越快。变量 dir 决定小灯是逐渐变暗还是逐渐变亮。编译,烧写程序到单片机,还是按照上一节一样连线,最终可以得到如下效果:

74fa5bad4809077f486d4ec6e36693ca.gif

能够看出, twinkle_once() 函数控制 LED 小灯的亮度并不是线性的,所以呼吸灯的“呼吸”效果并不是特别好。因此,更理想的做法不应该只是简单加减 1 修改 darkTime ,而是按照 LED 小灯的响应曲线修改之。限于篇幅,这里就不写了。

欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。

关于呼吸灯C语言编程Options 1,0,0 // Target 'Target 1' Device (AT89C51) Vendor (Atmel) Cpu (IRAM(0-0x7F) IROM(0-0xFFF) CLOCK(24000000)) FlashUt () StupF ("LIB\STARTUP.A51" ("Standard 8051 Startup Code")) FlashDR () DevID (2976) Rgf (REGX51.H) Mem () C () A () RL () OH () DBC_IFX () DBC_CMS () DBC_AMS () DBC_LMS () UseEnv=0 EnvBin () EnvInc () EnvLib () EnvReg (Atmel\) OrgReg (Atmel\) TgStat=16 OutDir (.\) OutName (a9) GenApp=1 GenLib=0 GenHex=1 Debug=1 Browse=1 LstDir (.\) HexSel=0 MG32K=0 TGMORE=0 RunUsr 0 0 RunUsr 1 0 BrunUsr 0 0 BrunUsr 1 0 SVCSID MODEL5=0 RTOS5=0 ROMSZ5=2 DHOLD5=0 XHOLD5=0 T51FL=80 XT51FL=0 CBANKS5=0 XBANKS5=0 RCB51 { 0,0,0,0,0,0,0,1,0 } RXB51 { 0,0,0,0,0,0,0,0,0 } OCM51 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } OCR51 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } IRO51 { 1,0,0,0,0,0,16,0,0 } IRA51 { 0,0,0,0,0,128,0,0,0 } XRA51 { 0,0,0,0,0,0,0,0,0 } XRA512 { 0,0,0,0,0,0,0,0,0 } IROM512 { 0,0,0,0,0,0,0,0,0 } C51FL=21630224 C51VA=0 C51MSC () C51DEF () C51UDF () INCC5 () AX51FL=4 AX51MSC () AX51SET () AX51RST () INCA5 () PropFld { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } IncBld=1 AlwaysBuild=0 GenAsm=0 AsmAsm=0 PublicsOnly=0 StopCode=3 CustArgs () LibMods () BankNo=65535 LX51FL=292 LX51OVL () LX51MSC () LX51DWN () LX51LFI () LX51ASN () LX51RES () LX51CCL () LX51UCL () LX51CSC () LX51UCS () LX51COB () LX51XDB () LX51PDB () LX51BIB () LX51DAB () LX51IDB () LX51PRC () LX51STK () LX51COS () LX51XDS () LX51BIS () LX51DAS () LX51IDS () OPTDL (S8051.DLL)()(DP51.DLL)(-p51)(S8051.DLL)()(TP51.DLL)(-p51) OPTDBG 48125,-1,()()()()()()()()()() ()()()() FLASH1 { 0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0 } FLASH2 () FLASH3 () FLASH4 () EndOpt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值