下文仅仅讲怎么使用。
本文章参考:
【蓝桥杯】PCF8591 A/D D/A转换应用_pcf8591中输出电压2v怎么表示-CSDN博客
蓝桥杯电子类单片机学习三——PCF8591 AD/DA转化器,AT24C02 EEPROM存储器(iic驱动)_蓝桥杯da转换输出的是什么-CSDN博客
【蓝桥杯单片机进阶强化-02】PCF8591的基本原理与A/D转换应用_蓝桥杯怎么调节rb2电阻-CSDN博客
icc总线在蓝桥杯单片机中总共会考三个地方:分别是ADC(光敏电阻、RB2模拟电压值) 、DAC输出电压、AT24C02中EEPROM存储器。
这里讲一下其中PCF8591的使用(即包括ADC和DAC电压输出两个知识点)
总的知识概括(icc总线)
(1)大致介绍
以下纯复制以下博主讲的内容,我觉得讲的很好,单纯想记录下来,如果侵权可联系我删掉谢谢!!!蓝桥杯电子类单片机学习三——PCF8591 AD/DA转化器,AT24C02 EEPROM存储器(iic驱动)_蓝桥杯da转换输出的是什么-CSDN博客
(2 )icc底层代码的编写
和之前其他的onewire,ds1302的底层代码编写文件大致相同。
首先是把结构写好:
其次就是函数声明,(去.c文件中找):
最后执行发现会有报错还有引脚没有定义,此时就要去看硬件图,定义相关引脚:这里就是
SDA为P2^1
SCL为P2^0.
PCF8591
硬件图如下:
对于PCF8591的使用,仅仅就使用方面,只了解下述几个部分即可:
1 ROM检测(设备地址)
刚刚提到icc上挂了两个设备,一个是PCF8591,一个是AT24C02,简单来理解,ROM检测就是判断icc要使用的设备是这两个的其中哪一个。
如上图,PCF8591的设备地址(8位)包括三部分,一个是固定部分为1001,一个是可编程部分,再加上最后一位为读写控制位。
在蓝桥杯中,看PCF8591的硬件图可知A0~A2是接地的,故可编程部分也变成了固定的0000,故只剩下最后一位可变。
所以记住就好!!PCF8591的设备的读操作地址为:0x91;而写操作地址则为:0x90。
2 控制寄存器
进行了ROM检测后,就可以输入控制字节了,可以理解为告诉PFC8591要执行个什么功能吧。
(以下图片来源小蜜蜂老师)
这里参考第二篇博文的内容,总结一下比赛常用的知识:(以下的位是按输入的二进制来看的,与图片是对应的如 0100 0000 中的0是二进制的第一位,即固定为0,对应图片上的第七位。)
第一位:固定为0
第二位:1:DA转化,0:AD转化
第三 四位:用于选择PCF8591的工作模式,通常选第一个模式,即00
第五位:固定为0
第六位:自增模式,一般为0
第七八位:选择通道
通道0对应的是00,蓝桥杯板子上连接的是一个空引脚,用于后续拓展或者DA输出
通道1(AIN1)对应01,蓝桥杯板子上连接的是光敏电阻RD1。
通道2(AIN2)对应10,蓝桥杯板子上连接的是LM324(基本很少使用)
通道3对应11,蓝桥杯板子上连接的是可调电阻RB2(电位计)
在板子上右下角找到RD1和RB2就是对应的光敏电阻和电位计了。
总结:
光敏传感器接到AIN1,通道1;控制寄存器应写入:0x01。
电位器Rb2接到AIN3,通道3;控制寄存器应写入:0x03。
DA输出:即第二位为1,写入:0x40(但有时也会写0x43,看题有没有特意说要通道三输出)
3 代码编写使用
啊啊啊啊我在练习的时候发现我昨天写的有误,现在更改一下!
其主要使用是两个函数,一个是ADC转换函数——简单来理解,他就是读取数据,读取到多少就是多少。
3.1ADC输出(读取PCF8591)
简单来说分为4部分:写 —— 等待电压转换 —— 读 —— 电压转换
注意:光敏电阻和电位计主要就是读取PCF8591的值,测量出来是多少就是多少,但由于其受到环境影响(如光),故可认为跳空高,比如去更暗的地方,光敏电阻的阻值就会改变,还有看板子上的电位计RB2,他其实是一个可以扭的按钮,故可通过扭动来调节阻值。
写:
初始化 - 》 写入写地址(等待 )-》写通道(等待)-》停止
初始化 IIC_Start();
写入设备地址0x90(+等待 IIC_WaitAck();)
选通道(+等待)(以下以DAC为例)
停止
IIC_Start();
IIC_SendByte(0x90); //PCF8591的写设备地址
IIC_WaitAck();
IIC_SendByte(0x40); //输出DAC
IIC_WaitAck();
IIC_Stop();
等待电压转换
就一句话:其实就是一个Delay
读:
初始化 -》 写入读地址(等待) -》读取数据 -》非应答信号 -》停止
初始化 IIC_Start();
读设备地址0x91(+等待)(注意,这里是写入)
读采样数据(将其放到一个变量里面)
产生非应答信号IIC_SendAck(1);
停止
IIC_Start();
IIC_SendByte(0x91); //PCF8591的读设备地址
IIC_WaitAck();
adc_value = IIC_RecByte(); //读出AD采样数据
IIC_SendAck(1); //产生非应答信号
IIC_Stop();
电压转换(可有可无,看需求)
原理是电压储存是8位(0~255),对应的是0~5V,则相当于把5V电压分为255份则:
假设输出为2V,对应储存的数转为十进制为x:
则得到x为 (2*255)/ 5 = 102。
还有说一个很奇葩的点,就是我写代码的时候发现其转换为电压时公式里的5要用5.0表示。
3.2 DA输出函数(写入PCF8591)
初始化
写入设备地址(+等待)
输出DAC(+等待)
发送采样到的数据(上面储存的变量值)
产生非应答信号
停止
void Set_PCF8591_DAC(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0x90); //PCF8591的写设备地址
IIC_WaitAck();
IIC_SendByte(0x40); //输出DAC,转换AIN3
IIC_WaitAck();
IIC_SendByte(dat); //设置DAC电压输出参数
IIC_WaitAck(); //产生非应答信号
IIC_Stop();
}
第二个是DA输出函数,用于DA输出电压。
这里往往会将输出电压显示出来,这里有意思的就是显示数码管的参数用的是直接定义一个变量,那就会想了,直接定义一个变量就直接显示了还要DA输出函数干嘛?
可以这样理解:DA输出函数是写给单片机里面的设置电压的,你是看不见的,当你要在数码管显示的时候,其实就相当于你设置一个变量储存对应时候的值,用于显示而已。比如下面这个代码,DA输出函数后,有设置对应的变量用于数码管显示。