Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] DS1307, 16f877a, Mikroc

Status
Not open for further replies.

jmlabuac

Newbie level 5
Joined
Jan 5, 2012
Messages
8
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,379
Hi guys... I really need some help...

I created the code below which just displays time and some amount which depends on the time lapsed.. My problem is that when I ran it in proteus, it went smoothly and produced the output I expected... But when I implemented it on the actual hardware, it all went gibberish.. The LCD keeps on updating every second since I set it to interrupt every second and display an updated value.. However on the hardware implementation the LCD keeps on putting characters that weren't even set....

I hope you could help me here....

#define _seconds 0x00
#define _minutes 0x01
#define _hours 0x02
#define _days 0x03
#define _date 0x04
#define _month 0x05
#define _year 0x06
#define _control 0x07
#define _Wr_1307 0b11010000 // write data to the rtc
# define _Rd_1307 0b11010001 // read data from the rtc
# define _config1 0b10010000 // 1hz output

unsigned int p_fee = 0; // parking fee
unsigned int counter = 0;
unsigned int seconds;
unsigned int minutes;
unsigned int hours;
unsigned int days;
unsigned int date;
unsigned int month;
unsigned int year;
char buff;
char update = 0;


// Lcd Initialization
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
//End of Lcd Initialization

char read_1307(char addr){
I2C1_Start();
I2C1_Wr(_Wr_1307);
I2C1_Wr(addr);
I2C1_Repeated_Start();
I2C1_Wr(_Rd_1307);
buff = I2C1_Rd(0);
I2C1_Stop();
return (buff);
}

void get_data(){
seconds = read_1307(_seconds);
minutes = read_1307(_minutes);
hours = read_1307(_hours);
date = read_1307(_date);
}

void interrupt(){
if (INTCON.INTF){
update = 1;
INTCON.INTF = 0; // clear interrupt flag.
}
if (counter < 300)
counter++;
else{
p_fee += 2;
counter = 0;
}
}

void initialize(){
INTCON.GIE = 1; //controls all possible interrupt sources simultaneously
INTCON.PEIE = 1; // acts similar to the GIE it, but controls interrupts enabled by peripherals
INTCON.INTE = 1; // Enable RB0/INT external interrupt
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1, 10, "Days");
Lcd_Chr(2,3,'A');
Lcd_Chr(2,4,'m');
Lcd_Chr(2,5,'o');
Lcd_Chr(2,6,'u');
Lcd_Chr(2,7,'n');
Lcd_Chr(2,8,'t');

TRISB = 0X01;

I2C1_Init(100000);
delay_ms(100);
}

void write_ds1307(unsigned short address,unsigned short w_data)
{
I2C1_Start(); // issue I2C start signal
//address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C1_Wr(0xD0); // send byte via I2C (device address + W)
I2C1_Wr(address); // send byte (address of DS1307 location)
I2C1_Wr(w_data); // send data (data to be written)
I2C1_Stop(); // issue I2C stop signal
}

void settime(){

write_ds1307(0,0x80); //Reset second to 0 sec. and stop Oscillator
write_ds1307(1,0x27); //write min 27
write_ds1307(2,0x14); //write hour 14
write_ds1307(3,0x00); //write day of week 2:Monday
write_ds1307(4,0x17); // write date 17
write_ds1307(5,0x00); // write month 6 June
write_ds1307(6,0x00); // write year 8 --> 2008
write_ds1307(7,0x10); //SQWE output at 1 Hz
write_ds1307(0,0x00); //Reset second to 0 sec. and start Oscillator

}


unsigned int time_reduce(unsigned int x){
if((x>9)&&(x<32))
x = 1;
else if((x>28)&&(x<48))
x = 2;
else if((x>41)&&(x<64))
x = 3;
else if((x>57)&&(x<80))
x = 4;
else if((x>73)&&(x<90))
x = 5;
else
x = 0;
return x;
}

unsigned int correct_time(unsigned int x){
x = x - (time_reduce(x) * 6);
return x;
}

