蓝桥杯-51单片机-PCF8591使用

PCF8591引脚图与原理图

蓝桥杯比赛中,PCF8591用于进行AD/DA转换,有模拟输入通道AN1光敏电阻和AN3滑动变阻。

使用时需明细通道。

PCF8591如何使用及代码

蓝桥杯比赛中,PCF8591可以进行AD转换读取和DA转换写入操作。

以下介绍AD转换读取操作,即通过光敏电阻或滑变读取模拟量转换为数字量的过程。

一:发送地址字节:

系统中的每个PCF8591芯片都有I2C总线系统控制,使用第一步需要通过I2C总线发送地址字节来激活PCF8591芯片,通过翻阅芯片手册可知,地址字节如下:

由上述原理图可知,蓝桥杯比赛版上A2=A1=A0=0,系统中只有一个PCF8591芯片,故仅需改变最低位来控制芯片的读写操作,发送0x91 = 1001 0001为读取,发送0x90 = 1001 0000为写入。

二:发送控制字节

第二步需要通过总线发送控制字节来告诉芯片选用哪一通道,使用时需注意第0位,第1位,第6位。前两位负责选用AD通道,第六位是输出使能位,其余位蓝桥杯不涉及,暂未了解。蓝桥杯比赛中有channel1 光敏电阻,channel 3 变阻器。选用channel1 则发送0x41 = 0100 0001选用光敏,选用channel 3则发送 0x43 = 0100 0011选用滑动变阻器。

三:AD转换读取函数:

以上两步结合总结,可以得出AD转换读取函数的流程,即:

发送地址字节,告诉芯片需要写入数据->发送控制字节,告诉芯片要选用哪一通道

发送地址字节,告诉芯片需要读取数据->将数据从芯片中读出,通过变量传出函数。

具体代码如下:

unsigned char AD_Read(unsigned char addr)
{
	unsigned char temp;
	I2CStart();
	I2CSendByte(0x90);		//发送地址字节-写入
	I2CWaitAck();
	I2CSendByte(addr);		//发送控制字节-选中通道
	I2CWaitAck();
	I2CStart();             
	I2CSendByte(0x91);      //发送地址字节-读取
	I2CWaitAck();
	temp = I2CReceiveByte();//读取操作
	I2CSendAck(1);
	I2CStop();
	return temp;            //将读取结果传出
}

以上代码中I2CStart(),I2CWaitAck()等操作是I2C总线的使用要求,与本芯片无关。通过上述代码将数字量temp读取出,其范围为0-255,比赛板的电压为5v,若想将表示为模拟量电压显示在数码管上,需要进行一步转换操作:

	temp = temp * (5.0 / 255);

四:DA转换写入函数:

DA转换的思路同AD转换,只不过在DA转换中不需要考虑发送控制字节选用哪一通道的问题,只需保证控制字节中第6位使能位为1即可。具体代码如下:

DA_Write(unsigned char dat)
{
    I2CStart();
    I2CSendByte(0x90);
    I2CWaitAck();
    I2CSendByte(0x41);    //0x40也可,仅需保证D6 = 1
    I2CWaitAck();
    I2CSendByte(dat);
    I2CSendAck(1);
    I2CStop();
}

 

五:主函数中如何使用:

仅演示如何使用AD_Read函数:

unsigned char dat; //定义一变量存放读取后的数据

void Seg_Proc()
{
	if(Seg_Slow_Down) return;
	Seg_Slow_Down = 1;
	
	/*** 信息读取区域 ***/
	
		/* DS1302时钟 */
//	RTC_Read(ucRTC);
	
		/* DS18B20温度 */
//	temperature = Temperature_Read();
	
		/* PCF8591 AD/DA */
	dat = AD_Read(0x43);
	
	/*** 数据处理区域 ***/
		/* DS1302时钟 */
//	Seg_Buf[0] = ucRTC[0] / 16; //时第一位
//	Seg_Buf[1] = ucRTC[0] % 16;
//	Seg_Buf[2] = 11;
//	Seg_Buf[3] = ucRTC[1] / 16; //分第一位
//	Seg_Buf[4] = ucRTC[1] % 16;
//	Seg_Buf[5] = 11;
//	Seg_Buf[6] = ucRTC[2] / 16; //秒第一位
//	Seg_Buf[7] = ucRTC[2] % 16;

		/* DS18B20温度 */
//	Seg_Buf[0] = (unsigned char)temperature / 10 % 10;
//	Seg_Buf[1] = (unsigned char)temperature % 10;
//	Seg_Point[1] = 1;
//	Seg_Buf[2] = (unsigned int)(temperature * 100) % 10;
//	Seg_Buf[3] = (unsigned int)(temperature * 10) % 10;

		/* PCF8591 AD/DA */
	Seg_Buf[0] = dat / 100 % 10;       //这里显示的是未经处理的数字量,范围0-255
	Seg_Buf[1] = dat / 10 % 10;
	Seg_Buf[2] = dat % 10;
		
		/* AT24C02 EEPROM存储 */
//	Seg_Buf[0] = EEPROM_Dat[0] / 10;
//	Seg_Buf[1] = EEPROM_Dat[0] % 10;
//	
//	Seg_Buf[6] = EEPROM_Dat[1] / 10;
//	Seg_Buf[7] = EEPROM_Dat[1] % 10;
}

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值