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


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
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 }
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
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 }
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 }
记录下~~
浙公网安备 33010602011771号