所用单片机型号:STC15f2k60s2
“千里一走马,五里一扬鞭。都护军书至,匈奴围酒泉。”
五月已近尾声,六月的国赛即将拉开序幕,
今日回顾复习一些蓝桥杯单片机有关ADC\DAC转换方面的设计点。
主要回顾如下几个设计上的问题:
1.ADC采集电压值,保留2位有效数字 (第十一届省赛)
2.浮点型数据不准确,无法判断相等。 (第十一届省赛)
3.DAC一次函数 输出电压 (第十二届省赛)
目录
1.ADC采集电压值,保留2位有效数字 :
2.浮点型数据不准确,无法判断相等
3.DAC一次函数 输出电压
例:有个变量会在0~100之间变化,将转化为0~5V电压的 DAC输出:
1.ADC采集电压值,保留2位有效数字 :
PCF8591AD转换的数据是一个8位的无符号整数,不带小数点。
因为PCF8591AD是一个8位ADC,
所以它只能返回0-255之间的整数值,不能返回任何小数。
如果你想要接收不带小数点的数据,可以直接读取PCF8591AD的I2C接口,
读取到的是一个8位的无符号整数。
如果你想要它带2位小数,需要将其转换为带有小数的浮点数。
例:
- 读取PCF8591AD转换结果,得到一个8位的无符号整数。
- 将这个整数除以255,得到一个0-1之间的小数。
- 将这个小数乘以你想要的最大数值范围,比如说你想要它表示0-10之间的数值,那么你就将这个小数乘以10。
- 最后将这个结果保留2位小数,即可得到带有2位小数的数值
float value_read_AIN3;//AtoD(0x43)是读取0x03 ADC模拟值的ADC转换函数
//此处是转化成0~5之间的 电压值
value_read_AIN3 = AtoD(0x03) *5 / 255;
若有需要打印到数码管显示或储存到AT24C02芯片的需要,
你还需要定义一个int /unsigned int 的整形变量做转换:
int adc_value;
adc_value=(unsigned int)(value_read_AIN3*100);
2.浮点型数据不准确,无法判断相等
浮点数据无法比较相等的原因是由于计算机内部使用二进制表示浮点数,但是在二进制下表示的浮点数并不是精确的,导致在比较浮点数大小时可能会出现误差。例如,0.1在二进制下表示不是精确的,因此使用浮点数进行比较时可能会出现0.1不等于0.1的情况。
解决办法有以下两种:
1.使用“近似相等”比较方法:在比较两个浮点数是否相等时,可以将它们之间的差值与一个较小的阈值进行比较,如果差值小于阈值,则认为它们是近似相等的。
2.使用十进制表示法:将浮点数转换为十进制数后进行比较,这种方法可以避免二进制表示下的精度误差,但是会降低计算速度和增加内存使用。
float value_read_AIN3;
float vp;if((unsigned int)(value_read_AIN3*100)==(unsigned int)(vp*100))
3.DAC一次函数 输出电压
我们在用DAC输出电压时,有时题目会要求我们0~5v之间
用一次函数式输出电压;
DAC输出数字量是通过I2C总线从控制器发送给PCF8591芯片的。
假设DAC输出电压基准电压为Vref,
DAC输出数字量为D,
DAC输出电阻为R,
则PCF8591芯片的DAC输出电压Vout可表示为:
Vout = Vref * D / 255 * R
例:有个变量会在0~100之间变化,将转化为0~5V电压的 DAC输出:
u8 DAC_value; //DAC输出变量
u8 value; //在0~100之间变化的变量DAC_value=value * 255 /100 ;
dac_pcf8591(DAC_value);
由此代码我们可知,value/100计算的就是占总量的百分之几,
再将它乘以255,即可输出按百分比对比5V的电压值了,
但为何此处代码中,是先乘255再除100呢?
因为过小的数比如1,除以100就是0.01,这个值是浮点数
而且太小了,容易被忽略,导致输出电压还是0.
乘除的运算先后顺序相同,因此将乘提前既不影响计算结果
也使得我们想要的实验效果实现了!