Đây là code của đồng hồ 6 digit của TMdùng để học tập. Tuy nhiên vì mới học PIC nên chưa hiểu được. Nhất là chổ MAP đó. Các cao thủ giải thích dùm nhé
Code:
/****************************************************************
* Real time Clock DS1307
* Dong ho so su dung DS1307 hien thi tren 6 LED 7-segment hh.mm.ss
* Sofware: Compiler CCS Ver 4.018
* Harware: TMe - EasyPIC: (www.tme.com.vn)
- Pull up PORTD, Pull-down Switches, connect PORTD to Switches
- Switches: T1 - Mode, T2 - set time, T3 - clean status
- DIP Swich SW2 all ON (Enable 7-segment and RTC DS1307)
*****************************************************************/
#include <16F877A.h>
#include <def_877a.h> //file header do nguoi dung dinh nghia
#include <ds1307.c>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=12000000)
byte sec,min,hour;
byte const MAP[10] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//Cathode
byte DIS1,DIS2,DIS3,DIS4,DIS5,DIS6;
byte key,mode;
int1 ampm,blink,blink_sec,blink_min,blink_hour;
int1 on_off;
int16 count;
#bit SW1 = 0x8.0 // D0 - mode
#bit SW2 = 0x8.1 // D1 - set_time
#bit SW3 = 0x8.2 // D2 - Clear_status
void set_blink();
void change_time();
void update_1307();
void keyscan();
void set_sec();
void set_min();
void set_hour();
void clear_status();
void read_time();
void update_time();
void display();
//===============================================
void set_blink()
{
switch (mode)
{
case 1: blink_sec=1; break;
case 2: {blink_min=1;blink_sec=0;} break;
case 3: {blink_hour=1;blink_min=0;} break;
case 4:
{
blink=0;mode = 0;blink_sec=0;
blink_min=0;blink_hour=0;
}
break;
}
}
void change_time(){ //Ham chon che do, giong nhu o dong ho CASIO, nhan 1 lan la phut, 2 lan la gio....
if(mode == 1) {blink_sec=1;set_sec();}
if(mode == 2) {blink_min=1;set_min();}
if(mode == 3) {blink_hour=1;set_hour();}
if(mode == 4)
{
blink=0;mode = 0;
blink_sec=0; blink_min=0; blink_hour=0;
}
}
void update_1307()
{
write_DS1307(0,sec);
write_DS1307(1,min);
bit_set(hour,6);
if (ampm == 0) {bit_clear(hour,5); write_DS1307(2,hour);} // AM
if (ampm == 1) {bit_set (hour,5); write_DS1307(2,hour);} // PM
}
void keyscan() {
RD0=1;RD1=1;RD2=1;RD3=1;
if(SW1 != 1) { key=0;SW1=1;delay_ms(150);}
if(SW2 != 1) { key=1;SW2=1;delay_ms(150);}
if(SW3 != 1) { key=2;SW3=1;delay_ms(150);}
if(key != 5)
{
switch (key)
{
case 0: {mode++;key = 5;blink=1;set_blink();}
break;
case 1: {change_time();key = 5;update_1307();}
break;
case 2: {clear_status();key = 5;}
break;
}
}
}
void set_sec()
{
sec=read_ds1307(0);
if (sec>=0x30) {sec=0; min++; write_ds1307(1,min);}
else sec=0;
write_ds1307(0,sec);
}
void set_min()
{ byte j;
min=read_ds1307(1);
min++;
j=min & 0x0F;
if (j>=0x0A) min=min+0x06;
if (min>=0x60) min=0;
write_ds1307(1,min);
}
void set_hour()
{
hour= hour & 0x1F;
hour++;
if(hour== 0x0a) hour = hour+0x06;
if(hour == 0x13)
{ hour = 0x00;
if (ampm == 0) ampm = 1;
else ampm = 0;
}
}
void clear_status() {
mode=4; set_blink();
}
void read_time()
{
sec = read_DS1307(0);
min = read_DS1307(1);
hour = read_DS1307(2);
update_time();
}
void update_time()
{
ampm = bit_test(hour,5); //test AM PM
if(ampm == 0) {RD4 = 0;RD5=1;} //AM
if(ampm == 1) {RD4 = 1;RD5=0;} // PM
DIS1= sec & 0x0F;
DIS2=(sec & 0xF0)>>4; //convert to BCD SEC
DIS3= min & 0x0F;
DIS4=(min & 0xF0)>>4; //convert to BCD MIN
DIS5= hour & 0x0F;
DIS6=(hour & 0x10)>>4; //convert to BCD HOUR
}
void display() {
TRISB=0x00;TRISA=0x00;
if(blink==0) goto norm;
if(on_off==0) goto led_blink;
norm:
// sec - min - hour
PortB=MAP[DIS1]; RA5=0;//DIS1
delay_ms(1); RA5=1;
PortB=MAP[DIS2]; RA4=0; //DIS2
delay_ms(1); RA4=1;
PortB=MAP[DIS3];output_low(PIN_B7);RA3=0;//DIS3
delay_ms(1); RA3=1;
PortB=MAP[DIS4]; RA2=0;//DIS4
delay_ms(1); RA2=1;
PortB=MAP[DIS5];output_low(PIN_B7); RA1=0;//DIS5
delay_ms(1); RA1=1;
PortB=MAP[DIS6];if (portb==0xC0) RA0=1; else RA0=0;//DIS6
delay_ms(1); RA0=1;//*/
if(count!=0) goto exit;
else
{
count=15;
on_off=0;
}
goto exit;
led_blink:
PortB=MAP[DIS1];
if (blink_sec==1) RA5=1;//DIS1
else RA5=0;
delay_ms(3); RA5=1;
PortB=MAP[DIS2];
if (blink_sec==1) RA4=1;//DIS2
else RA4=0;
delay_ms(3); RA4=1;
PortB=MAP[DIS3];output_low(PIN_B7);
if(blink_min==1) RA3=1;//DIS3
else RA3=0;//DIS3
delay_ms(3); RA3=1;
PortB=MAP[DIS4];
if(blink_min==1) RA2=1;//DIS4
else RA2=0;//DIS4
delay_ms(3); RA2=1;
PortB=MAP[DIS5];output_low(PIN_B7);
if(blink_hour==1) RA1=1;//DIS5
else RA1=0;//DIS5
delay_ms(3); RA1=1;
PortB=MAP[DIS6];
if(blink_hour==1) RA0=1;//DIS6
else {if (portb==0xC0) RA0=1; else RA0=0;}//DIS6
delay_ms(3); RA0=1;//*/
if(count==0) {count=15;on_off=1;}
exit:
count--;
}
void main() {
byte u;
Delay_ms(5);
Trisd = 0x0F;
Trisb = 0x00;//output
Trisa = 0x00;
RD4=1;RD5=1;
init_ds1307();
u=read_ds1307(0);
sec=u & 0x7F;// enable RTC
write_ds1307(0,sec);// set second to 00 and enable clock(bit7=0)
//Xoa tat ca cac co dieu khien
key=5;mode=0;blink=0;
blink_sec=0;blink_min=0;blink_hour=0;
count=15;on_off=1;
ampm = bit_test(hour,5);// test AM_PM
if(ampm==0) {RD4 = 0;RD5=1;} //LED AM
if(ampm==1) {RD4 = 1;RD5=0;} //LED PM
while(true)
{
read_time();
display();
keyscan();
}
}//end of main program