You are on page 1of 13

NG H THI GIAN THC DS1307 V PIC

16F877A
in T Chia S13:24:00
A+A- Print Email

.
Tham kho thm: Hng dn - IC thi gian thc DS1307
Chng trnh thc hin giao tip I2C gia PIC 16F877A v IC DS1307 ci t thi gian, c thi
gian t DS1307, hin th ln LCD, truyn qua RS232.
Vi LCD, chng trnh s c d liu DS1307 v cp nht LCD lin tc, cn khi truyn ln my tnh
s da vo ngt RB0 a vo t xung 1Hz ca DS1307, tc l mi 1s s truyn d liu 1 ln.
Trong chng trnh c s dng cc th vin: lcd_lib_4bit.c, ds1307.c.
S nguyn l m phng trn Proteus:

Truyn ln hyper terminal:

M ngun chng trnh chnh:


#include "16f877a.h"
#include "def_877a.h"
#device *=16 ADC=10
#use delay(clock=20000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD,
NOWRT
#use i2c(Master, sda = PIN_C4, scl=PIN_C3)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include "lcd_lib_4bit.c"

#include "ds1307.c"
#define Slave_add 0x68
#define Read 1
#define Write 0
void send(int8 a);
int8 sec,min,hrs,day,month,yr,dow;
//ngat o chan RB0: Truyen len cong RS232
#int_EXT
void EXT_isr(void) //moi 1s truyen len may tinh 1 lan
{
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
send(hrs);
putc(45);
send(min);
putc(45);
send(sec);
putc(10);
return;
}
void main()
{
enable_interrupts(INT_EXT);//cho phep ngat RB0
ext_int_edge(0,H_TO_L);//dat suon ngat
enable_interrupts(GLOBAL);//cho phep ngat toan cuc
LCD_init(); //Khoi tao LCD.
delay_ms(10);
ds1307_init();// khoi tao DS1307, tao xung 1Hz o chan 7 DS1307.
// Set date : 12-4-2012
// Set time : thu 5 - 12 gio, 59 pht 10 giy
ds1307_set_date_time(12,4,12,5,12,59,10);
while(1)
{
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
//Truyen len LCD
//o day chi hien gio, phut, giay. cac thong tin khac thuc hien tuong tu.
LCD_PutCmd(0x80);
LCD_PutChar(hrs/10+48);
LCD_PutChar(hrs%10+48);

LCD_PutChar(45);
LCD_PutChar(min/10+48);
LCD_PutChar(min%10+48);
LCD_PutChar(45);
LCD_PutChar(sec/10+48);
LCD_PutChar(sec%10+48);
}
}
void send(int8 a)
{
if(a<10)
{
putc(a+48);
}
if(a>9&&a<100)
{
unsigned char c=a/10;
unsigned char d=a%10;
putc(c+48);
putc(d+48);
}
if(a>99)
{
unsigned char t=a/100;
unsigned char c=a/10-10*t;
unsigned char d=a%10;
putc(t+48);
putc(c+48);
putc(d+48);
}
}

Th vin lcd_lib_4bit.c:
#include <stddef.h>
#define LCD_RS
//#define LCD_RW
#define LCD_EN

PIN_D2
PIN_A1
PIN_D3

#define LCD_D4
#define LCD_D5
#define LCD_D6
#define LCD_D7

PIN_D4
PIN_D5
PIN_D6
PIN_D7

// misc display defines-

#define Line_1
#define Line_2
#define Clear_Scr

0x80
0xC0
0x01

// prototype statements
#separate void LCD_Init ( void );// ham khoi tao LCD
#separate void LCD_SetPosition ( unsigned int cX );//Thiet lap vi tri con tro
#separate void LCD_PutChar ( unsigned int cX );// Ham viet1kitu/1chuoi len LCD
#separate void LCD_PutCmd ( unsigned int cX) ;// Ham gui lenh len LCD
#separate void LCD_PulseEnable ( void );// Xung kich hoat
#separate void LCD_SetData ( unsigned int cX );// Dat du lieu len chan Data
// D/n Cong
#use standard_io (C)
#use standard_io (D)
//khoi tao LCD**********************************************
#separate void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
delay_ms(200);
/* wait enough time after Vdd rise >> 15ms */
output_low ( LCD_RS );// che do gui lenh
LCD_SetData ( 0x03 ); /* init with specific nibbles to start 4-bit mode */
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); /* set 4-bit interface */
LCD_PulseEnable();
/* send dual nibbles hereafter, MSN first */
LCD_PutCmd ( 0x2C ); /* function set (all lines, 5x7 characters) */
LCD_PutCmd ( 0x0C ); /* display ON, cursor off, no blink */
LCD_PutCmd ( 0x06 ); /* entry mode set, increment & scroll left */
LCD_PutCmd ( 0x01 ); /* clear display */
}
#separate void LCD_SetPosition ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}
#separate void LCD_PutChar ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
output_high ( LCD_RS );
LCD_PutCmd( cX );
output_low ( LCD_RS );

}
#separate void LCD_PutCmd ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) ); /* send high nibble */
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */
LCD_PulseEnable();
}
#separate void LCD_PulseEnable ( void )
{
output_high ( LCD_EN );
delay_us ( 3 );
// was 10
output_low ( LCD_EN );
delay_ms ( 3 );
// was 5
}
#separate void LCD_SetData ( unsigned int cX )
{
output_bit ( LCD_D4, cX & 0x01 );
output_bit ( LCD_D5, cX & 0x02 );
output_bit ( LCD_D6, cX & 0x04 );
output_bit ( LCD_D7, cX & 0x08 );
}

