0
点赞
收藏
分享

微信扫一扫

蓝桥杯——PCF8591

GG_lyf 2022-05-04 阅读 62

先上原理图

        通过原理图可以看到,PCF8591(ADC芯片)是通过IIC进行读写控制的。

        一共有4个adc输入和一个dac输出。其中最常用的在芯片的左侧,分别有光敏电阻和滑动变阻分别对应着通道1通道三。通道0是外接输入的adc,在板子右侧有引脚引出。

         使用IIC进行读写,我们需要在数据手册找到其对应的地址位构成。可以看到前四位已经固定死了,后四位由A2、A1、A0和读写位组成,在原理图中已经将A2、A1、A0接地,所以 写的地址是0x90 、读的地址是0x91

        接下来需要知道的就是控制字了。

         

                         高                                                                                                低

00000001

         以上控制字的意思为:不允许模拟输出、四个通道对应输入,通道1模拟输入。

StartAddressAControl byteASAddressAStop
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输出的控制字,允许模拟输出。

01000000

    IIC

StartAddressAControl byteAAddressAStop
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
举报

相关推荐

0 条评论