15_单片机_A/D

1. A/D:模拟数字转换器,简称ADC,Analog to Digital Converter,通常是指一个将模拟信号转变为数字信号的电子元件。即模拟量到数字量的转换。

 模拟量:指变量在一定的范围内可以连续变化的量。也就是在一定的范围内可以取任意的值。比如说:温度计,范围0~100℃,可以取任一值,1℃,0.01℃ 或者0.0001℃ 等等。总之0~100之间有无限个中间值。所以此称为连续变量的值。

     现实中,温度计被认为刻上了符号,每两个大型的刻度间隔是10℃,这个实际上就是对模拟量的数字化。

     由于有一定的间隔,不是连续的,所以专业的说法叫做离散的。ADC就是将连续的信号用离散的数字表达处理,ADC是模数转换的一种机制。

 

  模拟量可以是电压、电流等电信号,也可以是压力、温度、湿度、位移、声音等非电信号,但在A/D转换前,输入的信号必须是电压信号(通过各种传感器将各种物理量转换为电压信号)

  经过A/D转换后,输出的信号是数字信号,可以是8bit、10bit、12bit等等。

2. A/D的主要技术参数:

 a. 分辨率(位数):也称为精度,通常是以数字信号的位数来表示,它表示对模拟信号进行数字化能够达到多细的程度。

  假如输入的电压为12V,根据位数,那么其分辨率:  

  

 b. 量程:即所转换的电压范围。

 c. 转换时间和转换率:完成一次A/D转换所需要的时间称为转换时间;转换时间的倒数称为转换率。不同形式、不同分辨率的器件,其转换时间的长短相差很大,可为几微妙~几毫秒之间。

3. 当下单片机所使用的A/D元件是兼容ADS7846,那参考ADS7846的data sheet

ADS7846:https://www.mouser.cn/ProductDetail/Texas-Instruments/ADS7846E-2K5?qs=%252BvKcWiXw%252BzQfBMCQoI7Kyw%3D%3D

 

4. 单片机线路图如下:

 


5. 根据ADS7846手册,获取相关信息

 协议:SPI;分辨率:8bit/12bit;量程:5V

 

  时序图

  


 6. 读取滑动变阻器、热敏电阻、光敏电阻的电压,通过串口打印

 a. 串口模块_头文件 

 1 #ifndef  __UART_H__
 2 #define __UART_H__
 3 
 4 #include <reg51.h>
 5 
 6 void InitUART(void);
 7 void SendOneByte(unsigned char c);
 8 void Send_int_data(unsigned int dat);
 9 
10 #endif
View Code

 b. 串口模块_源文件

 1 #include "uart.h"
 2 
 3 void InitUART(void)
 4 {
 5     TMOD = 0x20;
 6     SCON = 0x50;
 7     TH1 = 0xF3;        // baud rate 4800
 8     TL1 = TH1;
 9     PCON = 0x80;
10     # EA = 1;
11     # ES = 1;
12     TR1 = 1;
13 }
14 
15 void SendOneByte(unsigned char c)
16 {
17     SBUF = c;
18     while(!TI);
19     TI = 0;
20 }
21 
22 void Send_int_data(unsigned int dat)
23 {
24     unsigned char i = 0;
25     
26     // 千位数
27     i = dat/1000;
28     // ASCII,字符0=48
29     SendOneByte(i+48);
30     
31     // 百位
32     i = (dat%1000)/100;
33     SendOneByte(i+48);
34     
35     // 十位
36     i = (dat%1000%100)/10;
37     SendOneByte(i+48);
38     
39     // 个位
40     i = (dat%1000%100%10);
41     SendOneByte(i+48);
42     
43     SendOneByte('m');
44     SendOneByte('V');
45     
46     SendOneByte('\r');
47     SendOneByte('\n');
48 }
49 
50 void UARTInterrupt(void) interrupt 4
51 {
52     if(RI)
53     {
54         RI = 0;
55         //add your code here!
56     }
57     else
58         TI = 0;
59 }
View Code

 c. A/D模块_头文件

 1 #ifndef  __ET2046_H__
 2 #define __ET2046_H__
 3 
 4 #include <reg51.h>
 5 #include <intrins.h>
 6 
 7 /**************定义关键词**************/
 8 #ifndef uchar
 9 #define uchar unsigned char
10 #endif
11 
12 #ifndef uint
13 #define uint unsigned int
14 #endif
15 
16 /***************定义I/O***************/
17 sbit DOUT = P3^7;      //输出 DOUT
18 sbit CLK    = P3^6;      //时钟 CLK
19 sbit DIN    = P3^4;      //输入 DIN
20 sbit CS     = P3^5;      //片选 CS
21 
22 /***************函数声明***************/
23 void SPI_Write(uchar dat);
24 uint SPI_Read(void);
25 uint Read_AD_Data(uchar cmd);
26 
27 #endif
View Code

 d. A/D模块_源文件

 1 #include "et2046.h"
 2 
 3 
 4 /********************************************************
 5  * Function        : SPI_Write
 6  * Description    : 通过SPI向ET2046 写入数据
 7  * Parameters    : dat(数据)
 8  * Return Value  : None
 9 ********************************************************/
