#前言
本文主要讲解了如何用OLED屏幕来显示模拟量光敏检测到的模拟值
关于如何使用OLED屏幕可参考基于STC8G2K64S4单片机通过I2C硬件控制OLED屏幕
终于的终于不会被光敏阈值和场地光线因素问题困扰了,前两次都是因为这个然后连发车失败直接原地裂开。使用OLED显示器来显示模拟值更直观地观察参数,然后修改程序中的阈值
硬件方面
主控板和OLED继续使用上次的,这里就不多介绍,不懂的可以去看我上面说的文章
这里用到了模拟量光敏,某宝很多。跟数字量主要区别就是会少小一点,没有可调电阻,价格也会相对低一点
模拟量光敏顾名思义不是输出数字量,也就是说不是单纯的0和1,而是是输出模拟值。其实数字量光敏是在模拟量原理上加上一个可调变阻器用来确定一个值作为分界线,然后把模拟值与分界线来比较,大于分界线输出1;小于分界线的输出0
先说颜色,当然正常的黑色白色肯定没有大问题,出现淡黄色,红色这种,很可能会判定成白色,这样就会导致循迹出现问题。虽然说有可调电阻,可以调分界线的高低,但是你直接是看不到的,或许通过万用表或者其他方式能检测到,但是大大增加时间
再者是场地问题,现场的环境光线基本是和自己在学校里的调试的环境光线是不一样的,这也会导致黑色或者白色的模拟值越过分界线,全部判定成一种颜色,这种情况要是出现在赛前准备的里三分钟里就直接爆炸
所以使用模拟量光敏能够解决上述所有问题,循迹部基本不会出问题
软件方面
在程序里不能直接看到模拟值,需要通过ad转换成模拟值。
这里注意模拟量光敏OUT的引脚一定要接单片机有adc功能的引脚,不是普通io口都有的。这个也是根据芯片来定的
原理是模拟量光敏检测的是电压,然后单片机引脚需要把这个电压转换成一个模拟值,公式如下
a //模拟值
v //测到的电压
vrsf //参考电压
256 //8位精准度
a=v/vref*256
vrsf一般在芯片手册中都会有说明,不同芯片不一样。在STC8G2K64S4里是和vcc接在一起,所以就是5V了
精准度就很好理解,位数越大越精准,一般还有9位和10位可以选
接下来就是配合OLED来显示了模拟值了,也是运用了逐飞科技的库函数
初始化adc:
adc_init(ADC_P06,ADC_SYSclk_DIV_2); //选择P06为ADC功能,ADC时钟频率为SYSclk/2
模拟值的数字显示:
void gewei() //个位显示
{
int yushu;
yushu=q%10;
if(yushu == 1)
one(2,47);
if(yushu == 2)
two(2,47);
if(yushu == 3)
three(2,47);
if(yushu == 4)
four(2,47);
if(yushu == 5)
five(2,47);
if(yushu == 6)
six(2,47);
if(yushu == 7)
seven(2,47);
if(yushu == 8)
eight(2,47);
if(yushu == 9)
nine(2,47);
if(yushu == 0)
zero(2,47);
}
void shiwei() //十位显示
{
int yushu;
yushu=q/10%10;
if(yushu == 1)
one(2,40);
if(yushu == 2)
two(2,40);
if(yushu == 3)
three(2,40);
if(yushu == 4)
four(2,40);
if(yushu == 5)
five(2,40);
if(yushu == 6)
six(2,40);
if(yushu == 7)
seven(2,40);
if(yushu == 8)
eight(2,40);
if(yushu == 9)
nine(2,40);
if(yushu == 0)
zero(2,40);
}
void baiwei() //百位显示
{
int yushu;
yushu=q/100%10;
if(yushu == 1)
one(2,33);
if(yushu == 2)
two(2,33);
if(yushu == 3)
three(2,33);
if(yushu == 4)
four(2,33);
if(yushu == 5)
five(2,33);
if(yushu == 6)
six(2,33);
if(yushu == 7)
seven(2,33);
if(yushu == 8)
eight(2,33);
if(yushu == 9)
nine(2,33);
if(yushu == 0)
zero(2,33);
}
主代码:
#include "headfile.h"
int q;
void main()
{
DisableGlobalIRQ(); //关闭总中断
board_init(); //初始化内部寄存器,勿删除此句代码。
init_all(); //初始化所有函数
EnableGlobalIRQ(); //开启总中断
pingmu_init(); //屏幕初始化
xianshi(); //打开屏幕显示
while(1)
{
q = adc_once(ADC_P06, ADC_10BIT); //采集一次ADC,精度10位
gewei(); //显示个位
shiwei(); //显示十位
baiwei(); //显示百位
pca_delay_ms(10);
}
}
这里关于OLED的代码请参考基于STC8G2K64S4单片机通过I2C硬件控制OLED屏幕
效果展示:
#总结
做出这个东西我相信在之后的竞赛里,光敏循迹这一块就会很稳定,也不会因为现场时间不够而慌乱。虽然说不是一个很厉害的东西,但可能很好用。在代码方面还有很多需要优化的子函数,这些东西弄好了,在之后的使用过程中会更加便捷
本人小白,有问题交流讨论,虚心受教