hitech
Hi I am using HitechC .and i am using PIC16F877A.
I want to make a digital clock.
this is the code given below.
when compiled there is no error,but its not displaying time and date.
#include<htc.h>
void _nop_(void);
#define delay_us _nop_(); //generates 1 microsecond
#define LCD PORTD
#define RS RA2 //connect p0.0 to rs pin of lcd
#define EN RA0 //connect p0.1 to en pin of lcd
#define RW RA1
#define SCK RC3 //serial clock pin
#define SDA RC4 //serial data pin
#define SCKHIGH SCK=1
#define SCKLOW SCK=0
#define SDAHIGH SDA=1
#define SDALOW SDA=0
void integer_lcd(int);
void init_lcd(void);
void cmd_lcd(unsigned char);
void write_lcd(unsigned char);
void display_lcd(unsigned char *s);
void delay_ms(unsigned int);
void start(void);
void stop(void);
void send_byte(unsigned char);
unsigned char receive_byte(unsigned char);
void write_i2c(unsigned char,unsigned char,unsigned char);
unsigned char read_i2c(unsigned char,unsigned char);
//clock[]={seconds,minutes,hours,day_of_week,date,month,year}
unsigned char clock[] = {0x00,0x40,0x17,0x01,0x18,0x12,0x06};
const unsigned char *s[] = {"SUN","MON","TUE","WED","THU","FRI","SAT"};
unsigned char slave_ack,add=0,c,k;
unsigned int num;
// Real Time Clock Mode
void main(void)
{
const unsigned char *temp;
ADCON1=0x06;
init_lcd();
cmd_lcd(0x01);
//display_lcd("UTL");
//delay_ms(1000);
TRISA=0;
TRISD=0;
TRISC=0xFF;
start();
while(add<=6) //update real time clock
{
write_i2c(0xd0,add,clock[add]);
add++;
}
stop();
while(1)
{
c=read_i2c(0xD0,0x02);//read hours register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd(':');
c=read_i2c(0xD0,0x01);//read minutes register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd(':');
delay_ms(10);
c=read_i2c(0xD0,0x00);//read seconds register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd(' ');
temp=s[read_i2c(0xD0,0x03)];
display_lcd(temp);//read day register and display
cmd_lcd(0xc0);
c=read_i2c(0xD0,0x04);//read date register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd('/');
c=read_i2c(0xD0,0x05);//read month register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
write_lcd('/');
write_lcd('2');
write_lcd('0');
c=read_i2c(0xD0,0x06);//read year register and display on LCD
write_lcd((c/16)+48);
write_lcd((c%16)+48);
delay_ms(100);
cmd_lcd(0x01);
}
}
//starts i2c, if both SCK & SDA are idle
void start(void)
{
if(SCK==0) //check SCK. if SCK busy, return else SCK idle
return;
if(SDA==0) //check SDA. if SDA busy, return else SDA idle
return;
SDALOW; //data low
delay_us;
SCKLOW; //clock low
delay_us;
return;
}
//stops i2c, releasing the bus
void stop(void)
{
SDALOW; //data low
SCKHIGH; //clock high
delay_us;
SDAHIGH; //data high
delay_us;
return;
}
/*void start(void)
{
SCK=0;
SDA=1;
delay_ms(1);
SDA=0;
return;
}
void stop(void)
{
delay_ms(1);
SDA=0;
SCK=1;
delay_ms(1);
SDA=1;
delay_ms(1);
SCK=0;
return;
}*/
//transmits one byte of data to i2c bus
void send_byte(unsigned char c)
{
unsigned mask=0x80;
do //transmits 8 bits
{
if(c&mask) //set data line accordingly(0 or 1)
SDAHIGH; //data high
else
SDALOW;//data low
SCKHIGH; //clock high
delay_us;
SCKLOW; //clock low
delay_us;
mask/=2; //shift mask
}while(mask>0);
SDAHIGH; //release data line for acknowledge
SCKHIGH ; //send clock for acknowledge
delay_us;
slave_ack=SDA; //read data pin for acknowledge
SCKLOW ; //clock low
delay_us;
return;
}
//receives one byte of data from i2c bus
unsigned char receive_byte(unsigned char master_ack)
{
unsigned char c=0,mask=0x80;
do //receive 8 bits
{
SCKHIGH ;//clock high
delay_us;
if(SDA==1) //read data
c|=mask; //store data
SCKLOW ; //clock low
delay_us ;
mask/=2; //shift mask
}
while(mask>0);
if(master_ack==1)
SDAHIGH ;//don't acknowledge
else
SDALOW; //acknowledge
SCKHIGH ;//clock high
delay_us;
SCKLOW; //clock low
delay_us;
SDAHIGH ;//data high
return c;
}
//writes one byte of data(c) to slave device(device_id) at given address(location)
void write_i2c(unsigned char device_id,unsigned char location,unsigned char c)
{
do
{
start(); //starts i2c bus
send_byte(device_id); //select slave device
if(slave_ack==1) //if acknowledge not received, stop i2c bus
stop();
}while(slave_ack==1); //loop until acknowledge is received
send_byte(location); //send address location
send_byte(c); //send data to i2c bus
stop(); //stop i2c bus
delay_ms(4);
return;
}
//reads one byte of data(c) from slave device(device_id) at given address(location)
unsigned char read_i2c(unsigned char device_id,unsigned char location)
{
unsigned char c;
do
{
start(); //starts i2c bus
send_byte(device_id); //select slave device
if(slave_ack==1) //if acknowledge not received, stop i2c bus
stop();
}while(slave_ack==1); //loop until acknowledge is received
send_byte(location); //send address location
stop(); //stop i2c bus
start(); //starts i2c bus
send_byte(device_id+1); //select slave device in read mode
c=receive_byte(1); //receive data from i2c bus
stop(); //stop i2c bus
return c;
}
/*display of 16bit(integers) values on LCD
void integer_lcd(int n)
{
unsigned char c[6];
unsigned int i=0;
if(n<0)
{
write_lcd('-');
n=-n;
}
if(n==0)
write_lcd('0');
while(n>0)//Split integer to 2 bytes and send on 8bit line.
{
c[i++]=(n%10)+48;
n/=10;
}
while(i-->=1)
write_lcd(c);
}*/
//initialize lcd
void init_lcd(void)
{
//delay_ms(10); //delay 10 milliseconds
ADCON1=0x06;
TRISA=0;
TRISD=0;
cmd_lcd(0x38); //8 bit initialize, 5x7 character font, 16x2 display
cmd_lcd(0x0E); //lcd on, cursor on
cmd_lcd(0x06); //right shift cursor automatically after each character is displayed
cmd_lcd(0x01); //clear lcd
return;
}
//transmit command or instruction to lcd
void cmd_lcd(unsigned char c)
{
LCD=c;
RS=0;
RW=0;
EN=1;
delay_ms(20);
EN=0;
return;
}
//transmit a character to be displayed on lcd
void write_lcd(unsigned char c)
{
LCD=c;
RS=1;
RW=0;
EN=1;
delay_ms(20);
EN=0;
return;
}
//transmit a string to be displayed on lcd
void display_lcd(unsigned char *s)
{
while(*s)
write_lcd(*s++);
return;
}
//generates delay in milli seconds
void delay_ms(unsigned int i)
{
unsigned int j;
while(i-->0)
{
for(j=0;j<500;j++)
{
;
}
}
return;
}
void _nop_(void)
{
unsigned int i;
for(i=0;i<10;i++)
{
;
}
return;
}
the display which i get on lcd is 00:00:00 SUN 00/00/00
anyone check this out and reply to me immediately.
i think its only reading initial value, but not present value.
help me out???