Thursday, April 29, 2010

--> RTC Interface and frequency monitor

Frequency counter and real time controller interface and current time display:
PCF8583 is frequency divider, he gets clock ~32kHZ from xtal, and just divide to get signal 0.1Hz. Accuracy of PCF8583 is accuracy of xtal. But in this project it is only used as RTC just. The prime objective of the project is to measure the incoming frequency and then o display on the LCD (2 line and 20 characters 2*20 LCD alpha numaric liquid crystal display). When the measurement is completed, it also updates the current time and date on the second line of the lcd. PIC16f84 microcontroller is used.


I have written the code in basic "proton IDE" for the project, RTC interface and frequency monitor. but I am also trying to write the program in c language also. As we know that The RTC PCF 8583 and PIC 16f84 will communicate with each other through I2C protocol. so below is some code which will bring the most common function of the PCF 8583.
//*************************************************************************// Prog_i2c_1.c//
simple software driven I2C routine for Master Only mode
// Single routine to write data to i2c REQUIRED DEFINES ***********
// #define BITNUM(adr, bit) ((unsigned)(&adr)*8+(bit))
// static bit SCL @ BITNUM(PORTA,0)
//-- The SCL output pin// #define SCL_TRIS
//-- The SCL Direction Register Bit// #define SDA
//-- The SDA output pin// #define SDA_TRIS
//-- The SDA Direction Register Bit
// #define XTAL_FREQ 8MHZ
//-- Define the crystal frequency
#define I2CLOW 0 //-- Puts pin into output/low mode#define I2CHIGH 1 //-- Puts pin into Input/high mode
#ifndef MHZ #define MHZ *1000 /* number of kHz in a MHz */#endif#ifndef KHZ #define KHZ *1 /* number of kHz in a kHz */#endif
//********* I2C Bus Timing - uS ************#define I2CSTARTDELAY 50#define I2CSTOPDELAY 50#define I2CDATASETTLE 20#define I2CCLOCKHIGH 100#define I2CHALFCLOCK 50#define I2CCLOCKLOW 100#define I2CACKWAITMIN 50
//********************* FUNCTIONS ************************char I2C_Send(char Address,char *Data,char Num);char I2C_Read(char Address,char *Data,char Num);char i2csendbyte(char byte);char i2cgetbyte(void);char i2cgetack(void);void i2csendack(void);void i2cdelay(char delay);void i2cstart(void);void i2cstop(void);void i2cclock(void);char i2creadbit(void);
//*************************************************************************// I2C_Send//// Inputs:// char Address - Address to write data to// char *Data - Pointer to buffer// char Num - Number of bytes to send//*************************************************************************
char I2C_Send(char Address,char *Data,char Num){ i2cstart();
//-- Send Address i2csendbyte(Address & 0xFE); //-- Lowest bit = 0 => WRITE
if(!i2cgetack()) { i2cstop(); return(0); }
while(Num--) { i2csendbyte(*Data); if(!i2cgetack()) { i2cstop(); return(0); } Data++; }
i2cstop(); return(1);}//************** END OF I2C_Send
//*************************************************************************//
char I2C_Read(char Address,char *data, char Num)//*************************************************************************
char I2C_Read(char Address,char *Data, char Num){ i2cstart();
//-- Send Address i2csendbyte(Address 0x01); //-- Lowest bit = 1 => READ
if(!i2cgetack()) { i2cstop(); return(0); }
while(Num--) { *Data=i2cgetbyte(); Data++;
if(Num > 0) { i2csendack(); } } i2cstop(); return(1);
}
//*************************************************************************// i2csendbyte//*************************************************************************
char i2csendbyte(char Byte){ char count; SDA=I2CLOW; SCL=I2CLOW;
i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time
for(count=8;count>0;count--) //-- Send 8 bits of data { if( (Byte & 0x80)== 0) //-- Get the Bit { SDA=I2CLOW;
//-- Ensure Port pin is low SDA_TRIS=I2CLOW; //-- Lower pin if bit = 0 }
else { SDA_TRIS=I2CHIGH; //-- Release pin //if bit = 1 } Byte=Byte<<1;>
//-- Pulse the clock } SDA_TRIS=I2CHIGH; //-- Release data pin for ACK return(1);}//************** END OF i2csendbyte //*************************************************************************// char i2cgetbyte(void)//// Reads in a byte from the I2C Port//*************************************************************************
char i2cgetbyte(void){ char count,Byte=0;
SDA=I2CLOW; SCL=I2CLOW; i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time for(count=8;count>0;count--)
//-- Read 8 bits of data
{ Byte=Byte <<1; sda_tris="I2CHIGH;">
void i2cstart(void){ //-- Ensure pins are in high impedance mode -- SDA_TRIS=I2CHIGH; SCL_TRIS=I2CHIGH; SCL=I2CLOW; SDA=I2CLOW;
i2cdelay(I2CSTARTDELAY); //-- Generate the start condition SDA_TRIS=I2CLOW; SDA=I2CLOW; i2cdelay(I2CSTARTDELAY); SCL_TRIS=I2CLOW;
i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time }//************** END OF i2cstart //*************************************************************************// i2cstop//*************************************************************************
void i2cstop(void){ //-- Generate Stop Condition -- SDA_TRIS=I2CLOW; SCL_TRIS=I2CHIGH; i2cdelay(I2CSTOPDELAY); SDA_TRIS=I2CHIGH; }//************** END OF i2cstop //*************************************************************************// i2cclock//*************************************************************************
void i2cclock(void){ i2cdelay(I2CDATASETTLE); //-- Minimum Clock Low Time SCL_TRIS=I2CHIGH; //-- Release clock
i2cdelay(I2CCLOCKHIGH); //-- Minimum Clock High Time SCL_TRIS=I2CLOW; //-- Lower the clock
i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time}//************** END OF i2cclock //*************************************************************************// i2creadbit//*************************************************************************
char i2creadbit(void){ char Data=0;
i2cdelay(I2CDATASETTLE); //-- Minimum Clock Low Time SCL_TRIS=I2CHIGH; //-- Release clock
i2cdelay(I2CHALFCLOCK); //-- 1/2 Minimum Clock High Time if(SDA !=0 ) Data=1; //-- READ in the data bit
i2cdelay(I2CHALFCLOCK); //-- 1/2 Minimum Clock High Time SCL_TRIS=I2CLOW; //-- Lower the clock i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time return(Data);}//************** END OF i2cclock //*************************************************************************// i2cgetack//*************************************************************************
char i2cgetack(void){ SDA=I2CLOW; SCL=I2CLOW; SCL_TRIS=I2CLOW; //-- Ensure clock is low SDA_TRIS=I2CHIGH; //-- Release the Data pin so slave can ACK SCL_TRIS=I2CHIGH; //-- raise the clock pin
i2cdelay(I2CHALFCLOCK); //-- wait for 1/2 the clock pulse if(SDA) //-- sample the ACK signal { return(0); //-- No ACK so return BAD } i2cdelay(I2CHALFCLOCK); //-- Else wait for rest of clock SCL_TRIS=I2CLOW; //-- Finish the clock pulse i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time
return(1);}//************** END OF i2cgetack //*************************************************************************// void i2csendack(void)
//*************************************************************************
void i2csendack(void){ //--- Send Ack to slave except for last time --- SDA=0; SDA_TRIS=I2CLOW; //-- Send ACK i2cdelay(I2CDATASETTLE); //-- Give it time to settle i2cclock(); //-- Pulse the clock SDA_TRIS=I2CHIGH; //-- Release ACK i2cdelay(I2CDATASETTLE); //-- Gap between next byte}//************** END OF i2csendack //*************************************************************************// i2cdelay//// This delay is approx us plus the function call delays// Should be close enough for I2C//*************************************************************************
void i2cdelay(const char delay){ DelayUs(delay);// DelayMs(delay); //-- For Debug}//************** END OF i2cdelay 

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

No comments:

Post a Comment