Th vin ds1307.c:
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);
void ds1307_init(void)
{
BYTE initsec = 0;
BYTE initmin=0;
BYTE inithr=0;
BYTE initdow=0;
BYTE initday=0;
BYTE initmth=0;
BYTE inityear=0;
i2c_start();
i2c_write(0xD0);
// WR to RTC
i2c_write(0x00);
// REG 0
i2c_start();
i2c_write(0xD1);
// RD from RTC
initsec = bcd2bin(i2c_read() & 0x7f);
initmin = bcd2bin(i2c_read() & 0x7f);

inithr = bcd2bin(i2c_read() & 0x3f);


initdow = bcd2bin(i2c_read() & 0x7f); // REG 3
initday = bcd2bin(i2c_read() & 0x3f); // REG 4
initmth = bcd2bin(i2c_read() & 0x1f); // REG 5
inityear = bcd2bin(i2c_read(0));
// REG 6
i2c_stop();
delay_us(3);
i2c_start();
i2c_write(0xD0);
// WR to RTC
i2c_write(0x00);
// REG 0
i2c_write(bin2bcd(initsec));
// Start oscillator with current "seconds value
i2c_write(bin2bcd(initmin));
// REG 1
i2c_write(bin2bcd(inithr));
// REG 2
i2c_write(bin2bcd(initdow));
// REG 3
i2c_write(bin2bcd(initday));
// REG 4
i2c_write(bin2bcd(initmth));
// REG 5
i2c_write(bin2bcd(inityear)); // REG 6
i2c_start();
i2c_write(0xD0);
// WR to RTC
i2c_write(0x07);
// Control Register
i2c_write(0x90);
// squarewave output pin 1Hz
i2c_stop();
}
void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min,
BYTE sec)
{
sec &= 0x7F;
hr &= 0x3F;
i2c_start();
i2c_write(0xD0);
// I2C write address
i2c_write(0x00);
// Start at REG 0 - Seconds
i2c_write(bin2bcd(sec));
// REG 0
i2c_write(bin2bcd(min));
// REG 1
i2c_write(bin2bcd(hr));
// REG 2
i2c_write(bin2bcd(dow));
// REG 3
i2c_write(bin2bcd(day));
// REG 4
i2c_write(bin2bcd(mth));
// REG 5
i2c_write(bin2bcd(year)); // REG 6
i2c_write(0x90);
// REG 7 - 1Hz squarewave output pin
i2c_stop();
}
void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{

i2c_start();
i2c_write(0xD0);
i2c_write(0x03);
// Start at REG 3 - Day of week
i2c_start();
i2c_write(0xD1);
dow = bcd2bin(i2c_read() & 0x7f); // REG 3
day = bcd2bin(i2c_read() & 0x3f); // REG 4
mth = bcd2bin(i2c_read() & 0x1f); // REG 5
year = bcd2bin(i2c_read(0));
// REG 6
i2c_stop();
}
void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
// Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);
sec = bcd2bin(i2c_read() & 0x7f);
min = bcd2bin(i2c_read() & 0x7f);
hr = bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();
}
BYTE bin2bcd(BYTE binary_value)
{
BYTE temp;
BYTE retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}

}
return(retval);
}
// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
BYTE temp;
temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits for the upper digit.
temp &= 0x78;
// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}

Ni dung cn khi to hin th ln LCD ban u:


Hng 1 LCD: SATURDAY, 21-06-2008
Hng 1 LCD: 02:25:00 AM
(Tc c ngha l thi im hin ti ban u s c ci t l nh vy (bng nt nhn ngt ngoi RB0 trn
mch), sau khi set xong thi gian bt u m, sau nu bn mun xem gi trn ng h lc ny l bao
nhiu th bt ngun cho vdk chy (gi l bt ng h), khng mun xem na th tt ngun vdk (gi l tt
ng h), bn s thy l thi gian ti bt c lc no chng ta bt ng h ln u chnh xc nh ng h
tht vy !
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock = 20000000)
#fuses HS, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOPROTECT
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3, force_hw)
#include <lcd.c>
int8 second, minute, hour, date, day, month, year;
int16 year1;
int i;
/*------------ Chuyn d liu m BIN ca MASTER -> d liu m BCD cho DS1307---------*/
int write(int data) // MASTER -> DS1307.
{ // x -> y.
int x,y; //vd: 7 -> 7 = 0x07.
x = data; //vd: 12 -> 18 = 0x12.
if(x<10)
{

y = x;
}
else if(x>=10)
{
y = (x/10 * 6) + x; //vd: 29 -> 41 = 0x29.
}
return(y); //vd: 35 -> 53 = 0x35.
}