10 void SPI_Write(uchar dat)
11 {
12     uchar i=0;
13     CLK = 0;
14     for(i=0; i<8; i++)
15     {
16         DIN = dat>>7;        // 从最高位开始
17         dat = dat<<1;
18         CLK = 0;
19         CLK = 1;             // 制造上升沿
20     }
21 }
22 
23 /********************************************************
24  * Function        : SPI_Read
25  * Description     : 通过SPI向ET2046 读取数据
26  * Parameters     : None
27  * Return Value   : dat(12bit数据)
28 ********************************************************/
29 uint SPI_Read(void)
30 {
31     uint i=0, dat=0;
32     CLK = 0;
33     for(i=0; i<12; i++)
34     {
35         dat = dat<<1;
36         CLK = 1;
37         CLK = 0;            // 制造下降沿
38         dat = dat | DOUT;
39     }
40     return dat;
41 }
42 
43 /********************************************************
44  * Function        : Read_AD_Data
45  * Description     : 通过SPI向ET2046 读取外接的数据
46  * Parameters    : Control Byte(控制指令)
47  * Return Value  : dat(12bit数据)
48 ********************************************************/
49 uint Read_AD_Data(uchar cmd)
50 {
51     uchar i = 0;
52     uint AD_Value = 0;
53     
54     CLK = 0;
55     CS = 0;
56     
57     SPI_Write(cmd);                // 初始化SPI
58     
59     for(i=6; i>0; i++);            // 延时等待转换结果
60     
61     CLK = 1;                    // 发送一个周期,清楚BUSY
62     _nop_();
63     _nop_();
64     CLK = 0;
65     _nop_();
66     _nop_();
67     
68     AD_Value = SPI_Read();            // 读取12bit数据
69     
70     CS = 1;
71     
72     return AD_Value;
73 }
View Code

 c. main

 1 #include "uart.h"
 2 #include "et2046.h"
 3 
 4 /***************函数声明***************/
 5 void delay100ms(void);
 6 void delay1s(void);
 7 void Send_AD_Value(uint dat);
 8 void Send_AD_Voltage(uint dat);
 9 
10 /***************变量定义***************/
11 #define READ_CMD_AIN0 0x94        // Resistor Pot
12 #define READ_CMD_AIN1 0xD4        // NTC
13 #define READ_CMD_AIN2 0xA4        // LDR
14 
15 
16 
17 void main(void)
18 {
19     uint dat_val = 0;
20     
21     // 串口初始化
22     InitUART();
23 
24     while(1)
25     {
26         dat_val = Read_AD_Data(READ_CMD_AIN2);
27         # Send_AD_Value(dat_val);
28         Send_AD_Voltage(dat_val);
29         delay1s();
30     }
31     
32 }
33 
34 /********************************************************
35  * Function        : Send_AD_Value
36  * Description     : 通过UART向外发送数据(12bit数据分2次发送)
37  * Parameters     : dat(12bit数据)
38  * Return Value   : None
39 ********************************************************/
40 void Send_AD_Value(uint dat)
41 {
42     uchar dat_h = 0, dat_l = 0;
43     
44     dat_h = ((dat>>8) & 0xff);
45     dat_l = (dat & 0xff);
46     
47     SendOneByte(dat_h);        // 高8位
48     SendOneByte(dat_l);        // 低8位
49     SendOneByte(0);        // 分隔符
50 }
51 
52 /********************************************************
53  * Function        : Send_AD_Voltage
54  * Description     : 通过UART向外发送 转换的电压数值
55  * Parameters     : dat(12bit数据)
56  * Return Value   : None
57  * Remark        : Vcc * Val/2^12 = 5000mV * Val/4096
58                             = 1.22*Val(mV)
59 ********************************************************/
60 void Send_AD_Voltage(uint dat)
61 {
62     float k = 1.22;
63     float vol = k * dat;
64     
65     // 浮点型数据强制转换整型
66     uint voltage = (uint)vol;
67     
68     Send_int_data(voltage);
69 }
70 
71 void delay100ms(void)   
72 {
73     unsigned char a,b,c;
74     for(c=19;c>0;c--)
75         for(b=20;b>0;b--)
76             for(a=130;a>0;a--);
77 }
78 
79 void delay1s(void)  
80 {
81     unsigned char a,b,c;
82     for(c=167;c>0;c--)
83         for(b=171;b>0;b--)
84             for(a=16;a>0;a--);
85     _nop_();  
86 }
View Code

记录下~~

posted on 2023-05-18 21:20  Ivan2023  阅读(99)  评论(0)    收藏  举报