void compute_amount(){
unsigned int min_1 = 0, min = 0, hr = 0, dte = 0;
get_data();
min_1 = correct_time(minutes);
min = (min_1/5) * 3;
if ( (min_1 % 5) > 0 )
{ min = min + 3; }
hr = correct_time(hours) * 36;
dte = correct_time(date) * 864;
p_fee = min + hr + dte;
}

unsigned char BCD2UpperCh(unsigned char bcd)
{
return ((bcd >> 4) + '0');
}

unsigned char BCD2LowerCh(unsigned char bcd)
{
return ((bcd & 0x0F) + '0');
}


void display2(){
char data1[9];
char amount[7];
char data2[3];
get_data();
compute_amount();
data2[2] = '\0';
data2[1] = BCD2LowerCh(date);
data2[0] = BCD2UpperCh(date);
data1[7] = '\0';
data1[7] = BCD2LowerCh(seconds);
data1[6] = BCD2UpperCh(seconds);
data1[5] = ':';
data1[4] = BCD2LowerCh(minutes);
data1[3] = BCD2UpperCh(minutes);
data1[2] = ':';
data1[1] = BCD2LowerCh(hours);
data1[0] = BCD2UpperCh(hours);

IntToStr(p_fee,amount);
Lcd_Out(1,1,data1);
Lcd_Out(1,15, data2);
Lcd_Out(2,10,amount);
}


void main()
{
initialize();
settime();
while(1){
if (update)
{
display2();
Delay_ms(500);
update = 0;
}
}
}
 

looks like your using port B for the lcd

this is a bad idea better to stick to using port D
and port B for the ds chip
as port B is serviced before portD but they are in a cycle
pics go
port A-C B-D as clocked
so a bit like a car engine
port b on pics has an interrupt of its own {INTCON.INTE = 1; // Enable RB0/INT external interrupt in your code}

perhaps something goes on there
also the total time in Ms within your subroutines is too long
take out some delays like delay 100ms
as a repeated call to 100ms soon makes the other 500ms seconds up you make in the 'main' branch

void main()
{
initialize();
settime();
while(1){
if (update)
{
display2();
Delay_ms(500);
update = 0;
}
}
}

watch for update =0
set it to update = false
and set 'update' as a bit not an int etc

can be a problem

void main()
{
initialize();
settime();
do{
if (update)
{
display2();
Delay_ms(500);
update = 0;
}
}white (TRUE);
}

it sounds like some sort of interrupt re enter problem caused by time delays or interrupts etc
ie too much time used
this will cause corruption on the lcd

i am surprised proteus doesn't say something
like too much cpu usage or the compiler doesn't moan about its interrupts schedule

i feel the compiler your using is'nt so mature so expect strange non error generation stuff

above all your code is fine and logical

just needs some tweaks in time and pin placements proteus is mostly ignorant to this i feel



usefull case define when using logical expressions

remember some types of defines use zero as a null state and not a state

you can use a header file as you should always do in c or c++ etc...most except basic

and add this or similar adjusted for use in your compiler

////////////////////////////////
// : CASE LOGIC DEFINITIONS : //
////////////////////////////////
#case
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef YES
#define YES 1
#endif
#ifndef NO
#define NO 0
#endif
#ifndef HIGH
#define HIGH 1
#endif
#ifndef LOW
#define LOW 0
#endif
#ifndef ON
#define ON 1
#endif
#ifndef OFF
#define OFF 0
#endif
#ifndef UP
#define UP 1
#endif
#ifndef DOWN
#define DOWN 0
#endif
#ifndef UCHAR
#define UCHAR char
#endif
#ifndef UINT
#define UINT long
#endif
#ifndef BIT
#define BIT short
#endif
#ifndef SCHAR
#define SCHAR signed int
#endif
#ifndef SINT
#define SINT signed long
#endif
#ifndef FLOAT
#define FLOAT float
#endif
/////////////////////////////////
/////////////////////////////////
 
Last edited:
Thanks... I'll try it...
 
  • Like
Reactions: bijan

    bijan

    Points: 2
    Helpful Answer Positive Rating
I already solved it... The problem was that I was getting data from the ds1307 twice in every interrupt that is why the output was not as it seems... I just erased the get_data() in one of the functions... And it was running beautifully...
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top