【蓝桥杯单片机组】PCF8591 关于蓝桥杯坑爹I2C的吐槽

根据datasheet的时序:

【蓝桥杯单片机组】PCF8591 关于蓝桥杯坑爹I2C的吐槽_第1张图片

编程步骤:初始化AD,给AD传送采样通道与输入方式(写过程,上图)

(1)打开总线

(2)发送ADDRESS(BIT0 = 0)

(3)等待PCF应答

(4)发送控制位(控制参考下图)

(5)等待PCF应答

(6)结束总线

附:控制位

【蓝桥杯单片机组】PCF8591 关于蓝桥杯坑爹I2C的吐槽_第2张图片

地址位:

【蓝桥杯单片机组】PCF8591 关于蓝桥杯坑爹I2C的吐槽_第3张图片

综上所述:初始化PCF8591时的代码如下:

void PCF8591_init()			//wirte:fig.16 in datasheet
{
	EA = 0;
	IIC_Start();	
	IIC_SendByte(0x90);	   	//Address byte:fixed part + programmable part + R/W\ 

	while(!IIC_WaitAck());
//	IIC_WaitAck();

	IIC_SendByte(0x03);		//Control byte		CH3

	while(!IIC_WaitAck());
//	IIC_WaitAck();

	IIC_Stop();
	EA = 1;
	somedelay(10);
}

----------------------------------------------------------------------------------------------------------------------------

编程步骤:(读数部分:根据下图,是一个读数据过程)

【蓝桥杯单片机组】PCF8591 关于蓝桥杯坑爹I2C的吐槽_第4张图片

(1)开始总线

(2)发送地址位(BIT0 = 1)

(3)等待PCF的应答

(4)读数据

(5)向PCF回应“1”表示收到

(6)结束总线


综上所述:以下为读数代码

unsigned char PCF8591_adc()	//read:fig.17 in datasheet
{
	unsigned char vo;
	EA = 0;
	IIC_Start();
	IIC_SendByte(0x91);		//Address byte:fixed part + programmable part + R/W\ 

	while(!IIC_WaitAck());
//	IIC_WaitAck();

	vo = IIC_RecByte();		//read data
   	IIC_Ack(1);				//ack
	IIC_Stop();
	EA = 1;
	
	somedelay(10);
	return vo;
}
注意在读写过程中关闭EA,防止时序被打乱


附:主程序:

#include 
#include "init.h"
#include "iic.h"
#include "display.h"
void Delay500ms();		//@11.0592MHz
void sendchar(unsigned char dat);

sfr AUXR = 0x8E; 	//IAP15F2K61S2单片机特殊功能寄存器
unsigned char vol = 0;
unsigned char ms500flag = 0;


void main()
{
	cls_buzz();
	Timer0Init();
    PCF8591_init();
	UartInit();
	while(1)
	{
		display1(vol);
		if(ms500flag == 1)
		{
			ms500flag = 0;
			vol = PCF8591_adc();
//			sendchar(vol);
		}


	}
	
}

void T0_isr() interrupt 1
{
	static int i = 0;
	TL0 = 0x00;		//设置定时初值
	TH0 = 0xB8;		//设置定时初值
	i++;
	if(i >= 25)	//0.5S
	{
		ms500flag = 1;
		i = 0;
	}
}


--------------------------------------------------------------------------分割线----------------------------------------------------------------------------

2017-2-27

程序还是有点问题,感觉在软件延时上,因为使用的IAP15的运行速度为1T,所以需要修改iic.h中对somenop的定义:

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();    _nop_();_nop_();_nop_();_nop_();_nop_();  _nop_();_nop_();_nop_();_nop_();_nop_();    _nop_();_nop_();_nop_();_nop_();_nop_();  _nop_();_nop_();_nop_();_nop_();_nop_();  _nop_();_nop_();_nop_();_nop_();_nop_();}  //4
对,就他妈这么多个nop,但是还他妈有错,读数一直显示正常,知道将电位器调节到65以下的时候,就开始乱跳,原因还没找到,估计还是延时时间的问题。

2017-3-2

好了,修改好了,群里也有人碰到了同样的问题

解决方法:将读数据后的应答改成

	 IIC_Ack(0);
另外,数了一下亲测可用的NOP, 33个nop,记住!!!!!!

记住今天的苦难,全他妈是昨天官方驱动下的毒!!!!!



你可能感兴趣的:(蓝桥杯单片机组)