When I did my 1307 routines, I did the 'bit-test' stuff I needed to do 'up front'
and masked that off the data. Then took the 'number' portion of the data and
dropped that into my BCD_to_BIN routine.
When I had to set the data, I did it very similar. Did the BIN_to_BCD on the
data, then 'or' in the other bits and write it back.
It's not rocket science, but if you don't modularize what you're doing with
specific 'in and out' routines, you can get messed real quick.
Hi Ganimides,
I don't see the problem. Your H, M, S variables are initialised in HEX, and displayed in decimal.
Minutes = 0x10; //converts to 16 decimal
Hours = 0x12; //converts to 18 decimal
I did not check your code but I imagine that the software has a data-type issue which is stopping the seconds wrapping round and minutes updating.
Mark
Hi guys!.
Thank you for taking time to see my code!.
Yes you are right,yesterday night I looked around much better my code I realized that I`m displaying my data in BCD format because of the jumps that it has.
The problem is that I just need to make some routine to convert BCD to binary data so that I can send it out to LCD display.
Greetings!
Ganimides.
Hello Ganimides,
It may be simpler to convert each BCD digit to its ASCII value, and place the characters at the appropriate positions within a string (array). The string could then be directly sent to the LCD.
unsigned char upper_chr (unsigned char value)
{
return ((value >> 4) + 0x30);
}
unsigned char lower_chr (unsigned char value)
{
return ((value & 0x0F) + 0x30);
}
Regards,
Mac
Message Edited by ganimides on 05-17-200608:57 AM
Hello Ganimides,
Since the DS1307 registers are already in BCD format, it is simpler to do BCD to ASCII conversion, rather than BCD to binary conversion, followed by binary to ASCII conversion. The following sequence within your code actually provides the binary to ASCII conversion, and would not be required with my proposal.
Datos4bits(((value%1000)/100)+0x30);
Datos4bits(((value%100)/10)+0x30);
Datos4bits((value%10)+0x30);
The DS1307 actually uses packed BCD format, with two digits represented by a single byte. The purpose of the upper_chr() and lower_chr() functions is to unpack each BCD digit, and convert to an ASCII byte.
The suggested new and modified functions follow. The printf_LCD_4bits() function would now only need to output a text string.
unsigned char upper_char (unsigned char value);
{
return ((value >> 4) + 0x30);
}
unsigned char lower_char (unsigned char value);
{
return ((value & 0x0F) + 0x30);
}
void printf_LCD_4bits(unsigned char fila, unsigned char columna, char *texto)
{
unsigned char adrs;
adrs = columna - 1;
if(fila == 2)
adrs = adrs | 0x40;
Ctrl4bits(adrs | 0x80);
while(*texto)
Datos4bits(*texto++);
}
The following code could then be included within main(), or within another function.
unsigned char LCDtext[] = "xxh:xxm:xxs";
unsigned char Hours, Minutes, Seconds;
Hours = ReadRTCbyte(2) & 0x3F; // 24hr format assumed
Minutes = ReadRTCbyte(1) & 0x7F; // Mask 7 bits only
Seconds = ReadRTCbyte(0) & 0x7F; // Mask 7 bits only
LCDtext[0] = upper_chr (Hours);
LCDtext[1] = lower_chr (Hours);
LCDtext[4] = upper_chr (Minutes);
LCDtext[5] = lower_chr (Minutes);
LCDtext[8] = upper_chr (Seconds);
LCDtext[9] = lower_chr (Seconds);
printf_LCD_4bits (1,1,LCDtext);
I hope this clarifies the situation.
Regards,
Mac
Message Edited by bigmac on 05-18-200605:51 PM
#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations */#include <MC68HC908GP32.h>//#include <lcd.h>#include <stdio.h>//#include <lcd.c>#define SDA PTC_PTC6#define SCL PTC_PTC5#define DIR_SDA DDRC_DDRC6#define DIR_SCL DDRC_DDRC5#define SPEED 4 #define HOLD 1#define SLAVE_ADDRESS 0xD0 #define LEN 58 byte temp, dummy, RD_data, WR_data, ACK_flag, w, i;byte own_sl_addr = 0xD0; byte RAM_Data[LEN];byte RTC_reg[7] @0x60; byte Cntr_reg @0x67;typedef struct{ byte Sec; byte Min; byte Hrs; byte Day; byte Date; byte Month; byte Year;}sRTC;volatile sRTC RTC @0x60; #define Seconds RTC.Sec#define Minutes RTC.Min#define Hours RTC.Hrs#define Day RTC.Day#define Date RTC.Date#define Month RTC.Month#define Year RTC.Year#define RTC_REG_START 0x00#define NV_RAM_START 0x08 /* Function definition *///void Init_CPU(void);void Init_Time_Default(void);byte GetByte(void);void WriteIICbus(byte data);void Write_Control_reg(byte ctrl);void Read_ACK(void);void Write_ACK(void);void StartBit(void);void StopBit(void);void Wait_time(byte time);void Wait_sh(byte time);void InitPLL(void);extern void LCDdelay(void);extern void Ctrl8bits(unsigned char codigo);extern void Ctrl4bits(unsigned char codigo);extern void Datos4bits(unsigned char dato);extern void Config_LCD_4bits(void);extern void printf_LCD_4bits(unsigned char fila, unsigned char columna, char *texto,char value); void InitPLL(void){ CONFIG1 = 0x01; CONFIG2 = 0x00; PCTL_BCS = 0; PCTL_PLLON = 0; /* Disable the PLL */ /* PCTL: PLLIE=0,PLLF=0,PLLON=0,BCS=0,PRE1=0,PRE0=0,VPR1=1,VPR0=0 */ PCTL = 0x02; /* VCO Power-of-Two multiplier E=2 */ /* PMS: MUL11=0,MUL10=0,MUL9=1,MUL8=1,MUL7=1,MUL6=1,MUL5=0,MUL4=1,MUL3=0,MUL2=0,MUL1=0,MUL0=1 */ PMS = 0x03D1; /* Feedback divider N=977 */ /* PMRS: VRS7=1,VRS6=1,VRS5=0,VRS4=1,VRS3=0,VRS2=0,VRS1=0,VRS0=0 */ PMRS = 0xD1; /* VCO Linear multiplier L=208 */ /* PMDS: RDS3=0,RDS2=0,RDS1=0,RDS0=1 */ PMDS = 0x01; /* Reference clock devider R=1 */ /* PBWC: AUTO=1,LOCK=0,ACQ=0,—–=0,˜™=0,??=0,??=0,??=0 */ PBWC = 0x80; /* Select the operating modes */ /* PCTL: PLLON=1 */ PCTL_PLLON = 1; /* Enable the PLL */ while(!PBWC_LOCK) { /* Wait */ } /* PCTL: BCS=1 */ PCTL_BCS = 1; /* Select clock source from PLL */ __asm("nop"); __asm("nop"); }void Init_Time_Default(void) // see datasheet of DS1338;{ Seconds = 0; Minutes = 0x10; Hours = 0x12; Day = 4; // day of week; Date = 0x11; Month = 5; Year = 6;}//********************************************************************void Write_Control_reg(byte ctrl) // writes Cntr_reg to RTC;{ ACK_flag = 0; StartBit(); WriteIICbus(SLAVE_ADDRESS); asm nop; Read_ACK(); asm nop; if(ACK_flag !=0) { StopBit(); return; } WriteIICbus(7); // write address of the Control register; Read_ACK(); if(ACK_flag !=0) { StopBit(); return; } WriteIICbus(ctrl); // write value into Control register; Read_ACK(); if(ACK_flag !=0) { StopBit(); return; } StopBit();}//********************************************************************void Read_Control_reg(void) // reads Cntr_reg from RTC;{ ACK_flag = 0; StartBit(); WriteIICbus(SLAVE_ADDRESS); // RW bit = 0; asm nop; Read_ACK(); asm nop; if(ACK_flag !=0) { StopBit(); return; } WriteIICbus(7); // write address of the Control register; Read_ACK(); if(ACK_flag !=0) { StopBit(); return; } StartBit(); WriteIICbus(SLAVE_ADDRESS | 1); // RW bit = 1; Read_ACK(); if(ACK_flag !=0) { StopBit(); return; } DIR_SDA = 0; Cntr_reg = GetByte(); // read value from the Control register and save it; StopBit();}//********************************************************************void WriteRTC(void){ ACK_flag = 0; StartBit(); WriteIICbus(SLAVE_ADDRESS); asm nop; Read_ACK(); asm nop; if(ACK_flag !=0) { StopBit(); return; } WriteIICbus(0); // Starts write from address "0" in RTC (Seconds); Read_ACK(); if(ACK_flag !=0) { StopBit(); return; } for(i=0;i<7;i++) { WriteIICbus(RTC_reg[i]); Read_ACK(); if(ACK_flag !=0) { StopBit(); return; } } StopBit();}//********************************************************************byte ReadRTCbyte(byte addr){ ACK_flag = 0; StartBit(); WriteIICbus(SLAVE_ADDRESS); // RW bit = 0; asm nop; Read_ACK(); asm nop; if(ACK_flag !=0) { StopBit(); return 0; } WriteIICbus(addr); Read_ACK(); if(ACK_flag !=0) { StopBit(); return 0; } StartBit(); WriteIICbus(SLAVE_ADDRESS | 1); // RW bit = 1; Read_ACK(); if(ACK_flag !=0) { StopBit(); return 0; } DIR_SDA = 0; RD_data = GetByte(); StopBit(); return RD_data;}//********************************************************************byte GetByte(void){ byte tempb, i; tempb = 0; for(i=0;i<8;i++) { tempb = tempb << 1; SCL = 1; Wait_sh(SPEED); tempb = tempb | SDA; SCL = 0; Wait_sh(SPEED - HOLD); } return tempb;}//********************************************************************void WriteIICbus(byte data){ byte tempb, i; tempb = data; for(i=0;i<8;i++) { SDA = ((tempb & 0x80)>>7); tempb = tempb << 1; Wait_sh(HOLD); SCL = 1; Wait_sh(SPEED); SCL = 0; Wait_sh(SPEED - HOLD); }}//********************************************************************void Read_ACK(void){ DIR_SDA = 0; Wait_sh(HOLD); SCL = 1; Wait_sh(SPEED); ACK_flag = SDA; SCL = 0; DIR_SDA = 1;}//********************************************************************void Write_ACK(void){ DIR_SDA = 1; SDA = 0; Wait_sh(HOLD); SCL = 1; Wait_sh(SPEED); SCL = 0; Wait_sh(HOLD);}//********************************************************************void StartBit(void){ SDA = 1; SCL = 1; DIR_SDA = 1; DIR_SCL = 1; Wait_sh(SPEED); Wait_sh(SPEED); SDA = 0; Wait_sh(SPEED); SCL = 0; Wait_sh(SPEED);}//********************************************************************void StopBit(void){ Wait_sh(HOLD); SCL = 1; Wait_sh(SPEED); SDA = 1;}//***************************************************************************void Wait_time(byte time){ const word k = 250; word i, temp_t = (time*k); for (i=0;i<temp_t;i++) { asm nop; }}//********************************************************************void Wait_sh(byte time){ word i, temp_t = time; for (i=0;i<temp_t;i++) { asm nop; }}void main (void) { DDRA_DDRA4=1 ; DDRB_DDRB4=1 ; DDRB_DDRB5=1 ; DDRB_DDRB6=1 ; DDRB_DDRB7=1 ; DDRC_DDRC0=1 ; DDRC_DDRC3=1 ; DDRC_DDRC4=1 ; EnableInterrupts; /* enable interrupts */ InitPLL(); Config_LCD_4bits(); Write_Control_reg(3); // squarewave output 32.768kHz at RTC SQW pin; Init_Time_Default(); WriteRTC(); for(;;) { __RESET_WATCHDOG(); /* feeds the dog */ Hours = ReadRTCbyte(2); Minutes = ReadRTCbyte(1); Seconds = ReadRTCbyte(0); Datos4bits (0x01); printf_LCD_4bits (1,1,"h",Hours); printf_LCD_4bits (1,6,"m",Minutes); printf_LCD_4bits (1,12,"s",Seconds); //PTA = RD_data; // Show RTC info on LEDs; //PTB = RD_data; // Show RTC info on LEDs; //wait_time(250); //asm nop; } /* loop forever */ /* please make sure that you never leave this function */}
Message Edited by Alban on 05-16-2006 01:32 PM