753 字
4 分钟
PCF8591相关功能和考点解析
-
板子设置
板子上没有需要调整的设置,只需记住RB2旋钮和光敏电阻是该函数的外设即可。
测量DAC输出的电压,可以用万用表测J3的19和20引脚(板子上的最右边J3的最后两个引脚)
-
代码注意:
-
unsigned char Ad_Read(unsigned char addr);是读取的模拟值,且自动已转化为数字值。所以此时用变量读取到的值的范围为0-255,因此如果要在数码管上展示模拟信号0-5V,要将该变量 / 51(即5/255,映射值),并且还要注意返回类型为unsigned char
-
void Da_Write(unsigned char dat);是输出的数字值,且输出的数字值会自动转化为外设的模拟电压。所以比如要输出2.5V时,传进去的数据应该为2.5 * 51,即Da_Write(2.5 * 51)。
-
需要填写的地址规定,一般要开启DA输出,所以常用0x41 或者 0x43
-
PCF8591里面的数据读取一次之后,里面的数据就自动清除了,所以同一次,一个通道不能同时读取两次。比如
`Volt_RB3_100x = (AD_read(0x43)*100/51)+0.2;
Volt_temp = (AD_read(0x43)*100/51)+0.2;`
那么Volt_RB3_100x 是正常数值,Volt_temp 数值为0
- 在PCF8591双通道读取数据时,要注意两点(读数据手册可知):
1.我们本次读取的ADC值为上次转换的ADC值;
2. 第一次读取的值由于没有上次转换,因此上电后第一次读取的值默认为0x80。
所以为了正确的存储数值到相应的变量中,我们要在while循环前,将需要读取的通道先转换一次,再在while循环里,在调用相应函数时,进行”反读”操作。例:
void dat_Proc(){//.......//按单通道读取时:RB2_Volt = (Ad_Read(0x43)*10)/51;(0x43是滑动变阻器通道),这是因为虽然读取的是上一次转换的数值,但这都不影响RB2_Volt读取的是正确的通道转化的数值///而在双通道时,在主函数的while循环之前,提前先转化一次滑动变阻器通道的数值,之后再读取通道时,由于是读取的上一个通道的数值,所以用选择用RB2_Volt=(Ad_Read(0x41)*10)/51;这个代码,将滑动变阻器的数据存储在RB2_Volt里,同时再对光敏电阻通道的数值进行转化,等下一次调用时,就用LDR_Volt=(Ad_Read(0x43)*10)/51;与上面是同样的道理,如此循环,就可以成功实现PCF8591读取双通道数值,即所谓的"反读"操作。RB2_Volt=(Ad_Read(0x41)*10)/51;LDR_Volt=(Ad_Read(0x43)*10)/51;//.......}void main (){Ad_Read(0x43);while(1){}}

-
-
底层代码
#include "iic.h"#include "intrins.h"#define DELAY_TIME 5 //注意在官方代码上改过来sbit scl = P2 ^ 0;sbit sda = P2 ^ 1;//模拟电压5V -> 255unsigned char Ad_Read(unsigned char addr){unsigned char temp;// 选择芯片为PCFI2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CStart();I2CSendByte(0x91);I2CWaitAck();temp = I2CReceiveByte();I2CSendAck(1);I2CStop();return temp;}// 数字电压255->5Vvoid Da_Write(unsigned char addr,unsigned char dat) {// 选择芯片为PCFI2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();}
PCF8591相关功能和考点解析
https://mizuki.mysqil.com/posts/蓝桥杯单片机/pcf8591相关功能和考点解析/ 部分信息可能已经过时














