上一节,我们利用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 小灯,在某种程度上已经算是比较“智能”的小灯了,加上适当的调整,还能实现超过一定的亮度就关闭小灯,这就很有用了:黑夜里小灯较亮,能够照明环境,当天慢慢变亮时,灯就无需太亮,因为人们还可以借助自然光看清周围环境。当天大亮时,就不再需要小灯发光了,因此小灯就被自主关闭了。
通过这一节也能看出,传感器(如本节的光敏电阻)真的是“智能机器”的基础,离开传感器,中央处理器就很难感知环境参数的变化,也就很难做出自我调整了。