根据datasheet的时序:
编程步骤:初始化AD,给AD传送采样通道与输入方式(写过程,上图)
(1)打开总线
(2)发送ADDRESS(BIT0 = 0)
(3)等待PCF应答
(4)发送控制位(控制参考下图)
(5)等待PCF应答
(6)结束总线
附:控制位
地址位:
综上所述:初始化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);
}
----------------------------------------------------------------------------------------------------------------------------
编程步骤:(读数部分:根据下图,是一个读数据过程)
(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,记住!!!!!!
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』