/*------------- Chuyn d liu m BCD ca DS1307 -> d liu m BIN cho MASTER--------*/
int read(int data)
{ // MASTER <- DS1307.
int x,y,z; // x <- y.
y = data; //vd: 5 <- 5 = 0x05.
i=0; //vd: 10 <- 16 = 0x10.
if(y<10) //vd: 20 <- 32 = 0x20.
{ //vd: 30 <- 48 = 0x30.
x = y; //vd: 40 <- 64 = 0x40.
z = x; //vd: 50 <- 80 = 0x50.
} //.....
else if(y>=10)
{
do {
x = y - (6 * i);
z = (x/10 * 6) + x;
i++;
}
while(z!=y);
}
return(x);
}
#INT_EXT
void khoitao()
{
/*--------- khoi tao hien thi ban dau : SAT, 21-06-2008, 02:25:00 AM --------*/
second = 0; //giay: 00.
minute = 25; //phut: 25.
hour = 2; //gio: 02 (che do 24h).
day = 6; //thu 7: SAT (SATUDAY).
date = 21; //ngay: 21.
month = 6; //thang: 06.
year = 8; //nam: 08.
i2c_start();
i2c_write(0xD0); //den dia chi ds1307.
i2c_write(0x00); //den dia chi thanh ghi 00H.
i2c_write(write(second));
i2c_write(write(minute));
i2c_write(write(hour));
i2c_write(write(day));
i2c_write(write(date));
i2c_write(write(month));
i2c_write(write(year));
i2c_start();
i2c_write(0xD0);
i2c_write(0x07); //den thanh ghi dieu khien.

i2c_write(0x10); //tao xung vuong 1Hz.


i2c_stop();
}
void update_time()
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_start();
i2c_write(0xD1);
second = read(i2c_read());
minute = read(i2c_read());
hour = read(i2c_read());
day = read(i2c_read());
date = read(i2c_read());
month = read(i2c_read());
year = read(i2c_read(0));
i2c_stop();
}
void hienthi_LCD()
{
/*--------------- Hng 1 cua LCD : hien thi thu, ngay - thang - nam ------------*/
lcd_gotoxy(1,1);
//printf(lcd_putc,"%s",day); //thu trong tuan.
if(day==1) lcd_putc("Mon");
else if(day==2) lcd_putc("Tue");
else if(day==3) lcd_putc("Wed");
else if(day==4) lcd_putc("Thu");
else if(day==5) lcd_putc("Fri");
else if(day==6) lcd_putc("Sat");
else if(day==7) lcd_putc("Sun");
lcd_gotoxy(4,1);
lcd_putc(".");
lcd_gotoxy(6,1);
if(date<10)
{
lcd_putc("0");
lcd_gotoxy(7,1);
printf(lcd_putc,"%d",date); //ngay trong thang.
}
else if(date>=10)
{
printf(lcd_putc,"%d",date);
}
lcd_gotoxy(8,1);
lcd_putc("-");
lcd_gotoxy(9,1);
//printf(lcd_putc,"%s",month); //thang trong nam.
if(month==1) lcd_putc("Jan");
else if(month==2) lcd_putc("Feb");

else
else
else
else
else
else
else
else
else
else

if(month==3) lcd_putc("Mar");
if(month==4) lcd_putc("Apr");
if(month==5) lcd_putc("May");
if(month==6) lcd_putc("Jun");
if(month==7) lcd_putc("Jul");
if(month==8) lcd_putc("Aug");
if(month==9) lcd_putc("Sep");
if(month==10) lcd_putc("Oct");
if(month==11) lcd_putc("Nov");
if(month==12) lcd_putc("Dec");

lcd_gotoxy(12,1);
lcd_putc("-");
lcd_gotoxy(13,1); //nam.
year1 = 2000 + year;
printf(lcd_putc,"%ld",year1);

/*--------------- Hng 2 cua LCD : hien thi gio : phut : giay ,AM/PM ------------*/
lcd_gotoxy(6,2); //gio.
if(hour<10)
{
lcd_putc("0");
lcd_gotoxy(7,2);
printf(lcd_putc,"%d",hour);
}
else if(hour>=10)
{
printf(lcd_putc,"%d",hour);
}
lcd_gotoxy(8,2);
lcd_putc(":");
lcd_gotoxy(9,2); //phut.
if(minute<10)
{
lcd_putc("0");
lcd_gotoxy(10,2);
printf(lcd_putc,"%d",minute);
}
else if(minute>=10)
{
printf(lcd_putc,"%d",minute);
}
lcd_gotoxy(11,2);
lcd_putc(":");
lcd_gotoxy(12,2); //giay.
if(second<10)
{
lcd_putc("0");
lcd_gotoxy(13,2);
printf(lcd_putc,"%d",second);
}

else if(second>=10)
{
printf(lcd_putc,"%d",second);
}
lcd_gotoxy(15,2);
lcd_putc("AM");
}
void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
enable_interrupts(INT_RB);
ext_int_edge(H_to_L);
lcd_init();
delay_ms(10);
while(TRUE)
{
update_time();
hienthi_LCD();
}
}

You might also like