![045f0d2ce544aae289d51f1cbd9068e4.png](https://i-blog.csdnimg.cn/blog_migrate/85b66f1ca4064efe4f6c9d248e8e26ce.jpeg)
大家好,我是兔子。
是一个嵌入式软硬件工程师。
正在从单片机开发转岗Linux开发。
由于CPU是数字信号,只能分辨0和1(电压即为0V和3.3V)。
如果电压为0~3.3V之间的模拟信号,则CPU只能使用ADC功能来采集。
模拟量采集用处很多,比如PT铂电阻丝来测温度,就是根据不同温度导致电阻阻值变化,测量模拟量并计算电阻阻值,可以反推出温度。
比如变送器,也是通过电压的不同来传输信号。这就用到了模拟量采集了。
这次,我们使用芯片的ADC功能,通过转动电位器来改变电阻,采集不同的电压。
1.操作大纲
1)使用周立功官方提供的ADC驱动,编译驱动并加载驱动。
2)查看原理图,了解电路接线方式。
3)调整周立功官方提供的ADC测试程序,并编译。
4)开发板运行ADC测试程序,观看效果。
2.编译ADC驱动
将周立功官方提供的ADC驱动程序,拷贝到虚拟机里。
该驱动我们不需要更改,仅需调整Makefile文件后,直接编译使用。
![b525970c80ea4176168029cb2b5b0605.png](https://i-blog.csdnimg.cn/blog_migrate/d22f82499bf70956e8f4c81df453834f.jpeg)
可以看到,Makefile文件,和之前一样,调整内核地址即可。
(因为编译驱动需要内核文件的支持,兔子我的内核文件夹是放在我的虚拟机/home/book/路径里,内核文件夹名称为/linux-2.6.35.3)
进入终端,进入ADC驱动文件夹里,使用make编译驱动。
可以看到,无错误无警告,表示编译通过。
![bca6047884988e4ec7446e4b549f902f.png](https://i-blog.csdnimg.cn/blog_migrate/54390d7b7ebcd49436f4c0507bbb9eea.jpeg)
可以看到,生成了lradc.ko,表示ADC驱动文件生成。
3.原理图
![f215e8235528e0a17fd198c14f406563.png](https://i-blog.csdnimg.cn/blog_migrate/0c01bc9d2eb5ac9ea1de7dfb9fdb7ba2.jpeg)
我们这次操作的目的,是旋转扩展板上的电位器RW1,使用螺丝刀改变电位器的阻值,并使用CPU的ADC功能,采集电位器两侧的电压值。
![69ba19365d527dcfbbbbdcf2cddd185e.png](https://i-blog.csdnimg.cn/blog_migrate/55f6aa8f7328e7b201ae6ec1e5d5836a.jpeg)
这个是该电位器的原理图。
和兔子我一起分析一下它的功能。
首先,电位器是一个10K阻值的可调电阻。它和一个固定阻值为8.2K的电阻串在一起。再整个供电3.3V。
电位器的范围即0~10K。
1)如果电位器滑动到0欧姆,则对地为10K。
该电路的ADC检测的电压,就为3.3V的8.2K和10K之间的分压。
即3.3 *(10/18.2) = 1.813V
2)如果电位器滑动到10K,则对地为0欧姆。
该电路的ADC检测到的电压,就直接为地。即0V。
所以,这个电路,能检测到的电压范围为0~1.8V。
再来看看,电位器的ADC采集,是接到了CPU的哪里。
扩展板上,电气网络名称为ADC_IN0。
![c426048d8e5cbb574ebe5ea609188477.png](https://i-blog.csdnimg.cn/blog_migrate/a32b20e12adca07ddbc8cd6c0af09149.jpeg)
可以看到,电气名称ADC_IN0,接到了电气名称ADC0上。
和兔子一起再搜索ADC0,看到它还和哪些相接。
![5ceb5dfd123df8e5da3f200fe92f2dc6.png](https://i-blog.csdnimg.cn/blog_migrate/ec65731ad90d5990177960c752760a2e.jpeg)
发现ADC0是直接接到了和CPU主控板相接的座子上。
为IDC-B的座子的第20脚。
![0ee175a08e986fab228a610f09defade.png](https://i-blog.csdnimg.cn/blog_migrate/8ac402bddb006d5d300d7384719a8878.jpeg)
我们再看看,i.MX280的CPU主控板,这个管脚的电气网络名称。
![0527dd6da7d7545f81108e1e7d8393c5.png](https://i-blog.csdnimg.cn/blog_migrate/237ab7e7f7f6aa2ad97b49e99aabdfc7.jpeg)
可以看到,在i.MX280主控板上,这个管脚为ADC5。
(i.MX283,287板卡同理,引脚不一定一样)
则原理图分析完毕。
4.调整ADC程序
/*********************************************************************************
** ADC参考电压为1.85V,外部输入电压不能超过3.7V,内部带有一个模拟除2电路。
*********************************************************************************/
#include<stdio.h> /* using printf() */
#include<stdlib.h> /* using sleep() */
#include<fcntl.h> /* using file operation */
#include<sys/ioctl.h> /* using ioctl() */
#include "lradc.h"
int main(int argc, char *argv[])
{
int fd;
int iRes;
//int time = 50;
int num = 0;
double val;
fd = open("/dev/magic-adc", 0);
if(fd < 0){
printf("open error by APP- %dn",fd);
close(fd);
return 0;
}
while(1){
sleep(1);
#if 0
ioctl(fd,IMX28_ADC_CH0_DIV2, &iRes); /* 开启除2 CH0 */
val = (iRes * 3.7) / 4096.0;
printf("CH0:%.2f ", val);
ioctl(fd,IMX28_ADC_CH1, &iRes); /* 不开除2 CH1 */
val = (iRes * 1.85) / 4096.0;
printf("CH1:%.2f ", val);
/* 对于EasyARM-iMX280A,请设置为1 */
ioctl(fd,IMX28_ADC_CH2_DIV2, &iRes); /* 开启除2 CH2 */
val = (iRes * 3.7) / 4096.0;
printf("CH2:%.2f ", val);
ioctl(fd, IMX28_ADC_CH3, &iRes); /* 不开除2 CH3 */
val = (iRes * 1.85) / 4096.0;
printf("CH3:%.2f ", val);
ioctl(fd,IMX28_ADC_CH4_DIV2, &iRes); /* 开启除2 CH4 */
val = (iRes * 3.7) / 4096.0;
printf("CH4:%.2f ", val);
#endif
ioctl(fd,IMX28_ADC_CH5, &iRes); /* 不开除2 CH5 */
val = (iRes * 1.85) / 4096.0;
num ++;
printf("CH5:%.2f ,num %d", val,num);
#if 0
ioctl(fd,IMX28_ADC_CH6_DIV2, &iRes); /* 开启除2 CH6 */
val = (iRes * 3.7) / 4096.0;
printf("CH6:%.2f ", val);
ioctl(fd,IMX28_ADC_VBAT_DIV4, &iRes); /* 电池电压默认除4 */
val = (iRes * 7.4) / 4096.0;
printf("Vbat:%.2f ", val);
#endif
printf("rn");
}
close(fd);
}
程序说明:
1)由于只用到ADC5,即ADC通道5。
兔子我就把周立功的官方程序其他通道都注释掉了,仅留通道5,即CH5。
2)open("/dev/magic-adc", 0);
驱动程序里定义的文件magic-adc。即加载ADC驱动后,会在/dev文件夹里生成该文件。
使用ADC功能,需要先open该文件。
3)ioctl(fd,IMX28_ADC_CH5, &iRes);
操作ADC驱动文件,将CH5通道的ADC数据读出来,并存储到变量iRes中。
4)#if 0 #endif 表示中间的内容为注释,如果#if 1,则解开注释。
![e9fc9f1df886267767e73a55f4a04907.png](https://i-blog.csdnimg.cn/blog_migrate/c4f040e44dacc76e05f8bf3f2cd1ce10.jpeg)
调整Makefile文件。
使用make指令,编译测试程序lradc_test.c。
![e056066558097b92a07fce1bbfafdc00.png](https://i-blog.csdnimg.cn/blog_migrate/e87b2026a3636d659b9298e7a4df941e.jpeg)
无错误无警告,表示程序编译通过。生成的文件在该目录下的/bin文件夹里。
至此,ADC模数采集程序编译完成。
并将生成的ADC模数采集的驱动lradc.ko和程序lradc_test拷贝到共享文件夹/work/nfs_root下。
(NFS共享目录操作,可移步教程3)
兔子MCU:从51单片机到Linux 开发板传文件利器-NFS(教程3)zhuanlan.zhihu.com![33e847a96bf17acc0d64f9c1c3a19969.png](https://i-blog.csdnimg.cn/blog_migrate/a1bd5eafbb8974d603f071b5c3d7c098.jpeg)
5.运行程序
1)开发板上电,并挂载NFS共享目录。
(具体操作可移步教程3)
兔子MCU:从51单片机到Linux 开发板传文件利器-NFS(教程3)zhuanlan.zhihu.com![33e847a96bf17acc0d64f9c1c3a19969.png](https://i-blog.csdnimg.cn/blog_migrate/a1bd5eafbb8974d603f071b5c3d7c098.jpeg)
2)进入开发板的NFS挂载点/mnt文件夹下。通过ls命令能查看到我们编译好的ADC模数采集程序和驱动。
![f25aab01461d5048d8734c726227e849.png](https://i-blog.csdnimg.cn/blog_migrate/a4e7455ca2fcbca911fc92fd0bcefa3b.jpeg)
3)首先,先加载驱动。
使用insmod lradc.ko指令。
![ca8389db8e843082a81cfdbefe7bd489.png](https://i-blog.csdnimg.cn/blog_migrate/3b8e4ab98db15378f3a10efd24a43a9e.jpeg)
驱动加载完毕后,使用lsmod指令,确认是否加载OK。
可以看到后面打印了驱动的信息,表示驱动以及加载OK。
4)运行ADC模数采集程序
使用./lradc_test & 表示让ADC模数采集程序在后台运行。
![3e031341d133750b7337ff89a1813098.png](https://i-blog.csdnimg.cn/blog_migrate/5414f40812dda100eda6c84c5360fa05.jpeg)
可以看到,程序这边在不停的打印采集到的ADC的电压值。
1秒打印1次。
![9f79658f5492a5f0a91a219fabc9d8fd.png](https://i-blog.csdnimg.cn/blog_migrate/e1237557dd61222c1a1196e43f8daccb.jpeg)
使用螺丝刀旋转电位器的旋钮,可以看到打印的电压值也在改变。
![a4593a1c89bb8fb4ac846d7b7d1713fb.png](https://i-blog.csdnimg.cn/blog_migrate/e199bac0c6f70c0f9a56e3f66ddf4b46.jpeg)
![3dce88fb52f8186abb71d7a3cfa93a14.png](https://i-blog.csdnimg.cn/blog_migrate/a4577090335c0f9543bbe31dbdb3d77f.jpeg)
至此,ADC模数采集程序已经成功运行。
6.视频操作效果
![f3fbbe1a42f48aa74242cb8279f5c575.png](https://i-blog.csdnimg.cn/blog_migrate/78d27898bf5308ad7b035c5ac4f8a7f2.jpeg)
欢迎大家一起交流学习,本章资料都存放在群里。学习路上不孤单。
![2abcb81865a9a7c71ea2a0afb07a777e.png](https://i-blog.csdnimg.cn/blog_migrate/a568a8e1c99b56c5f2b5d9a9ca21cdf1.jpeg)