/*  Filename     ZPCF8591.C
    Description  Example Program  
    Hardware     SLAB-51  
    Chip         89V51RD2BN Xtal 11.0592 MHz (Speed x1)
    Compiler     Keil PK51 v7.10
    Engineer	 ANAN PHUKITTIKUL	
    Company      Sila Research Co.,Ltd. 
*/

#include <reg52.h>
#include <intrins.h>
#include <stdio.h>


#define  CH0   0x41
#define  CH1   0x42
#define  CH2   0x43
#define  CH3   0x44
         
// ********** 3B port I2C **********//
sbit     XXSDA			= P1^0;
sbit     XXSCL			= P1^1;             // I2C BUS
         
//******** Basic Function ********//
void dmsec (unsigned int count) {           // mSec Delay
    unsigned int i;                         // for Keil CA51 (Speed x1)
    while (count) {
        i = 115; while (i>0) i--;
        count--;
    }
}

/********** 3B-Port I2C **********/

void ipdel (void) {                    // I2C delay 
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
}

void xxchigh (void) {                  // I2C clock high 
    XXSCL = 1;
    ipdel ();
}

void xxclow (void) {                   // I2C clock low 
    XXSCL = 0;
    ipdel ();
}

void xxstart (void) {                  // start condition 
    XXSDA = 1;
    XXSCL = 1;
    XXSDA = 0;
    ipdel ();
    XXSCL = 0;
    XXSDA = 1;
}
                                        
void xxstop (void) {                   // stop condition 
    XXSDA = 0;
    XXSCL = 1;
    ipdel ();
    XXSDA = 1;
}

bit xxwrbyte (unsigned dat) {          // write one byte 
    unsigned char i;                   // return 0 = ok 
    bit outbit;                        // return 1 = error 
    for (i=1;i<=8;i++) {
        outbit = dat & 0x80;
        XXSDA = outbit;
        dat = dat << 1;
        xxchigh ();
        xxclow ();
    }
    XXSDA = 1;
    xxchigh ();
    outbit = XXSDA;
    xxclow ();
    return (outbit);
}


unsigned char xxrdbyte () {            // read one byte 
    unsigned char i,dat;               // return 0xff = error 
    bit inbit;
    dat = 0;
    for (i=1;i<=8;i++) {
        xxchigh ();
        inbit = XXSDA;
        dat = dat << 1;
        dat = dat | inbit;
        xxclow ();
    }
    XXSDA = 1;
    xxchigh ();
    inbit = XXSDA;
    xxclow ();
    if (~inbit) dat = 0xff;
    return (dat);
}
/************* A/D **************/
unsigned char ADC(unsigned char channel){
	unsigned char temp;
	xxstart();
	xxwrbyte(0x90);	 // pcf8591 address 0
	xxwrbyte(0x40|channel);
	xxstop();
	xxstart();
	xxwrbyte(0x91);
	temp = xxrdbyte();
	xxstop();
	return(temp);
}
/*********** D/A *****************/
void DAC(unsigned char dat){
	xxstart();
	xxwrbyte(0x90);
	xxwrbyte(0x40);
	xxwrbyte(dat);
	xxstop();
}
/*********** RS 232 ***************/
void start (void) {               // speed x 1
    SCON = 0x52;             	  // set RS232 parameter
    TMOD = 0x20;
    TH1 = 0xfd; PCON |= 0x80;     // 19200
    TR1  = 1;
}
/********** MAIN **************/
void main(void){
	unsigned char a,b,c,d;
	float w,x,y,z;	
	start();
	while(1){
		a = ADC(CH0);
		b = ADC(CH1);
		c = ADC(CH2);
		d = ADC(CH3);
		w = a*0.0195;
		x = b*0.0195;
		y = c*0.0195;
		z = d*0.0195;
		printf("ADC CH0 = %1.2f Volt\n",w);
		printf("ADC CH1 = %1.2f Volt\n",x);
		printf("ADC CH2 = %1.2f Volt\n",y);
		printf("ADC CH3 = %1.2f Volt\n\n\n",z);
		DAC(a); 
		dmsec(1000);
	}
}
