一个网站建设需要多少人力,北京seo站内优化,哪些网站可以兼职做设计,app源码网站1.AD转换及其相关背景知识
1.基本概念
1.什么是AD转换#xff1f; A#xff08;A#xff0c;analog#xff0c;模拟的#xff0c;D#xff0c;digital#xff0c;数字的#xff09; 现实世界是模拟的#xff0c;连续分布的#xff0c;无法被分成有限份#xff1b;…
1.AD转换及其相关背景知识
1.基本概念
1.什么是AD转换 AAanalog模拟的Ddigital数字的 现实世界是模拟的连续分布的无法被分成有限份 计算机世界是数字的离散分布的可以被分成有限份的 AD转换就是把一个物理量从模拟的转换成数字的。 2.AD转换的意义 想要计算机来实现现实世界 3.什么情况下需要AD转换 CPU是数字的【要准确的0V或者5V】 2.AD转换的原理
1.比较器 将差一点的电压转换为准确的二进制 所有的AD转换芯片内部都是用比较器来实现的。 2.和十进制转二进制有点像 使用除法 3.AD转换中的主要概念
1.位数 AD转换后转出来的二进制数由几位二进制来表示。【实际结果是一样大】 位数越多越细腻。【精度越高】 2.量程 AD转换器可以接受的模拟量的范围 3.精度 精度准确度 简单理解就是转出来有多准 【精度越小可靠率越高】 4.分辨率 AD转换器转出来的二进制数每一格表示多少 5.转换速率转换时间 时间越短速率越大 6.例子 输入电压范围0-5VAD转换输出位数是10精度是0.01V 量程0-5V 分辨率5-0/2exp100.00488V 比如一次AD转换后得到数据为【1010101010】对应电压值1010101010--十进制682电压682*0.004883.328V考虑精度后为3.33V 4.AD转换在系统中存在的方式
1.CPU外部扩展专用AD芯片
2.CPU内部集成AD模块内部外设
2.原理图和数据手册
https://www.semiee.com/file/ETEK/ETEK-ET2046.pdf
1.原理图 2.数据手册 AIN0-AIN3不能同时采集同一时间只能采集一路 3.SPI接线 CLK接P1.0 CS接P1.1 DI接P1.2 DO接P1.3 4.3种模拟电压变化原理 AIN0靠滑动变阻器控制电压变化 AIN1靠热敏电阻NTC AIN2靠光敏电阻 5.ET2046控制字 bit7起始位【高表示开始传输】1 bit6-bit4决定采样哪一路AIN1AIN0AINT2AINT3 AIN0001/011 X AIN1101 Y AIN2010 VBAT AIN3110 VBAT bit3设置ADC精度【1使用bit8位】【0使用bit12位--一般使用这个】0 bit2【1表示用单端模式】【0表示差分模式触摸屏】1 bit1power down模式使能00表示使能 读AIN00b 1001 01000x94 读AIN10b 1101 01000xd4 读AIN20b 1010 01000xa4读AIN30b 1110 01000xe4 AIN0001/011 X AIN1101 Y AIN2010 VBAT AIN3110 VBAT 3.分析时序
1.时序图
1.SPI变种
回顾SPI知识点【单片机】13-实时时钟DS1302-CSDN博客 有CSDCLKI/O 2.上升沿写入下降沿读出 之前DS1302SPI的时候也是这样 上升沿写入当CLK为上升沿的时候数据通过DI从SPI主设备写入到SPI从设备 下降沿读出当CLK为下降沿的时候数据通过DO从SPI从设备读入到SPI主设备 3.读写都是高位在前 之前DS1302SPI的时候是低位在前 4.注意写和读的交界点 2.官方例程分析
1.ET2046写数据 /*******************************************************************************
* 函 数 名 : xpt2046_wirte_data
* 函数功能 : XPT2046写数据
* 输 入 : dat写入的数据
* 输 出 : 无
*******************************************************************************/
void xpt2046_wirte_data(u8 dat)
{u8 i;CLK 0;//可以忽略的_nop_();for(i0;i8;i)//循环8次每次传输一位共一个字节{//先准备好数据在置CLK0DIN dat 7;//先传高位再传低位dat 1;//将低位移到高位CLK 0;//CLK由低到高产生一个上升沿从而写入数据_nop_(); CLK 1;_nop_();}
}
2.ET2046读数据 /*******************************************************************************
* 函 数 名 : xpt2046_read_data
* 函数功能 : XPT2046读数据
* 输 入 : 无
* 输 出 : XPT2046返回12位数据
*******************************************************************************/
u16 xpt2046_read_data(void)
{u8 i;u16 dat0;CLK 0;_nop_();for(i0;i12;i)//循环12次每次读取一位大于一个字节数所以返回值类型是u16{dat 1;CLK 1;_nop_();CLK 0; //CLK由高到低产生一个下降沿从而读取数据_nop_();dat | DOUT;//先读取高位再读取低位。 }return dat;
}
3.ET2046返回AD值 /*******************************************************************************
* 函 数 名 : xpt2046_read_adc_value
* 函数功能 : XPT2046读AD数据
* 输 入 : cmd指令
* 输 出 : XPT2046返回AD值
*******************************************************************************/
u16 xpt2046_read_adc_value(u8 cmd)
{u8 i;u16 adc_value0;CLK 0;//先拉低时钟CS 0;//使能XPT2046xpt2046_wirte_data(cmd);//发送命令字for(i6; i0; i--);//延时等待转换结果这个时候进行AD转换CLK 1;//发送应该_nop_();CLK 0;//发送一个时钟清除BUSY_nop_();adc_valuexpt2046_read_data();CS 1;//关闭XPT2046return adc_value;
}
4.main函数
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{ u16 adc_value0;float adc_vol;//ADC电压值u8 adc_buf[3];while(1){ //0x94对应AINT0--0b 1001 1100 adc_valuexpt2046_read_adc_value(0x94);//测量电位器adc_vol5.0*adc_value/4096;//将读取的AD值转换为电压adc_valueadc_vol*10;//放大10倍即保留小数点后一位adc_buf[0]gsmg_code[adc_value/10]|0x80;adc_buf[1]gsmg_code[adc_value%10];adc_buf[2]0x3e;//显示单位Vsmg_display(adc_buf,6); }
}
4.代码实践【AD转换】
1.将12bit位的数值分2次输出
//AD value是12bit的分2波出去【因为一次只能输出8位】
void uart_send_advalue(u16 val){uart_send_byte((val8)0xff); //高8位uart_send_byte(val0xff); //低8位uart_send_byte(0);//分割符
}
2. 计算电压值 3.读取AD数值
ET2046.c
#includeET2046.h/*******************************************************************************
* 函 数 名 : xpt2046_read_adc_value
* 函数功能 : XPT2046读AD数据
* 输 入 : cmd指令
* 输 出 : XPT2046返回AD值
*******************************************************************************/
u16 xpt2046_read_adc_value(u8 cmd)
{u8 i;u16 adc_value0; //局部变量的初始化非常重要CLK 0;//先拉低时钟CS 0;//使能XPT2046//写入数据for(i0;i8;i)//循环8次每次传输一位共一个字节{//先准备好数据在置CLK0DIN cmd 7;//先传高位再传低位cmd 1;//将低位移到高位CLK 0;//CLK由低到高产生一个上升沿从而写入数据_nop_(); CLK 1;_nop_();}for(i6; i0; i--);//延时等待转换结果这个时候进行AD转换CLK 1;//发送应该_nop_();CLK 0;//发送一个时钟清除BUSY_nop_();for(i0;i12;i)//循环12次每次读取一位大于一个字节数所以返回值类型是u16{adc_value 1;CLK 1;_nop_();CLK 0; //CLK由高到低产生一个下降沿从而读取数据_nop_();adc_value | DOUT;//先读取高位再读取低位。 }CS 1;//关闭ET2046return adc_value;
}
ET2046.h
#ifndef _xpt2046_H
#define _xpt2046_H#include reg51.h
#include intrins.h typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
typedef unsigned long u32;//管脚定义
sbit DOUT P1^3; //输出
sbit CLK P1^0; //时钟
sbit DIN P1^2; //输入
sbit CS P1^1; //片选//函数声明
u16 xpt2046_read_adc_value(u8 cmd);#endif
main.c
#includeET2046.h
#includeuart.h#define CMD_READ_AIN0 0x94 //滑动变阻器
#define CMD_READ_AIN1 0xD4 //NTC--热敏电阻
#define CMD_READ_AIN2 0xA4 //GR1--光敏电阻
#define CMD_READ_AIN3 0xE4 //外部输入的电压值void Delay400000us() //11.0592MHz
{unsigned char i, j, k;_nop_();_nop_();i 17;j 208;k 27;do{do{while (--k);} while (--j);} while (--i);
}//AD value是12bit的分2波出去【因为一次只能输出8位】
void uart_send_advalue(u16 val){uart_send_byte((val8)0xff); //高8位uart_send_byte(val0xff); //低8位uart_send_byte(0);//分割符
}void main(){//注意定义一个变量要记得初始化要不然后面可能出现问题u16 val0;//12bit数值uart_init();while(1){valxpt2046_read_adc_value(CMD_READ_AIN0);uart_send_advalue(val);Delay400000us();}
}
4.串口直接显示电压值
1.关键点 1直接显示电压值而不是采样AD值 2以文本方式显示而不是十六进制方式 2.将数值转换为十进制
//以文本方式发送c过去意思就是要串口助手用文本方式来查看看到的是
//这个数字本身
void uart_send_text(unsigned char c){//思路就是把c以十进制方式显示的几个数字挨个变成文本发出去unsigned char i;//因为c是unsigned char 范围是0-255//先计算得出c的最高位然后发出去ic/100;uart_send_byte(i48);//48是对应ASCII//计算次高位cc%100;ic/10;uart_send_byte(i48);//计算个位cc%10;ic;uart_send_byte(i48);//发送一个换行uart_send_byte(\r);uart_send_byte(\n);
} 因为我们这里的电压是5V对应5000mV明显上面的0-255不在范围内所以我们要求传入的是unsigned int c【0-2的16次方】才足够 //因为这个函数的范围是unsigned char----是2的8次方
//但是我们最大电压值为5V----5000mV所以我们这里要使用unsigned int
//以文本方式发送c过去意思就是要串口助手用文本方式来查看看到的是
//这个数字本身
void uart_send_text2(unsigned int c){//思路就是把c以十进制方式显示的几个数字挨个变成文本发出去unsigned char i;//因为c是unsigned char 范围是0-255//因为我们知道电压值不会超过5000mV所以只考虑显示1万以内的数据//先计算得出c的最高位然后发出去ic/1000;uart_send_byte(i48);//48是对应ASCIIcc%1000;ic/100;uart_send_byte(i48);//48是对应ASCII//计算次高位cc%100;ic/10;uart_send_byte(i48);//计算个位cc%10;ic;uart_send_byte(i48);//发送一个换行uart_send_byte(\r);uart_send_byte(\n);
}5.DA转换 将数字转换为模拟的 1.DA转换的原理 为了让数字量转换成模拟量必须将每一位代码按其权重的大小转换为相应的模拟量然后再把这些模拟量相加。 2.原理图和案例分析
1.运算放大器LM358 放大作用将数字信号-----》模拟信号 隔离作用防止输出信号影响输入信号 2.PWM数字信号 当输入的PWM数字信号一直为1则输出的模拟信号一直为高电压 如果输入的PWM数字信号一直为0则输出的模拟信号一直为低电压 关键点取决于输入的PWM信号的高低电平所占的时间。【连续变化的模拟量】 3.LM358 其实不接LM358直接用IO口连接LED实现现象也一样。说明灯的亮度只与PWM输入的电压值的大小有关 4.注意点 真正的DA一般是专用芯片或者CPU内置模块给数字值输出平滑模拟量