单片机很好玩12,制作亮度随环境亮度变化的小灯

上一节,我们利用C语言编程单片机仿制了达文西的“古怪手电筒”,达成了“在有光的时候就会亮,在没有光的情况下绝对不会亮!”的目标。

其实在此基础上,C语言还能做些更好玩的东西。例如,制作一个小灯,这个小灯的亮度能够随着环境光线自我调整改变,如下图:

可以看出,当环境光线较强时,LED 小灯的亮度较暗,用塑料板遮住一部分光,使环境光线较暗时,LED 小灯则变亮了。或者稍作修改,也能实现相反的效果:环境光线越强,LED 小灯越亮,环境光线越弱,LED 小灯越暗。

设计能够自我调整亮度的 LED 小灯

和上一节一样,这里计划仍然使用C语言编程 51 单片机实现能够自我调整亮度的 LED 小灯,那么,51 单片机就是负责控制 LED 小灯的亮度的大脑。

使用 51 单片机控制 LED 小灯的亮度,可以参考第三节介绍的“呼吸灯”。

此外,单片机还需要能够感知环境光线的“眼睛”,光敏电阻就非常适合做单片机的眼睛,因为光敏电阻的阻值会随着照射在其上的光照强度改变而改变:

这样一来,我们可以将光敏电阻串入电路,再利用 51 单片机的 ADC 功能采集电阻两端的电压值。

因为光敏电阻的阻值随着环境光照改变,电阻两端的电压值也会随着环境光照改变,所以单片机就能够通过ADC模块采样值变化,获取环境光照情况。

让单片机“看到”环境光线

先来实现单片机的“眼睛”,即单片机的 ADC 模块。ADC的初始化是简单的,请看C语言代码如下:

void adc_init()
{
    P1ASF = 0x01;       
    ADC_RES = 0;
    ADC_CONTR = ADC_POWER|ADC_SPEEDLL;
    delay_about_100ms(2);
}

P1ASF = 0x01;表示将ADC的通道0打开,也即使用单片机的 P1.0 作为 ADC 输入口。获取一次 ADC 采样值的C语言代码如下:

// 获取 10 位 adc
WORD get_adc_res(BYTE ch)
{
    WORD res = 0;
    res = get_adc_h8bit(ch);
    res <<= 2;
    res |= ADC_LOW2;

    return res;
}

能够看出,因为 51 单片机是 8 位的单片机,所以若想采集 10 位的 ADC 值,需要两次组合。

这里的ADC相关代码比较简要,详细介绍可参考第 9 节文章。

使单片机具有控制 LED 小灯发光强度的能力

现在单片机能够“看到”环境光线强度了,再来看看单片机如何控制 LED 小灯的亮度。在第 3 节介绍“呼吸灯”时提到,可以控制一个周期内LED 小灯的亮灭持续时间长短,来实现控制 LED 小灯的亮度,核心 C 语言代码如下:

void delay(unsigned int n)
{
    unsigned int x;
    while(n--){
        x = 50;
        while(x--);
    }
}
void twinkle_once(unsigned char darkTime)
{
    P20 = 0;
    delay(100-darkTime);
    P20 = 1;
    delay(darkTime);
}


这里使用单片机的 P2.0 口控制 LED 小灯的发光周期。“呼吸灯”的C语言程序的设计思路是不断修改 darkTime 的值,使 LED 小灯亮暗逐渐缓慢变化。如果只是想实现控制 LED 小灯的亮度,可以将 twinkle_once() 函数放入 while 循环,通过修改传递给它的参数值来控制 LED 小灯的亮度。

C语言编程单片机,实现能够自我调整亮度的 LED 小灯

现在单片机既能“看到”环境光线,又能控制 LED 小灯的发光亮度了,现在将二者组合,使单片机能够根据环境光线的强度,自主改变 LED 小灯的发光强度。请看C语言代码如下:

void main()
{
    float vol;
    int dark_time = 0;
    adc_init();

    while(1){
        vol = 5.0*((float)get_adc_res(0))/1024.0;

        dark_time = (char)(110.0 *(vol/5.0));
        if(dark_time>100)
            dark_time = 100;
        twinkle_once(dark_time) ;
    }
}


以上C语言代码还是非常简单的,因为ADC采集的电压值 vol 介于 0~5V 之间,并且会随着环境光线的改变而改变。

dark_time 的最大值本应该是 100,但是 LED 小灯的发光强度与 dark_time 并不是线性的关系,这里为了获得更佳的效果,让最大值等于 110 了。

现在编译 C语言程序并烧写到单片机,会发现我们的设计成功了!

思考

本节介绍的能够自主根据环境光线强弱调整自己亮度的 LED 小灯,在某种程度上已经算是比较“智能”的小灯了,加上适当的调整,还能实现超过一定的亮度就关闭小灯,这就很有用了:黑夜里小灯较亮,能够照明环境,当天慢慢变亮时,灯就无需太亮,因为人们还可以借助自然光看清周围环境。当天大亮时,就不再需要小灯发光了,因此小灯就被自主关闭了。

通过这一节也能看出,传感器(如本节的光敏电阻)真的是“智能机器”的基础,离开传感器,中央处理器就很难感知环境参数的变化,也就很难做出自我调整了。

阅读更多:   单片机
添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif