A/D&D/A

芝士就是力量,嗯!


今日学习目标达成~~学到了挂接到I2C上的另一个设备 PCF8591 (^-^)V


明确几个点:
(1)A/D依靠的是模数转换器 ADC ,D/A依靠的是数模转换器 DAC
(2)可以把ADC想象成一个米尺,刻度划分规则是:一个n位的ADC表示有2的n次方个刻度;
(3)基准源(基准电压)要保持绝对准确
(4)分辨率是描述刻度划分的,而不是用来描述准确程度的,分辨率如何计算呢?举例说明:5.10v的电压系统用8位的ADC来测量,那么分辨率就等于5.10/(256-1),也就是0.02v;
(5)ADC精度的描述:INL和DNL,单位都是LSB
(6)转换速率:ADC每秒能进行采样转换的最大次数;
(7)ADC将模拟信号转换为数字信号,DAC将数字信号转换为模拟信号。


关于PCF8591

先上原理图:
A/D&D/A_第1张图片
PCF8591是I2C总线上挂的设备,所以使用的也是I2C的通信协议,大家在学习时可以联系一下24C02。
软件编程:
(1)PCF8591的器件地址字节:与24C02相类似,PCF8591也是7位地址,高四位固定是0b1001,低三位是000,那么PCF8591的地址就是01001000,用16进制表示一下就是 0x48 第8位是读写位;
(2)PCF8591的控制字节:这个字节是用来控制PCF8591的功能的
A/D&D/A_第2张图片
第6位: DA使能位,置1可以产生模拟电压输出功能;
第4.5位: 配置AD输入方式(00表示单端输入11表示差分输入,我们的51开发板上用的是单端输入);
第0.1位: 通道选择位,00,01,10,11,表示从 0到3 四个通道选择;
第2位: 自动增量控制位,这里自动增加的是通道数,如读完通道0,就可以直接进入通道1,但是需要注意!!!A/D每次读取的数据并不是当前通道的值,而是上一个通道的值,我们在这里让第二位为0,表明不使用这一功能。
下面是代码:

#define VCC 48//定义电压系统的电压是4.8v
/*读取当前的ADC转换值,chn为ADC的通道号0-3*/
u8 GetADCValue(u8 chn)
{
	u8 val;
	
	I2CStart();
	if(!I2CWrite(0x48<<1))//寻址PCF8591,如未应答,则停止操作并返回0
	{
		I2CStop();
		return 0;
	}
	I2CWrite(0x40 | chn);//写入控制字节,选择转换通道
	I2CStart();
	I2CWrite((0x48<<1) | 0x01);
	I2CReadACK();//先读取一个空字节,提供转换时间
	val = I2CReadNAK();//这里转换完的值只是n个分辨率,即n个刻度
	I2CStop();
	
	val = (val*VCC) / 255;//将读取的数值转换为电压值,val*分辩率
	return val;
}

/*设置DAC输出值,val为设定值*/
void SetDACOut(u8 val)
{
	val = (val*255) / VCC;//将设置的电压值转换为n个刻度,即n个分辨率,这样单片机才能处理
	
	I2CStart();
	if(!I2CWrite(0x48<<1))////寻址PCF8591,如未应答,则停止操作并返回0
	{
		I2CStop();
		return ;//设定温度没有返回值,所以返回空
	}
	I2CWrite(0x40);
	I2CWrite(val);
	I2CStop();
}

几点说明:

  1. 关于GetADCValue这个函数:它的功能是将读取到的刻度值转换为电压值,与转换通道有关,我们来看ADC上面从0-3的转换通道分别是怎么连接的:
    通道0:
    A/D&D/A_第3张图片
    通道0是在J3这个排针上,对应我们的单片机是 J3上的写着A/D的插针,测试时,只要将这个插针与单片机上的GND或者VCC相连,便可用万用表测出相应的电压值,当然也可以显示到数码管上,只要写出相应的代码就可。
    通道1,3:
    A/D&D/A_第4张图片
    通道1是与一个光敏电阻相连接的,改变光敏电阻的光照强度可以得到不同的电压值,建议写一个数码管显示的函数,将电压直观地显示到数码管上。
    通道3是与滑动变阻器Rb2相连接的,同样的转动滑动变阻器,改变阻值,就能得到不同的电压。
    通道2:
    A/D&D/A_第5张图片
    通道2是接在一个电压放大器上的。
  2. 关于下面这段代码:
	I2CReadACK();//先读取一个空字节,提供转换时间
	val = I2CReadNAK();//这里转换完的值只是n个分辨率,即n个刻度

为什么要先读取一个空字节呢?还记得我们上面强调过A/D每次读取到的数据都是上一个通道的值吗,我们在这里这样处理也是因为这一特点。

DAC的功能说明:
自己定义一个电压值输入到PCF8591内部,也可以说是输入到单片机内部,一个8位的D/A,那么输入200就输出一个2V的电压,这个电压可以用万用表测量D/A和GND两点的电压值得到。

你可能感兴趣的:(蓝桥备赛)