当前位置:网站首页>51 MCU peripherals: ADC
51 MCU peripherals: ADC
2022-08-02 06:20:00 【The road not brook brook】
概念引入
ADC:analog digital converter,AD转换,模数转换(也就是模拟转数字)
CPU本身是数字的,而外部世界变量(如电压、温度、高度、压力···)都是模拟的,所以需要用CPU来处理这些外部的模拟变量的时候就需要做AD转换.
为什么需要ADC?为了用数字技术来处理外部的模拟物理量.
关于模拟量和数字量
模拟的就是连续的,现实生活当中的时间、电压、高度等都是模拟的(连续分布的,划分的话可以无限的更小划分).模拟量反映在数学里面就是无限小数位(从0到1之间有无数个数)数字的就是离散的,离线的就是不连续的.这种离散处理实际上是从数学上对现实中的模拟量的一种有限精度的描述.数字化就是离散化,就是把连续分布的模拟量按照一定精度进行取点(采样)变成有限多个不连续分布的数字值,就叫数字量.
数字化的意义就在于可以用(离散)数学来简化描述模拟量,这东西是计算机技术的基础.
计算机处理参量的时候都是数字化的,计算机需要数字化的值来参与运算.如果系统输入参数中有模拟量,就需要外加AD转换器将模拟量转成数字量再给计算机.有AD自然就有DA
AD是analog to digital,DA自然就是digital to analog,数字转模拟.
纯粹用cpu是不可能实现数字转模拟,因为cpu本身就是数字的.使用一些(具有一些积分或微分效果的)物理器件就可实现数字转模拟.
数字转模拟的作用.譬如可以用来做波形发生器.
ADC的主要相关概念:
量程(模拟量输入范围)
AD转换器是一个电子器件,所以他只能输入电压信号.其他种类的模拟信号要先经过传感器(Sensor)的转换变成模拟的电压信号然后才能给AD.
AD输入端的模拟电压要求有一个范围,一般是0~3.3V或0~5V或者是0~12V等等.模拟电压的范围是AD芯片本身的一个参数.实际工作时给AD的电压信号不能超过这个电压范围.精度(分辨率resolution)
AD转换输出的数字值是有一定的位数的(譬如说10位,意思就是输出的数字值是用10个二进制位来表示的,这种就叫10位AD).这个位数就表示了转换精度.
10位AD就相当于把整个范围分成了1024个格子,每个格子之间的间隔就是电压的表示精度.加入AD芯片的量程是0~3.3V,则每个格子代表的电压值是3.3V/1024=0.0032265V.如果此时AD转换后得到的数字量是447,则这个数字量代表的模拟值是:447×0.0032265V=1.44V.
AD的位数越多,则每个格子表示的电压值越小,将来算出来的模拟电压值就越精确.
AD的模拟量程一样的情况下,AD精度位数越多精度越高,测出来的值越准.但是如果AD的量程不一样.譬如2个AD,A的量程是0~50V,B的量程是0~0.5V,A是12位的,B是10位的,可能B的精度比A的还要高.(A的精度:50/1024=0.04883,B的精度:0.5/4096=0.000122)
转换速率(MSPS与conventor clock的不同)
首先要明白:AD芯片进行AD转换是要耗费时间的.这个时间需要多久,不同的芯片是不一样的,同一颗芯片在配置不一样(譬如说精度配置为10位时时间比精度配置为12位时要小,譬如说有些AD可以配转换时钟,时钟频率高则转换时间短)时转换时间也不一样.
详细的需要时间可以参考数据手册.一般数据手册中描述转换速率用的单位是MSPS(第一个M是兆,S是sample,就是采样;PS就是per second,总的意思就是兆样本每秒,每秒种转出来多少M个数字值)
AD工作都需要一个时钟,这个时钟有一个范围,我们实际给他配置时不要超出这个范围就可以了.AD转换是在这个时钟下进行的,时钟的频率控制着AD转换的速率.注意:时钟频率和MSPS不是一回事,只是成正比不是完全相等.譬如S5PV210中的AD转换器,MSPS = 时钟频率/5.通道数
AD芯片有多少路analog input通道,代表了将来可以同时进行多少路模拟信号的输入.
查看原理图
其中,ET2046It is a touch screen controller chip,Because touchscreens are, essentiallyAD转换,So use this controller to demonstrateADC.
Refer to the data sheet for the specific content of the chip:ET2046 - 百度文库
We only record the key points here.
1、该芯片采用的是SPI总线协议,重点关注以下4个引脚,DIN,DOUT,CS,DCLK,正好是SPIThe four pins of the protocol,两根数据线,一根时钟线,一根片选线.We connect them to the following pins respectively.CLK接P1.0,CS接P1.1,DI接P1.2,DQ接P1.3.
2、There are three analog inputs.AIN0The voltage change is controlled by a sliding rheostat,AIN1by the thermistorNTCControl voltage changes,AIN2By photoresistorGR1Control voltage changes.
ET2046控制字
控制字(加在DIN端口)提供ET2046的以下信息:Start conversion flag、地址、ADC的精度、配置方式和Power-Down模式的选择,如下所示:
bit7:起始位,Must be held high to indicate the start of a control word transfer.Ignored when no start bit is detectedDINall inputs on the pins.
bit6-4:Decide which way to sample(AIN0、AIN1、AIN2、AIN3)
AIN0:001/011 X+
AIN1:101 Y+
AIN2:010 VBAT
AIN3:110 AUXbit3:设置采样位数.0表示12bit,1表示8bit,一般都用12bit.
bit2:为1Indicates single-ended mode,为0表示差分模式.Single-ended mode is used here.
bit1-0:power down模式(Power-down operating mode,Belongs to low power mode)使能,00表示使能.
总结来看:
读AIN0时写入:0b10010100 = 0x94
读AIN1时写入:0b11010100 = 0xD4
读AIN2时写入:0b10100100 = 0xA4
读AIN3时写入:0b11100100 = 0xE4
读写时序
属于SPI总线协议,但又不完全是.
1、上升沿写入,下降沿读出;
2、Read and write are high order first;
3、BUSYSignals are for detectionAD是否在忙,this busy time,就是ADThe time period being converted.But generally don't care,Because we only need to delay for a while after writing the control word(比如1us),No need for this test,Spend one moreIO口.
4、所以,After writing the control word,There is a slightly longer delay,让AD完成转换,然后再读取.
5、Because the control word is generally selected12bit精度,So the read data is12位二进制数,需要用uint来接收.
数值计算
float = 接收到的12位数,转成十进制数,然后除以2^12.
得到的比例,Then multiply by the range.That is, the final voltage value.
留个思考题:If the value is displayed in the form of characters through the serial port?
代码实现
#include "ET2046.h" uint Read_AD_Data(uchar cmd) { uchar i; uint AD_Value = 0; // The initialization of local variables is very important CLK = 0; CS = 0; for(i=0; i<8; i++) { DIN = cmd >> 7; //放置最高位 cmd <<= 1; CLK = 0; //上升沿放置数据 CLK = 1; } for(i=6; i>0; i--); //延时等待转换结果 CLK = 1; //发送一个时钟周期,清除BUSY _nop_(); _nop_(); CLK = 0; _nop_(); _nop_(); for(i=0; i<12; i++) //接收12位数据 { AD_Value <<= 1; CLK = 1; CLK = 0; AD_Value |= DOUT; } CS = 1; return AD_Value; }
main.c
#include "ET2046.h" #include "uart.h" #define CMD_READ_AIN0 0x94 // 滑动变阻器 #define CMD_READ_AIN1 0xD4 // NTC #define CMD_READ_AIN2 0xA4 // GR1 #define CMD_READ_AIN3 0xE4 // Voltage value of external input // AD value是12bit的,分2dial out void uart_send_advalue(uint val) { uart_send_byte((val >> 8) & 0xff); // 高8位 uart_send_byte(val & 0xff); // 低8位 uart_send_byte(0); } void delay1s(void) //误差 0us { unsigned char a,b,c; for(c=167;c>0;c--) for(b=171;b>0;b--) for(a=16;a>0;a--); _nop_(); //if Keil,require use intrins.h } // 思路:用51MCU to calculate,Calculate the final voltage value directly,Then send the display through the serial port // 第1步:First, calculate the voltage value(val/4096)*5000mV =1.22*val(mV) // 第2步:The serial port is sent out for display.显示方法1,Send it out in binary for display // 方法2:Displayed in text.Calculate the value to send,转成对应的ASCII码发送 // Display the serial port // Prints voltage values directly in text void uart_send_voltage(uint val) { // 先将AD值val换算成mVvoltage value in units float index = 1.22; float voltage = index * val; uint vol_display = (uint)voltage; uart_send_text2(vol_display); } void main(void) { uint val = 0; uart_init(); // uart_send_voltage(3241); // while (1); while (1) { val = Read_AD_Data(CMD_READ_AIN0); // 滑动变阻器,测试ok // val = Read_AD_Data(CMD_READ_AIN1); // NTC,测试ok // val = Read_AD_Data(CMD_READ_AIN2); // 光敏电阻,测试ok //uart_send_advalue(val); uart_send_voltage(val); delay1s(); } }
uart.c
#include "uart.h" // 串口设置为: 波特率9600、数据位8、停止位1、奇偶校验无 // The crystal used is11.0592MHz的,注意12MHz和24MHz的不行 void uart_init(void) { // 波特率9600 SCON = 0x50; // 串口工作在模式1(8位串口)、允许接收 PCON = 0x00; // 波特率不加倍 // Communication baud rate related settings TMOD = 0x20; // 设置T1为模式2 TH1 = 253; TL1 = 253; // 8位自动重装,意思就是TH1The next cycle after it is used upTL1会 // Automatically reload toTH1去 TR1 = 1; // 开启T1让它开始工作 // ES = 1; // EA = 1; } // 通过串口发送1个字节出去 void uart_send_byte(unsigned char c) { // 第1步,发送一个字节 SBUF = c; // 第2步,Make sure that the sending part of the serial port is not busy while (!TI); // 第3步,软件复位TI标志位 TI = 0; } // Send as textc过去,It means to use the serial port assistant to view it in text mode,看到的是 // 这个数字本身 void uart_send_text(unsigned char c) { // 思路就是把cSeveral numbers displayed in decimal,One by one into text and send out unsigned char i; // 先计算得出c的最高位,然后发出去 i = c / 100; uart_send_byte(i + 48); // Then calculate the next highest bit c = c % 100; i = c / 10; uart_send_byte(i + 48); // Then count the units c = c % 10; i = c; uart_send_byte(i + 48); // Send a newline uart_send_byte('\r'); uart_send_byte('\n'); } // Because we know the voltage value will not exceed5000,So only consider display1values within 10,000 // This way the limit can be limited to a maximum value of 9999 void uart_send_text2(unsigned int c) { // 思路就是把cSeveral numbers displayed in decimal,One by one into text and send out unsigned char i; i = c / 1000; uart_send_byte(i + '0'); uart_send_byte('.'); // 先计算得出c的最高位,然后发出去 c = c % 1000; i = c / 100; uart_send_byte(i + 48); // Then calculate the next highest bit c = c % 100; i = c / 10; uart_send_byte(i + 48); // Then count the units c = c % 10; i = c; uart_send_byte(i + 48); uart_send_byte('V'); // Send a newline uart_send_byte('\r'); uart_send_byte('\n'); }
边栏推荐
- MySQL 8.0.29 设置和修改默认密码
- 25K测试老鸟6年经验的面试心得,四种公司、四种问题…
- 公司不重视软件测试,新来的阿里P8给我们撰写了测试用例编写规范
- PIL与numpy格式之间的转换
- MySQL multi-table association one-to-many query to get the latest data
- Redis集群模式
- MySQL 8.0.29 解压版安装教程(亲测有效)
- Detailed explanation of the software testing process (mind map) of the first-tier manufacturers
- How Navicat Connects to MySQL
- Navicat报错:1045 -拒绝访问用户[email protected](使用passwordYES)
猜你喜欢
The company does not pay attention to software testing, and the new Ali P8 has written a test case writing specification for us
Shuttle + Alluxio 加速内存Shuffle起飞
navicat connects to MySQL and reports an error: 1045 - Access denied for user 'root'@'localhost' (using password YES)
How much does a test environment cost? Start with cost and efficiency
Navicat new database
100 latest software testing interview questions in 2022, summary of common interview questions and answers
C language: Check for omissions and fill in vacancies (3)
ApiPost is really fragrant and powerful, it's time to throw away Postman and Swagger
Three methods of importing sql files in MySQL
leetcode每天5题-Day04
随机推荐
Cyber Security Learning - Intranet Penetration 4
Detailed explanation of interface in Go language
Navicat报错:1045-Access denied for user [email protected](using passwordYES)
Go language study notes - grpc serverclient protobuf Go language from scratch
Browser onload event
18年程序员生涯,读了200多本编程书,挑出一些精华分享给大家
100 latest software testing interview questions in 2022, summary of common interview questions and answers
21 Day Learning Challenge Schedule
"Digital reconstruction of the system, getting the CEO is the first step"
leetcode 665. Non-decreasing Array 非递减数列(中等)
apifox介绍及使用(1)。
Google Chrome(谷歌浏览器)安装使用
go项目的打包部署
navicat新建数据库
软件测试的需求人才越来越多,为什么大家还是不太愿意走软件测试的道路?
classSR论文阅读笔记
Redis-cluster mode (master-slave replication mode, sentinel mode, clustering mode)
Mysql实现乐观锁
MySQL导入sql文件的三种方法
Shuttle + Alluxio 加速内存Shuffle起飞