ad6怎么画电阻_光敏电阻传感器的使用

2021年9月14日 6点热度 0条评论 来源: weixin_39965283

来源:百问网_嵌入式Linux wiki_jz2440 新1期视频维基教程 (视频文字版)

作者:韦东山

本文字数:2552,阅读时长:3分钟

这节课我们开始讲的传感器,有光敏电阻、DH11温湿度传感器、DS18B20温度传感器、HS0038红外接收器。

首先介绍光敏电阻传感器。

光敏电阻有一个特点,就是它的阻值随光照强度变化而变化,

看一下它的原理图,R5是一个普通电阻,LAS1是光敏电阻,它们串联组成一个分压电路,

LAS1阻值变化,将会导致中间RES_AO测得的电压发生变化。

这个电路图有点绕,画一个示意图如下:

使用ADC测量A点的电压,可以得知LAS1的变化情况,这里的测量是一个模拟信号。

现在假如需要这个光敏系统在光照大于/小于某个值时,发出中断,怎么办呢?

这里就需要再加一个比较的电路,B处的电压是可调电阻得到的电压,可以通过调节电阻进行变化。A、B两个电压最后接在一个比较器的“正负端”,当A>B时,输出1,反之输出0。

通过调节可调电阻,可以实现对比较阈值的控制。

现在这个电路就即可得到模拟信号和数字信号。

现在就可以开始写程序了,复制前面024的代码为025_sensors,这是这一章的第一个项目,再创建个001_photoresistor文件夹,将代码都放进去。

再创建一个sensors文件夹用来放本课的所有传感器代码,然后再创建photoresistor文件夹放本节课代码,再在里面创建photoresistor.c。

在代码里面,我们要做两件事:

1.启动ADC,读出AIN1电压值;

2.注册中断,当光线强度超过或小于某个阈值时,产生中断;

打开工程里的adc代码,原来的adc_init,只初始化了adc0,现在我们要用AIN1,修改下代码,传入个参数就能初始化对应的AIN:

void adc_init(int channel){/* [15] : ECFLG,  1 = End of A/D conversion * [14] : PRSCEN, 1 = A/D converter prescaler enable * [13:6]: PRSCVL, adc clk = PCLK / (PRSCVL + 1) * [5:3] : SEL_MUX, 000 = AIN 0 * [2]   : STDBM * [0]   : 1 = A/D conversion starts and this bit is cleared after the startup. */ADCCON = (1<<14) | (49<<6) | (channel<<3);ADCDLY = 0xff;}

后面的adc_read_ain0只能读取AIN0的数据,现在修改一下,传入个通道参数,就能读取对应通道的ADC值:

int adc_read(int channel){adc_init(channel);/* 启动ADC */ADCCON |= (1<<0);while (!(ADCCON & (1<<15)));  /* 等待ADC结束 */return ADCDAT0 & 0x3ff;}

修改了这两个函数,原来的adc_test函数里调用的adc读取函数也要对应进行修改。

参考这个adc_test,编写photoresistor_test函数。

需要修改的内容并不多,首先是修改adc_read参数,将通道0改为通道1。

然后我们想同时再把AIN0上的滑动电阻对应的电压也读出来,因此再做一次ADC0读取的操作。

void photoresistor_test(void){int val, val0;double vol, vol0;int m, m0; /* 整数部分 */int n, n0; /* 小数部分 *///adc_init();while (1){val = adc_read(1);vol = (double)val/1023*3.3;   /* 1023----3.3v */m = (int)vol;/* 3.01, m = 3 */vol = vol - m;/* 小数部分: 0.01 */n = vol * 1000;  /* 10 */val0 = adc_read(0);vol0 = (double)val0/1023*3.3;   /* 1023----3.3v */m0 = (int)vol0;/* 3.01, m = 3 */vol0 = vol0 - m0;/* 小数部分: 0.01 */n0 = vol0 * 1000;  /* 10 *//* 在串口上打印 */printf("photoresistor vol: %d.%03dv, compare to threshold %d.%03dv", m, n, m0, n0);  /* 3.010v *//* 在LCD上打印 *///fb_print_string();}

以上就完成了我们的第一个目标。

现在开始做第二个目标,注册中断放在interrupt.c里实现。

硬件上RES_DO是EINT15。我们可以仿照之前的按键中断来编写本次的中断。

先分析一下中断,如图:

GPG7作为中断引脚,它会先经过外部中断EINTMASK寄存器,才能进入到中断控制器。

所以,需要做以下操作:

  • ①首先初始化:

a.GPG7配置为中断引脚;

b.设置中端触发方式:双边沿触发;

c.设置EINTMASK使能中断;

  • ②中断处理:

a.分辨:读EINTPEND;

b.读GPG7;

在原来的key_eint_init函数里配置GPG7为中断引脚:

/* 配置GPG7为中断引脚, 用于光敏电阻 */GPGCON &= ~((3<<14));GPGCON |= ((2<<14));

然后设置中端触发方式:双边沿触发

/* 设置中断触发方式: 双边沿触发 */EXTINT0 |= (7<<0) | (7<<8);     /* S2,S3 */EXTINT1 |= (7<<12);             /* S4 */EXTINT2 |= (7<<12);             /* S5 */

最后再使能中断:

/* 使能中断GPG7/EINT15, 用于光敏电阻 */EINTMASK &= ~((1<<15));

修改key_eint_irq中断处理函数,先判断是哪个中断产生,再读取电平,打印。

else if (val & (1<<15)) /* eint15, 用于光敏电阻 */{if (val2 & (1<<7)){printf("photoresistor dark!");}else{printf("photoresistor light!");}}

至此,代码就写完了,最后还要修改对应的Makefile和主函数。

「新品首发」STM32MP157开发板火爆预售!首批仅300套

    原文作者:weixin_39965283
    原文地址: https://blog.csdn.net/weixin_39965283/article/details/110205097
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。