Hello,
i try to interface one DS1302 (real time clock) with one PIC 16F877A.
i have try different way, but each time i got the same bug.
The digits show 0 - 1 - 0 - 3 - 0 - 1 - 0 - 7 - 0 - 1 instead 0-1-2-3-...-8-9.
I try to find a solution by 1 week... i'm going crazy..
Here it's my code (with LCD):
I hope the problem come from the clock read routine..
Thanks for your help.
i try to interface one DS1302 (real time clock) with one PIC 16F877A.
i have try different way, but each time i got the same bug.
The digits show 0 - 1 - 0 - 3 - 0 - 1 - 0 - 7 - 0 - 1 instead 0-1-2-3-...-8-9.
I try to find a solution by 1 week... i'm going crazy..
Here it's my code (with LCD):
Code:
#include <pic.h>
#include <htc.h>
#include <stdlib.h>
//__CONFIG(XT&WDTDIS&LVPDIS);
__CONFIG(0x1832);
void lcd_line1(void); //function prototypes
void lcd_line2(void);
void init(); //I/O init
void lcd_init(); //LCD init
void write(char x); //display one byte
void lcd_enable(); //LCD display setting.
void delay(void);
void clk_write(unsigned char);
unsigned char clk_read(void);
void clkburst(void);
void datafix(void);
#define RS RA1
#define RW RA2
#define E RA3
#define RST RB5
#define DATA RB4
#define SCLK RB0
#define DATA_Tris TRISB4
char number[16] = " : : ";
char daydate[16] = " : :20 ";
char sec[] = " ";
void main(void)
{
char x;
unsigned char a,b;
a=0;
number[2] = number[5] = 0x3a;
daydate[2] = daydate[5] = 0x3a;
daydate[6] = 0x32;
daydate[7] = 0x30;
TRISB = 0;
TRISD = 0;
RST = 0; //1302 reset low
SCLK = 0; //1302 clock low
RW = 0; //set lcd R/W low
E = 0; //set lcd E low
delay();
init(); //I/O init
lcd_init(); //LCD init
while(1)
{
RST = 1; //read hours
clk_write(0xbf); //burst read
sec[0] = clk_read(); //sec
sec[1] = clk_read(); //min
sec[2] = clk_read(); //hour
sec[3] = clk_read(); //date
sec[4] = clk_read(); //month
sec[5] = clk_read(); //day
sec[6] = clk_read(); //year
sec[7] = clk_read(); //control
RST = 0;
datafix(); //convert for display
PORTD=0x02; //clr screen
lcd_enable();
lcd_line1(); //display company's website
PORTD=0xC0; //set the 2nd line display address
lcd_enable(); //LCD display setting.
lcd_line2(); //display company's tel number.
}
}
void datafix(void)
{
char temp,x;
char *foo = sec;
char bleh[] = " ";
for(x=0;x<14;x+=2)
{
temp = *foo;
temp &+ 0xf0;
temp >>= 4;
bleh[x] = temp + 0x30;
temp = *foo;
temp &= 0x0f;
bleh[x+1] = temp + 0x30;
foo++;
}
number[10]=bleh[0]; //sec
number[11]=bleh[1];
number[7]=bleh[2]; //min
number[8]=bleh[3];
number[4]=bleh[4]; //hour
number[5]=bleh[5];
daydate[6]=bleh[6]; //day
daydate[7]=bleh[7];
daydate[3]=bleh[8]; //month
daydate[4]=bleh[9];
daydate[11]=bleh[12]; //year
daydate[12]=bleh[13];
}
void clk_write(unsigned char dat)
{
char x;
for(x=0;x<8;x++)
{
if(dat & 0x01) //put bit on data pin
{
DATA = 1;
}
else DATA = 0;
SCLK = 1; //toggle clock to latch bit
SCLK = 0;
dat >>= 1; //move next bit into place
}
}
unsigned char clk_read(void)
{
char x;
unsigned char dat,tmpdat;
dat = 0;
DATA_Tris = 1; //make DATA input
for(x=0;x<8;x++)
{
if(DATA) //read a bit
{
tmpdat |= 1;
} else {
tmpdat |= 0;
}
tmpdat <<= 7;
dat >>= 1;
dat |= tmpdat;
SCLK = 1; //toggle clock to latch bit
SCLK = 0;
}
DATA_Tris = 0;
return(dat);
}
void lcd_16number(int num)
{
number[0]=(char)(abs(num/10000)+0x30);
num=num-abs(num/10000)*10000;
number[1]=(char)(abs(num/1000)+0x30);
num=num-abs(num/1000)*1000;
number[2]=(char)(abs(num/100)+0x30);
num=num-abs(num/100)*100;
number[3]=(char)(abs(num/10)+0x30);
num=num-abs(num/10)*10;
number[4]=(char)(num+0x30);
}
//---------------------------------------
//I/O init
void init()
{
ADCON1=0x07; //a port as ordinary i/o.
TRISA=0x00; //a port as output.
TRISD=0x00; //d port as output.
return;
}
//---------------------------------------
//LCD init
void lcd_init()
{
PORTD=0x01; //clr screen
lcd_enable();
PORTD=0x38; //8 bits 2 lines 5*7 mode.
lcd_enable();
PORTD=0x0C; //display on,cursor on,blink on.
lcd_enable();
PORTD=0x06; //character not move,cursor rotate right.
lcd_enable();
PORTD=0x80; //¡
lcd_enable();
return;
}
//--------------------------------------
//write a byte to lcd.
void write(char x)
{
PORTD=x; //data send to PORTD
RS = 1; //is data not command
RW = 0; //is write not read
E = 0; //pull low enable signal
delay(); //for a while
E = 1; //pull high to build the rising edge.
return;
}
//--------------------------------------
//lcd display setting
void lcd_enable()
{
RS=0; //is command not data
RW=0; //is write not read.
E=0; //pull low enable signal.
delay(); //for a while.
E=1; //pull high to build the rising edge
return;
}
void lcd_line1()
{
int i;
for(i=0;i<16;++i) //total 16 bytes to display.
{
write(number[i]); //search table to display
}
return;
}
void lcd_line2()
{
int i;
for(i=0;i<16;++i) //total 16 bytes to display.
{
write(daydate[i]); //search table to display
}
return;
}
void delay(void)
{
long int y;
for(y=0;y<100;y++){}
}
I hope the problem come from the clock read routine..
Code:
unsigned char clk_read(void)
{
char x;
unsigned char dat,tmpdat;
dat = 0;
DATA_Tris = 1; //make DATA input
for(x=0;x<8;x++)
{
if(DATA) //read a bit
{
tmpdat |= 1;
} else {
tmpdat |= 0;
}
tmpdat <<= 7;
dat >>= 1;
dat |= tmpdat;
SCLK = 1; //toggle clock to latch bit
SCLK = 0;
}
DATA_Tris = 0;
return(dat);
}
Thanks for your help.