What would be the fun in that?Mike so your saying just use that output of 1hz to count and stuff.
If you want to scrap the DS1306, I would just use a 32Khz crystal with the Timer1/oscillator/CCP for my 1 second interrupt.
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
What would be the fun in that?Mike so your saying just use that output of 1hz to count and stuff.
What would be the fun in that?
If you want to scrap the DS1306, I would just use a 32Khz crystal with the Timer1/oscillator/CCP for my 1 second interrupt.
if(setmode & mode < 3) // if set switch and display "on"
{ loadbuffer(); // copy source array to set[] buffer
group = 0; // set starting group (hours/months)
setlimits(); // set lower/upper field limits
while(setmode) // while set switch "on"
{ if(rtarrow) // if rt arrow
{ rtarrow = 0; //
if(group == 2) // bump display group, 0..2
group = 0; //
else //
group++; //
setlimits(); // set lower/upper field limits
} //
while(uplatch) // while up arrow pressed
{ uparrow = 0; // increment display group value
if(set[group] == hilimit)
set[group] = lolimit;
else //
set[group]++; //
delay_ms(220); // delay approx 1/4 sec
if(uplatch) // if still pressed
beepctr = 16; // send repeat 'click'
}
while(dnlatch) // while dn arrow pressed
{ dnarrow = 0; // decrement display group value
if(set[group] == lolimit)
set[group] = hilimit;
else //
set[group]--; //
delay_ms(220); // delay approx 1/4 sec
if(dnlatch) // if still pressed
beepctr = 16; // send repeat 'click'
}
}
intcon.GIE = 0; // suspend interrupts
savebuffer(); // copy set[] buffer to source array
if(mode == 0) // if 'clock' was 'source' then
{ rtcl = 25; // reset RTC counters including
rtch = 0; // set switch debounce time...
}
intcon.GIE = 1; // restart interrupts
}
Hi Eric,
Just wondering why you would read date & time on every 1 second interrupt?
Mike
Mike so your saying just use that output of 1hz to count and stuff.
That would eliminate the whole 2100 year issue and all BCD problems completely. Since i would be writing the code myself. Which means i wouldnt even have to use the RTC SPI lines besides having to program the 1hz to operational. Thats pretty cool idea. I have another 1306 Ill play with that idea on another pic. I have another LCD and some more sn74LS164's so ill be good to make another and try it out.
anyone in there right mind wouls know what year it is also lol but i understand the benefits of using just
12/28/08 (US)
Still having entire code in PIC saves alot of reading to from the Ds1306 and if one can eliminate it period by using a 1hz on a interrupt i dont see the issue. The DS1306 i guess is for ease of use type work to simplify or shorten code for some.
I find the idea of having a 1hz crystal way better than a 1306 altogether. Even tho i have to create the months and days and years my self thats really not a issue. And to remove cost from this clock i should remove the DS1306 completely but i wont since i dont have a 1hz crystal.
Still having entire code in PIC saves alot of reading to from the Ds1306 and if one can eliminate it period by using a 1hz on a interrupt i dont see the issue. The DS1306 i guess is for ease of use type work to simplify or shorten code for some.
I find the idea of having a 1hz crystal way better than a 1306 altogether. Even tho i have to create the months and days and years my self thats really not a issue. And to remove cost from this clock i should remove the DS1306 completely but i wont since i dont have a 1hz crystal.
Edit: Removing the DS1306 also simplifies the Layout of PCB
static unsigned char RTC [] = { 59, 59, 23 }; // secs, mins, hours
static unsigned char TMR [] = { 00, 00, 23 }; // secs, mins, hours
static unsigned char ALM [] = { 59, 59, 23 }; // secs, mins, hours
static unsigned char CAL [] = { 01, 31, 08 }; // month, day, year
const rom unsigned char DTbl [] = { 29, // February (leap yr)
31, // January
28, // February
31, // March
30, // April
31, // May
30, // June
31, // July
31, // August
30, // September
31, // October
30, // November
31 }; // December
#define Month CAL[0]
#define Day CAL[1]
#define Year CAL[2]
#define FebruaryLeap !(Year%4 || Month^2)
/************************************************************
* Bump Real Time Clock and Calendar (ISR excerpt) *
************************************************************/
n = 0; // index seconds array element
while(RTC[n]++ == 59) // while value 59 (post inc value)
RTC(n++) = 0; // set to 00 and bump array index
if(RTC[2] == 24) // change 24:00:00 to 00:00:00
{ RTC[2] = 0; // and bump the Calendar
n = Month; // use Month 1..12 for index
if(FebruaryLeap) // if leap year and february
n = 0; // use 0 for day table index
if(Day++ == DTbl[n]) // if last day of month
{ Day = 1; // set day to 1 and
if(Month++ == 12) // if end of year
{ Month = 1; // set month to january and
Year++; // increment year and
Year %= 100; // keep it in 00..99 range
}
}
}
/************************************************************
* Alarm *
************************************************************/
if(AlarmEnabled) // if Alarm enabled
{ if(RTC[2] == ALM[2]) // if hours match and
if(RTC[1] == ALM[1]) // if minutes match
AlarmFlag = 1; // turn on alarm spkr output
}
/************************************************************
* Count Down Timer / Appliance Timer *
************************************************************/
if(TimerEnabled) // if Count Down Timer enabled
{ n = 0; // index seconds array element
while (!TMR[n]--) // while value 00 (post dec value)
TMR[n++] = 59; // set to 59 and bump array index
if (!(TimerEnabled = TMR[0]||TMR[1]||TMR[2]))
{ // do timed out functions here
} //
}
I must have missed that part You have a tendency to rush from one project to another. At some point soon you need to take the time to get it right. Upgrade you coding skills. I am amazed at how fast you have progressed. Take this as a pointer or concern on my part, not a negative comment.3v0: I am not switching over without solving a issue. The entire clock works fine.
#define Button (PORTA >> 1) & 0x0F;
#define Button_T TRISA
#define setupBtn 0x01
#define downBtn 0x02
#define upBtn 0x04
#define selectBtn 0x08
/******************************************************************************
*
* AtomSoft Clock Using PIC18F248, DS1306, 74LS164, 74LS165
*
******************************************************************************
* FileName: main.c
* Author: Jason Lopez
* Processor: PIC18F248(0)
* Compiler: C18
* Company: AtomSoftTech
* Version: 2.0.0
******************************************************************************/
#include <p18F248.h>
#include <stdio.h>
#include <delays.h>
#include <spi.h>
#pragma config WDT = OFF, LVP = OFF, OSC = HS
/************************************
Prototypes
*************************************/
void main(void);
void initSPI(void);
void e_togg(void);
void lcd_line(char line);
void lcd_cmd(unsigned char letter);
void lcd_char(unsigned char letter);
void lcd_string(char *senpoint);
void lcd_init(void);
void delay_ms(int mS);
void delay_us(int uS);
void delay_s(int S);
void lcdByte(unsigned char dNyb,unsigned char rs);
char RTCRegRead(char adx);
void RTCRegWrite(char adx, char data);
static unsigned char uint2bcd(unsigned char ival);
char readBtn(void);
unsigned char bcd2dec(unsigned char aBCD, char type);
void putDate(char type, char data);
void UpdateTime(void) ;
/************************************
Definitions
************************************/
#define CS LATCbits.LATC2
#define CS_T TRISCbits.TRISC2
#define SCL_T TRISCbits.TRISC3
#define SDA_T TRISCbits.TRISC4
#define SDO_T TRISCbits.TRISC5
#define LCD_DAT_T TRISCbits.TRISC0
#define LCD_CLK_T TRISCbits.TRISC1
#define LCD_DAT LATCbits.LATC0
#define LCD_CLK LATCbits.LATC1
#define LCD_E_T TRISCbits.TRISC6
#define LCD_E LATCbits.LATC6
#define PL LATBbits.LATB0
#define CP2 LATBbits.LATB1
#define SDL PORTBbits.RB2
#define PL_T TRISBbits.TRISB0
#define CP2_T TRISBbits.TRISB1
#define SDL_T TRISBbits.TRISB2
#define Button (PORTA >> 1) & 0x0F;
#define Button_T TRISA
#define setupBtn 0x01
#define downBtn 0x02
#define upBtn 0x04
#define selectBtn 0x08
#define alarmOut LATBbits.LATB3
#define alarmOutT TRISBbits.TRISB3
#define alarmIn TRISBbits.TRISB4
/************************************
Variables
************************************/
char string[] = " ";
char string2[] = " ";
unsigned char lDate[16];
unsigned char myTmp;
//////////////////////////
/* NEW VARs */
//////////////////////////
unsigned char decHour;
unsigned char decMin;
unsigned char decAPM;
unsigned char decDate;
unsigned char decMonth;
unsigned char decYear;
unsigned char time[16];
unsigned char comDate[16];
unsigned char view;
/************************************
Main
************************************/
void main(void) {
ADCON1 = 0x0E;
initSPI();
lcd_init();
SDL_T = 1;
Button_T = 0xFF; //TRISA (all input)
RTCRegWrite(0x8F,0x05);
UpdateTime();
view = 0;
while(1) {
myTmp = Button;
if(myTmp == selectBtn){
if(view == 1){
sprintf(string," AtomSoftTech ",0);
lcd_string(string);
view = 0;
} else {
lcd_string(comDate);
view = 1;
}
UpdateTime();
while(myTmp == selectBtn){myTmp = Button};
}
}
}
/***********************************
RTC Tools
************************************
Convert Char(byte) to BCD
************************************/
unsigned char uint2bcd(unsigned char ival)
{
return ((ival / 10) << 4) | (ival % 10);
}
/************************************
Convert BCD to Char(byte)
************************************/
unsigned char bcd2dec(unsigned char aBCD, char type)
{
char lowNyb = aBCD & 0x0F;
char highNyb = aBCD >> 4;
char MyDec = lowNyb;
char x;
switch(type){
case 0:
highNyb &= 0x0F;
break;
case 1:
highNyb &= 0x01;
break;
case 2:
highNyb &= 0x03;
break;
case 3:
highNyb &= 0x07;
break;
case 4:
highNyb &= 0x00;
break;
}
for(x=0;x<highNyb;x++){
MyDec += 10;
}
return MyDec;
}
/************************************
Read a Register off the DS1306
************************************/
char RTCRegRead(char adx){
char tmp;
CS = 1;
WriteSPI(adx); //sec
tmp = ReadSPI();
CS = 0;
return tmp;
}
/************************************
Write to a Register on the DS1306
************************************/
void RTCRegWrite(char adx, char data){
CS = 1;
WriteSPI((adx | 0x80 ));
WriteSPI(data);
CS = 0;
}
/************************************
Initialize SPI
************************************/
void initSPI(void){
CS_T = 0; //CS is output
SCL_T = 0; //SCL is output
SDA_T = 1; //SDA is input
SDO_T = 0; //SDO is output
OpenSPI(SPI_FOSC_4,MODE_10,SMPEND);
CS = 1;
WriteSPI(0x8F);
WriteSPI(0x00);
CS = 0;
}
/***********************************
LCD Functions
************************************
Send String to LCD
************************************/
void lcd_string(char *senpoint){
delay_ms(1);
while(*senpoint != '\0'){
lcd_char(*senpoint);
senpoint++;
}
}
/************************************
Send Data(Nybble) to LCD
************************************/
void lcdByte(unsigned char dNyb,unsigned char rs){
int i;
LCD_DAT=0; //Clear 74LS164 set initial bit to 0
for(i=0;i<8;i++){ //repeat for 8 bits
LCD_CLK=1;LCD_CLK=0; //write 0's to the 164
}
for(i=0;i<4;i++){ //output the nybble
if((dNyb & 0x08) != 0)
LCD_DAT=1;
else
LCD_DAT=0;
LCD_CLK=1;LCD_CLK=0;
dNyb=dNyb<<1;
}
LCD_DAT = rs; //output the RS bit value
LCD_CLK=1;LCD_CLK=0;
LCD_DAT = 0;
LCD_CLK=1;LCD_CLK=0;
LCD_CLK=1;LCD_CLK=0;
LCD_CLK=1;LCD_CLK=0;
e_togg();
}
/************************************
Toggle E Line
************************************/
void e_togg(void){
LCD_E=1;LCD_E=0;
}
/************************************
Set LCD Line
************************************/
void lcd_line(char line){
if(line == 0x01)
lcd_cmd(0x80);
else
lcd_cmd(0xc0);
}
/************************************
LCD Send Command
************************************/
void lcd_cmd(unsigned char letter){
unsigned char temp;
temp=letter;
temp=temp>>4;
lcdByte(temp,0);
temp=letter;
temp=temp&0x0f;
lcdByte(temp,0);
}
/************************************
LCD Send Character
************************************/
void lcd_char(unsigned char letter){
unsigned char temp;
temp=letter;
temp=temp>>4;
lcdByte(temp,1);
temp=letter;
temp=temp&0x0f;
lcdByte(temp,1);
}
/************************************
LCD Initialization
************************************/
void lcd_init(void){
LCD_E_T = 0;
LCD_CLK_T = 0;
LCD_DAT_T = 0;
lcdByte(0x03,0);
delay_ms(5);
e_togg();
delay_us(160);
e_togg();
delay_us(160);
lcdByte(0x02,0);
delay_us(160);
lcd_cmd(0x28); //set 4-bit mode and 2 lines
delay_us(160);
lcd_cmd(0x10); //cursor move & shift left
delay_us(160);
lcd_cmd(0x06); //entry mode = increment
delay_us(160);
lcd_cmd(0x0d); //display on - cursor blink on
delay_us(160);
lcd_cmd(0x01); //clear display
delay_ms(500);
}
/************************************
Delays (S,mS,uS) for 20Mhz
************************************/
/*********************
Delay Second(s)
**********************/
void delay_s(int S){
int y;
char x;
for(y=0;y<S;y++)
for(x=0;x<4;x++)
delay_ms(250);
}
/************************
Delay MilliSecond(s)
*************************/
void delay_ms(int mS){
int y;
for(y=0;y<mS;y++)
Delay1KTCYx(5);
}
/************************
Delay MicroSeconds
*************************
Lowercase 'u' is common
symbol for Micro
*************************/
void delay_us(int uS){
int y;
char x;
for(y=0;y<uS;y++)
for(x=0;x<5;x++)
Nop();
}
/**********************************
readBtn
***********************************/
char readBtn(void){
return Button;
}
/**********************************
LCD / RTC stuff
***********************************/
void UpdateTime(void) {
unsigned char tmp,tmp2;
char i;
// Fill In the LCD String
time[0] = 'T';
time[1] = 'i';
time[2] = 'm';
time[3] = 'e';
time[4] = ':';
time[5] = ' ';
time[8] = ':';
time[11] = ' ';
time[13] = 'M';
time[14] = ' ';
time[15] = ' ';
// Get Date
comDate[0] = 'D';
comDate[1] = 'a';
comDate[2] = 't';
comDate[3] = 'e';
comDate[4] = ':';
comDate[5] = ' ';
comDate[8] = '/';
comDate[11] = '/';
comDate[14] = ' ';
comDate[15] = ' ';
// Get Minutes
tmp = RTCRegRead(0x01);
time[10] = (tmp & 0x0F) + 0x30;
time[9] = (tmp >> 4) + 0x30;
// Get Hours
tmp = RTCRegRead(0x02);
time[7] = (tmp & 0x0F) + 0x30;
time[6] = ((tmp >> 4) & 0x01 ) + 0x30;
// GET AM or PM (already read register 0x02)
time[12] = ((tmp >> 4) & 0x01 ) + 0x30;
if(time[12] == 0){
time[12]='A';
} else {
time[12]='P';
}
//Get Month
tmp = RTCRegRead(0x05);
comDate[6] = (tmp >> 4) + 0x30 ;
comDate[7] = (tmp & 0x0F) + 0x30 ;
//Get Date(day)
tmp = RTCRegRead(0x04);
comDate[9] = (tmp >> 4) + 0x30 ;
comDate[10] = (tmp & 0x0F) + 0x30 ;
//Get Year
tmp = RTCRegRead(0x06);
comDate[12] = (tmp >> 4) + 0x30 ;
comDate[13] = (tmp & 0x0F) + 0x30 ;
lcd_line(2);
lcd_string(time);
lcd_line(1);
if(view == 0){
sprintf(string," AtomSoftTech ",0);
lcd_string(string);
} else {
lcd_string(comDate);
}
decMonth = bcd2dec(RTCRegRead(0x05), 2);
decDate = bcd2dec(RTCRegRead(0x04), 0);
decYear = bcd2dec(RTCRegRead(0x06), 0);
decHour = bcd2dec(RTCRegRead(0x02),1);
decMin = bcd2dec(RTCRegRead(0x01),3);
decAPM = bcd2dec(RTCRegRead(0x05),0);
decAPM = (decAPM >> 4) & 0x01;
}
/**********************************
Show Menu
***********************************/
/**********************************
Set the Time
***********************************/
/**********************************
Set the Date
***********************************/
/**********************************
Interrupt Code
***********************************/