Setting time
- Press and hold MODE button until the digits blink
- The blinking digits are the hour is being set
- Press SET button to count up the hour
- When get the right hour, press MODE button to confirm hour setting
- Now the minute digits are blinking and ready to be set
- Press SET button to count up the minute
- When get the right minute, press MODE button to confirm minute setting and the second will be set to 0 automatically
- Now, the clock is set and the clock is running
Have fun!!!
Next improvements:
1. Using DS1307 as the time base will improve the clock accuracy and backup battery is also a nice feature of the DS1307
2. Dot matrix will be scanned and updated via interrupt routine to give the PIC more free time for doing something else
== Updated on 29 Nov 2009 ===
This firmware is written for The 5x7 Dot matrix Cathode Row. If you use Anode Row you have to make change to make_dotmatrix() by inverting the output PORTB and PORTD
===========================
//One 5x7 Led Dot Matrix Clock
// PIC16F887
// I will use DS1307 as the RTC for the next improvement
// punkky@gmail.com
// 26 Sep 2008
#define MYMODE PORTA.F0
#define SET PORTA.F1
//External OSC 32.768KHz
#define HTMR1 0x80
#define LTMR1 0x00
//Constants for 4MHz Internal Clock
#define PAUSE_TIME 40
#define SCROLL_TIME_DELAY 60
#define HM_PAUSE_TIME 8
#define DTime 200
//Cursor Positions
#define HR_H_POS 0
#define HR_L_POS 0
#define DOT_1_POS 32
#define MIN_H_POS 12
#define MIN_L_POS 12
#define DOT_2_POS 56
#define SEC_H_POS 64
#define SEC_L_POS 72
//5x7 font
//Vertical scan , Little endian order
const unsigned char char2[][4]={
{0x1F,0x11,0x1F,0x00}, //0
{0x09,0x1F,0x01,0x00},
{0x17,0x15,0x1D,0x00},
{0x11,0x15,0x1F,0x00},
{0x1C,0x04,0x1F,0x00},
{0x1D,0x15,0x17,0x00},
{0x1F,0x15,0x17,0x00},
{0x10,0x10,0x1F,0x00},
{0x1F,0x15,0x1F,0x00},
{0x1D,0x15,0x1F,0x00}, //9
{0x0E,0x0E,0x0E,0x00}, //Comma1
{0x04,0x0E,0x04,0x00} //Comma2
};
unsigned char output[8];
unsigned char data[40];
unsigned char ptr;
unsigned char base_ptr;
unsigned char result_ptr;
unsigned char pp;
unsigned char pause_cnt;
unsigned char hr_pause_cnt;
unsigned char min_pause_cnt;
unsigned short counter;
unsigned short sec_h;
unsigned short sec_l;
unsigned short min_h;
unsigned short min_l;
unsigned short hr_h;
unsigned short hr_l;
unsigned short tick;
unsigned short num;
unsigned short i;
unsigned short j;
unsigned short time[8];
unsigned short setting_time;
unsigned short change_MYMODE;
void check_bt();
void button_fn(unsigned short param1, unsigned short pos1, unsigned short pos2);
void make_dotmatrix();
void interrupt() { //Internal clock
PIR1.TMR1IF = 0; // clears TMR1IF
TMR1H = HTMR1; //Set only high byte
tick = 1; // increment counter
}
void update_time();
void make_time();
void fill_data();
void show_digit(unsigned short pos);
void scroll();
void pause_digit(unsigned short position,unsigned short pause_delay);
unsigned short shift_register;
void main(){
setting_time = 0;
change_MYMODE = 0;
ANSEL = 0x00; //Digital I/O for PORTA
TRISA = 0x03;
PORTA = 0x03;
TRISB = 0x00;
PORTB = 0xFF;
TRISC = 0x0E;
TRISD = 0x00;
PORTD = 0x00;
ANSELH = 0x00; //Digital Input for PORTB
OSCCON = 0x65 ; //pic16f887 : 0110 0101, Internal Osc at 4MHz for lowest power consumption
counter = 0;
shift_register = 0x01;
hr_h = 1;
hr_l = 2;
min_h = 3;
min_l =4;
sec_h = 0;
sec_l = 0;
tick = 0;
fill_data();
pause_cnt =0;
hr_pause_cnt = 0;
min_pause_cnt = 0;
//TMR1 setup
T1CON = 0x8F; // 887 TMR1 Prescaler 1:1 external clock
INTCON = 0xC0; // Set GIE, PEIE
TMR1H = 0x80;
TMR1L = 0x00;
Delay_ms(10); // Delay for setting up TMR1
PIE1.TMR1IE = 1; // enable interupt
tick =0;
while(1){
scroll();
}
}
void show_digit(unsigned short pos){
for(i=0;i<8;i++){
output[i] = data[i+pos];
}
}
void update_time(){
if(tick){
tick =0;
sec_l++;
make_time();
fill_data();
}
}
void make_time(){
if(sec_l>9){
sec_l = 0;
sec_h++;
}
if(sec_h>5){
sec_h=0;
min_l++;
}
if(min_l>9){
min_l = 0;
if(setting_time == 0){
min_h++;
}
}
if(min_h>5){
min_h = 0;
if(setting_time == 0){
hr_l++;
}
}
if(hr_l>9){
hr_l = 0;
if(setting_time == 0){
hr_h++;
}
}
if(hr_h >2){
hr_h = 0;
}
if(hr_h >=2 && hr_l>3){
if(setting_time == 0){
hr_h = 0;
}
hr_l = 0;
}
}
void fill_data(){
time[0] = hr_h;
time[1] = hr_l;
time[2] = 10;
time[3] = min_h;
time[4] = min_l;
time[5] = 11;
time[6] = sec_h;
time[7] = sec_l;
for(i = 0;i<8;i++){
for(j=0;j<4;j++){
data[j+4*i] = char2[time[i]][j];
}
}
}
void button_fn(unsigned short param1, unsigned short pos1, unsigned short pos2){
for(;;){
if(SET == 0){
Delay_ms(10);
while(SET == 0);
Delay_ms(10);
switch (param1){
case 1: hr_h++; break;
case 2: hr_l++; break;
case 3: min_h++;break;
case 4: min_l++;break;
}
make_time();
fill_data();
show_digit(pos1);
}
if(MYMODE == 0){
Delay_ms(10);
while(MYMODE == 0);
Delay_ms(10);
if( param1 == 4){
setting_time = 0;
ptr = 0;
base_ptr = 0;
}else{
show_digit(pos2);
}
break;
}
make_dotmatrix();
Delay_ms(1);
}
}
void check_bt(){
while(MYMODE == 0){
Delay_ms(10);
for(i=0;i<100;i++){
for(j=0;j<10;j++){
make_dotmatrix();
Delay_ms(1);
if(MYMODE != 0){
setting_time = 0;
change_MYMODE = 1;
break;
}
}
}
while(MYMODE == 0){ // Set Hr high
setting_time = 1;
show_digit(HR_H_POS);
make_dotmatrix();
}
if(change_MYMODE){
ptr=8;
base_ptr = 0;
change_MYMODE = 0;
}
}
if(setting_time){
INTCON.GIE = 0 ; //Stop time counting
button_fn(1, HR_H_POS, HR_L_POS);
button_fn(2, HR_L_POS, MIN_H_POS);
button_fn(3, MIN_H_POS, MIN_L_POS);
button_fn(4, MIN_L_POS, 0);
//Reset timer1
TMR1L = LTMR1;
TMR1H = HTMR1;
INTCON.GIE = 1 ; // start clock
sec_l =0;
sec_h =0;
tick=0;
make_time();
fill_data();
}
}
void pause_digit(unsigned short position, unsigned short pause_delay){
if(base_ptr == position){
if(pause_cnt<pause_delay){
base_ptr--;
pause_cnt++;
}else{
base_ptr = position+1;
pause_cnt=0;
}
}
}
void scroll(){
ptr = 0; //start pointer
base_ptr = 0;
while(base_ptr<41){
result_ptr = (base_ptr+ptr)%40;
output[ptr] = data[result_ptr];
ptr++;
if(ptr == 8){
ptr = 0;
base_ptr++;
//Sec pause
pause_digit(25,PAUSE_TIME);
//Min pause
pause_digit(13,HM_PAUSE_TIME);
//Hr pause
pause_digit(1,HM_PAUSE_TIME);
}
for(pp=0;pp<SCROLL_TIME_DELAY;pp++){
update_time();
make_dotmatrix();
}
update_time();
check_bt();
make_dotmatrix();
}
}
void make_dotmatrix(){
if(counter == 7){
PORTB = output[counter]; //sent font data to PORTB
Delay_us(DTime);
PORTB = 0x00; //Turn off dots
shift_register = 0x01;
PORTD = ~shift_register; //sent scan data to PORTD
counter = 0;
} else{
PORTB = output[counter];
Delay_us(DTime);
PORTB = 0x00; //Turn off dots
shift_register = shift_register << 1;
PORTD = ~shift_register;
counter++;
}
}
// PIC16F887
// I will use DS1307 as the RTC for the next improvement
// punkky@gmail.com
// 26 Sep 2008
#define MYMODE PORTA.F0
#define SET PORTA.F1
//External OSC 32.768KHz
#define HTMR1 0x80
#define LTMR1 0x00
//Constants for 4MHz Internal Clock
#define PAUSE_TIME 40
#define SCROLL_TIME_DELAY 60
#define HM_PAUSE_TIME 8
#define DTime 200
//Cursor Positions
#define HR_H_POS 0
#define HR_L_POS 0
#define DOT_1_POS 32
#define MIN_H_POS 12
#define MIN_L_POS 12
#define DOT_2_POS 56
#define SEC_H_POS 64
#define SEC_L_POS 72
//5x7 font
//Vertical scan , Little endian order
const unsigned char char2[][4]={
{0x1F,0x11,0x1F,0x00}, //0
{0x09,0x1F,0x01,0x00},
{0x17,0x15,0x1D,0x00},
{0x11,0x15,0x1F,0x00},
{0x1C,0x04,0x1F,0x00},
{0x1D,0x15,0x17,0x00},
{0x1F,0x15,0x17,0x00},
{0x10,0x10,0x1F,0x00},
{0x1F,0x15,0x1F,0x00},
{0x1D,0x15,0x1F,0x00}, //9
{0x0E,0x0E,0x0E,0x00}, //Comma1
{0x04,0x0E,0x04,0x00} //Comma2
};
unsigned char output[8];
unsigned char data[40];
unsigned char ptr;
unsigned char base_ptr;
unsigned char result_ptr;
unsigned char pp;
unsigned char pause_cnt;
unsigned char hr_pause_cnt;
unsigned char min_pause_cnt;
unsigned short counter;
unsigned short sec_h;
unsigned short sec_l;
unsigned short min_h;
unsigned short min_l;
unsigned short hr_h;
unsigned short hr_l;
unsigned short tick;
unsigned short num;
unsigned short i;
unsigned short j;
unsigned short time[8];
unsigned short setting_time;
unsigned short change_MYMODE;
void check_bt();
void button_fn(unsigned short param1, unsigned short pos1, unsigned short pos2);
void make_dotmatrix();
void interrupt() { //Internal clock
PIR1.TMR1IF = 0; // clears TMR1IF
TMR1H = HTMR1; //Set only high byte
tick = 1; // increment counter
}
void update_time();
void make_time();
void fill_data();
void show_digit(unsigned short pos);
void scroll();
void pause_digit(unsigned short position,unsigned short pause_delay);
unsigned short shift_register;
void main(){
setting_time = 0;
change_MYMODE = 0;
ANSEL = 0x00; //Digital I/O for PORTA
TRISA = 0x03;
PORTA = 0x03;
TRISB = 0x00;
PORTB = 0xFF;
TRISC = 0x0E;
TRISD = 0x00;
PORTD = 0x00;
ANSELH = 0x00; //Digital Input for PORTB
OSCCON = 0x65 ; //pic16f887 : 0110 0101, Internal Osc at 4MHz for lowest power consumption
counter = 0;
shift_register = 0x01;
hr_h = 1;
hr_l = 2;
min_h = 3;
min_l =4;
sec_h = 0;
sec_l = 0;
tick = 0;
fill_data();
pause_cnt =0;
hr_pause_cnt = 0;
min_pause_cnt = 0;
//TMR1 setup
T1CON = 0x8F; // 887 TMR1 Prescaler 1:1 external clock
INTCON = 0xC0; // Set GIE, PEIE
TMR1H = 0x80;
TMR1L = 0x00;
Delay_ms(10); // Delay for setting up TMR1
PIE1.TMR1IE = 1; // enable interupt
tick =0;
while(1){
scroll();
}
}
void show_digit(unsigned short pos){
for(i=0;i<8;i++){
output[i] = data[i+pos];
}
}
void update_time(){
if(tick){
tick =0;
sec_l++;
make_time();
fill_data();
}
}
void make_time(){
if(sec_l>9){
sec_l = 0;
sec_h++;
}
if(sec_h>5){
sec_h=0;
min_l++;
}
if(min_l>9){
min_l = 0;
if(setting_time == 0){
min_h++;
}
}
if(min_h>5){
min_h = 0;
if(setting_time == 0){
hr_l++;
}
}
if(hr_l>9){
hr_l = 0;
if(setting_time == 0){
hr_h++;
}
}
if(hr_h >2){
hr_h = 0;
}
if(hr_h >=2 && hr_l>3){
if(setting_time == 0){
hr_h = 0;
}
hr_l = 0;
}
}
void fill_data(){
time[0] = hr_h;
time[1] = hr_l;
time[2] = 10;
time[3] = min_h;
time[4] = min_l;
time[5] = 11;
time[6] = sec_h;
time[7] = sec_l;
for(i = 0;i<8;i++){
for(j=0;j<4;j++){
data[j+4*i] = char2[time[i]][j];
}
}
}
void button_fn(unsigned short param1, unsigned short pos1, unsigned short pos2){
for(;;){
if(SET == 0){
Delay_ms(10);
while(SET == 0);
Delay_ms(10);
switch (param1){
case 1: hr_h++; break;
case 2: hr_l++; break;
case 3: min_h++;break;
case 4: min_l++;break;
}
make_time();
fill_data();
show_digit(pos1);
}
if(MYMODE == 0){
Delay_ms(10);
while(MYMODE == 0);
Delay_ms(10);
if( param1 == 4){
setting_time = 0;
ptr = 0;
base_ptr = 0;
}else{
show_digit(pos2);
}
break;
}
make_dotmatrix();
Delay_ms(1);
}
}
void check_bt(){
while(MYMODE == 0){
Delay_ms(10);
for(i=0;i<100;i++){
for(j=0;j<10;j++){
make_dotmatrix();
Delay_ms(1);
if(MYMODE != 0){
setting_time = 0;
change_MYMODE = 1;
break;
}
}
}
while(MYMODE == 0){ // Set Hr high
setting_time = 1;
show_digit(HR_H_POS);
make_dotmatrix();
}
if(change_MYMODE){
ptr=8;
base_ptr = 0;
change_MYMODE = 0;
}
}
if(setting_time){
INTCON.GIE = 0 ; //Stop time counting
button_fn(1, HR_H_POS, HR_L_POS);
button_fn(2, HR_L_POS, MIN_H_POS);
button_fn(3, MIN_H_POS, MIN_L_POS);
button_fn(4, MIN_L_POS, 0);
//Reset timer1
TMR1L = LTMR1;
TMR1H = HTMR1;
INTCON.GIE = 1 ; // start clock
sec_l =0;
sec_h =0;
tick=0;
make_time();
fill_data();
}
}
void pause_digit(unsigned short position, unsigned short pause_delay){
if(base_ptr == position){
if(pause_cnt<pause_delay){
base_ptr--;
pause_cnt++;
}else{
base_ptr = position+1;
pause_cnt=0;
}
}
}
void scroll(){
ptr = 0; //start pointer
base_ptr = 0;
while(base_ptr<41){
result_ptr = (base_ptr+ptr)%40;
output[ptr] = data[result_ptr];
ptr++;
if(ptr == 8){
ptr = 0;
base_ptr++;
//Sec pause
pause_digit(25,PAUSE_TIME);
//Min pause
pause_digit(13,HM_PAUSE_TIME);
//Hr pause
pause_digit(1,HM_PAUSE_TIME);
}
for(pp=0;pp<SCROLL_TIME_DELAY;pp++){
update_time();
make_dotmatrix();
}
update_time();
check_bt();
make_dotmatrix();
}
}
void make_dotmatrix(){
if(counter == 7){
PORTB = output[counter]; //sent font data to PORTB
Delay_us(DTime);
PORTB = 0x00; //Turn off dots
shift_register = 0x01;
PORTD = ~shift_register; //sent scan data to PORTD
counter = 0;
} else{
PORTB = output[counter];
Delay_us(DTime);
PORTB = 0x00; //Turn off dots
shift_register = shift_register << 1;
PORTD = ~shift_register;
counter++;
}
}
2 comments:
I really like your clock , My question is , Can you upgrade it with the DS1307 and sell me a copy of the software , I want to build it, it´s great Thanx in advance
I cant compile a code ช่วยหน่อกับบบบบ ผมมือใหม่ยรแ ส่วนมากผมใช้arduino
48 396 Invalid declarator expected'(' or identifier LTP_305clock.c
131 315 Invalid expression LTP_305clock.c
131 402 ; expected, but 'data' found LTP_305clock.c
131 424 '}' expected ';' found LTP_305clock.c
132 424 '}' expected '}' found LTP_305clock.c
193 396 Invalid declarator expected'(' or identifier LTP_305clock.c
193 310 Constant expression required LTP_305clock.c
193 374 Array dimension must be greater than 0 LTP_305clock.c
194 424 '}' expected '}' found LTP_305clock.c
195 424 '}' expected '}' found LTP_305clock.c
297 315 Invalid expression LTP_305clock.c
297 402 ; expected, but 'data' found LTP_305clock.c
297 424 '}' expected ';' found LTP_305clock.c
313 424 '}' expected '}' found LTP_305clock.c
317 312 Internal error '' LTP_305clock.c
0 102 Finished (with errors): 27 ÁÕ.¤. 2017, 12:40:31 LTP_305clock.mcppi
mikroC v.7.1.0 pic
Post a Comment