先上原理图
????????通过原理图可以看到,PCF8591(ADC芯片)是通过IIC进行读写控制的。
????????一共有4个adc输入和一个dac输出。其中最常用的在芯片的左侧,分别有光敏电阻和滑动变阻分别对应着通道1和通道三。通道0是外接输入的adc,在板子右侧有引脚引出。
?????????使用IIC进行读写,我们需要在数据手册找到其对应的地址位构成。可以看到前四位已经固定死了,后四位由A2、A1、A0和读写位组成,在原理图中已经将A2、A1、A0接地,所以 写的地址是0x90 、读的地址是0x91 。
? ? ? ? 接下来需要知道的就是控制字了。
?????????
?????????????????????????高????????????????????????????????????????????????????????????????????????????????????????????????低
?????????以上控制字的意思为:不允许模拟输出、四个通道对应输入,通道1模拟输入。
Start | Address | A | Control byte | A | S | Address | A | Stop |
uchar read_adc(uchar Crl)
{
uchar date;
IIC_Start();
IIC_SendByte(0x90); //器件地址-写
IIC_WaitAck();
IIC_SendByte(Crl); //控制字
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91); //器件地址-读
IIC_WaitAck();
date = IIC_RecByte();
IIC_Stop();
return date;
}
?????????在主函数中使用。
adc_val=read_adc(0x01);
volt=adc_val*1.96;
? ? ? ? ?dac输出的控制字,允许模拟输出。
? ? IIC
Start | Address | A | Control byte | A | Address | A | Stop | |
void write_dac(uchar dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(dat); //da 输出 0-255
IIC_WaitAck();
IIC_Stop();
}
? ? ? ? 将想要输出的值装入函数,即可转换成对应电压。
底层驱动
iic.c
#include "iic.h"
#define DELAY_TIME 5
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit;
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
iic.h
#ifndef _IIC_H
#define _IIC_H
#include "stc15.h"
#include "intrins.h"
sbit SDA = P2^1;
sbit SCL = P2^0;
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
#endif
|