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.

RTC DS1307 Time updata problem with Atmega16

Status
Not open for further replies.

hardik.patel

Member level 5
Joined
Aug 15, 2012
Messages
94
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Activity points
2,008
I simply displaying time on 4 Seven Segments as HR n MIN.
It shows 10:52 continously(Which is set once at first time) then there is no update

Before 2 days back....everything is OK. but then after i cant understood whats problem with it.

Hardware is ok as it was running before 2 days so there is no problem with it.
SCL/SDA are pulled high with 10K. Even 3V battery also attached.
Atmega16+11.0592Mhz+AVR GCC




Code:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>

#define sbi(x,y) x |= _BV(y) //set bit - using bitwise OR operator
#define cbi(x,y) x &= ~(_BV(y)) //clear bit - using bitwise AND operator 

#define MT_SLA_ACK1          0x18        //twi interface commands for ds1307
#define MT_DATA_ACK1         0x28

#define START                0x08

#define MT_SLA_ACK            0x40
#define MT_DATA_ACK           0x58

#define SLA_R   0b11010001                             //address for ds1307
#define SLA_W   0b11010000
  
#define SEG_ALL 0x7F
#define SEG_A 1
#define SEG_B 2
#define SEG_C 4
#define SEG_D 8
#define SEG_E 16
#define SEG_F 32
#define SEG_G 64


#define disp0_1 	sbi(PORTB,4)
#define disp0_0 	cbi(PORTB,4)

#define disp1_1 	sbi(PORTB,5)
#define disp1_0 	cbi(PORTB,5)

#define disp2_1 	sbi(PORTB,6)
#define disp2_0 	cbi(PORTB,6)

#define disp3_1 	sbi(PORTB,7)
#define disp3_0 	cbi(PORTB,7)


//#define ok_low  	cbi(PORTB,3)
//#define ok_high 	sbi(PORTB,3)
////
//#define set_low 	cbi(PORTB,2)
//#define set_high 	sbi(PORTB,2)
////
//#define hour_low 	cbi(PORTB,0)
//#define hour_high 	sbi(PORTB,0)
////
//#define min_low 	cbi(PORTB,1)
//#define min_high 	sbi(PORTB,1)
//



#define sec_register                          0x00
#define min_register                          0x01
#define hour_register                         0x02
#define weekday_weekend_register 			  0x03
#define day_register                          0x04
#define month_register                        0x05
#define year_register                         0x06

uint8_t address;
void seven_seg();
uint8_t data_Read;
uint8_t H,M,S,WK,DY,MN,YR;

int set_variable=0;
int h_var=0;
int m_var=0;
int alarm_H=0;
int alarm_M=0;
int alarm_set_ok=1;

void display(uint8_t n) {
	switch(n) {
		case 0: PORTA = SEG_ALL-SEG_G; break;
		case 1: PORTA = SEG_B+SEG_C; break;
		case 2: PORTA = SEG_ALL-SEG_F-SEG_C; break;
		case 3: PORTA = SEG_ALL-SEG_F-SEG_E; break;
		case 4: PORTA = SEG_F+SEG_G+SEG_B+SEG_C; break;
		case 5: PORTA = SEG_ALL-SEG_B-SEG_E; break;
		case 6: PORTA = SEG_ALL-SEG_B; break;
		case 7: PORTA = SEG_A+SEG_B+SEG_C; break;
		case 8: PORTA = SEG_ALL; break;
		case 9: PORTA = SEG_ALL-SEG_E; break;
		default:PORTA = 0; break;

	}
}





 

uint8_t BCDToDecimal (uint8_t bcdByte)
  {
	return (((bcdByte& 0xF0) >> 4) * 10) + (bcdByte& 0x0F);
  }

uint8_t DecimalToBCD (uint8_t decimalByte)
  {
	return (((decimalByte / 10) << 4) | (decimalByte % 10));
  }
  
void TWI_bit_rate_set(void)
{
	TWBR=8;      // set  SCL frequency  to 400kHz
	TWCR|=1<<TWEN;
}

int TWI_start()
{
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);      // set start
		while (!(TWCR & (1<<TWINT)));      //Wait for TWINT Flag set. This indicates that the START condition has been transmitted
			if ((TWSR & 0xF8) != START)         //Check value of TWI Status Register. Mask prescaler bits. If status different from START go to ERROR
			return 0;
}

int TWI_send_address_read()                // READ..........send slave address in read mode
{
	TWDR = SLA_R;
	TWCR = (1<<TWINT) | (1<<TWEN);     // Load SLA_W into TWDR Register. Clear TWINT bit in TWCR to start transmission of address

	while (!(TWCR & (1<<TWINT)));      //Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received
		if ((TWSR & 0xF8) != MT_SLA_ACK)    // Check value of TWI Status Register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR
		return 0;
}

int TWI_send_addr_data(uint8_t data)      // WRITE.........send the address of data
{
	TWDR=data;
	TWCR = (1<<TWINT) | (1<<TWEN);      //Load DATA into TWDR Register. Clear TWINT bit in TWCR to start transmission of data
		while (!(TWCR & (1<<TWINT)));       // Wait for TWINT Flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received
		if ((TWSR & 0xF8) != MT_DATA_ACK1)     //  Check value of TWI Status Register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR
		return 0;
}

int TWI_get_data()    // READ.....get the address of the data required
{
	TWCR = (1<<TWINT) | (1<<TWEN);      //Load DATA into TWDR Register. Clear TWINT bit in TWCR to start transmission of data
	while (!(TWCR & (1<<TWINT)));       // Wait for TWINT Flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received
		data_Read=TWDR;
		TWCR = (1<<TWINT) | (1<<TWEN);      //Load DATA into TWDR Register. Clear TWINT bit in TWCR to start transmission of data
	while (!(TWCR & (1<<TWINT)));       // Wait for TWINT Flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received
		if ((TWSR & 0xF8) != MT_DATA_ACK)     //  Check value of TWI Status Register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR
		return 0;
}

int TWI_send_address_write()                // WRITE........send slave address in write  mode
{

	TWDR = SLA_W;

TWCR = (1<<TWINT) | (1<<TWEN);     // Load SLA_W into TWDR Register. Clear TWINT bit in TWCR to start transmission of address

 

while (!(TWCR & (1<<TWINT)));      //Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received

 

if ((TWSR & 0xF8) != MT_SLA_ACK1)    // Check value of TWI Status Register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR

return 0;

 

}


void TWI_stop()    //................................stop................................................//

{

 

TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);   //  Transmit STOP condition

 

}


int write(uint8_t pg_addr,uint8_t data1)

{

TWI_bit_rate_set();

 

TWI_start();

 

TWI_send_address_write();

 

TWI_send_addr_data(pg_addr); // send address of page

 

TWI_send_addr_data(data1);  // send data to be written to the address

 

TWI_stop();    

}


int read(uint8_t pg_addr)

{

TWI_bit_rate_set();

           

TWI_start();

 

TWI_send_address_write();

 

TWI_send_addr_data(pg_addr);

 

TWI_start();

 

TWI_send_address_read();

 

TWI_get_data();

 

TWI_stop();    

}


void hour_digits(uint8_t data)

{H=BCDToDecimal(data);}

 

void sec_digits(uint8_t data)

{S=BCDToDecimal(data);}      

 

void min_digits(uint8_t data)

{M=BCDToDecimal(data);}

 

void weekday_weekend_digits(uint8_t data)

{WK=BCDToDecimal(data);}

 

void day_digits(uint8_t data)

{DY=BCDToDecimal(data);}

 

void month_digits(uint8_t data)

{MN=BCDToDecimal(data);}

 

void year_digits(uint8_t data)

{YR=BCDToDecimal(data);}

void wait(int a)

{   int i;

            for(i=1;i<=a;i++)

            {_delay_ms(1000);}

}


void init_interrupt2()
{
	GICR |= (1<<INT2);                 // Enable external interrupt INT2
    MCUCSR |= (1<<ISC2);               // INT2 is executed on rising edge
    sei();    	//
}

ISR(INT2_vect)
{
	//alarm_set_ok=0;
	disp0_1;disp1_0;disp2_0;disp3_0;
	PORTA = SEG_D;_delay_ms(1000);alarm_set();
}
void seven_seg_H(void)
{
	
		
		int h1,h2;
		if(alarm_H<12) h_var++;
		if(alarm_H>12) h_var--;
		
		alarm_H=h_var;
		
		h1=alarm_H/10; //h1
		disp0_1;disp1_0;disp2_0;disp3_0;//PORTB=0x01;
		display(h1);
		_delay_ms(5);
		
		h2=alarm_H%10; //h2
		disp0_0;disp1_1;disp2_0;disp3_0;//PORTB=0x02;
		display(h2);
		_delay_ms(5);
		
		//_delay_ms(500);
		
		if((PINB & (1 << PB3)) != 0){alarm_min();}
		else{alarm_hour();}
		
		
}

void seven_seg_M(void)
{
	
		
		int m1,m2;
		if(alarm_M<59) m_var++;
		if(alarm_M>59) m_var--;
		
		alarm_M=m_var;
		m1=alarm_M/10; //min1
		disp0_0;disp1_0;disp2_1;disp3_0;//PORTB=0x04;
		display(m1);
		_delay_ms(5);
		
		m2=alarm_M%10; //min2
		disp0_0;disp1_0;disp2_0;disp3_1;//PORTB=0x08;
		display(m2);
		_delay_ms(5);
		
		//_delay_ms(500);
		if((PINB & (1 << PB3)) != 0){RTC_read_data();}
		else{alarm_min();}
		
}


void alarm_hour()
{
	
	if((PINB & (1 << PB0)) != 0)//if (bit_is_clear(PINB, 0))
	 {
		_delay_ms(60);
		{seven_seg_H();}
		//if(alarm_H>12){h_var--;    seven_seg_H();}
		//_delay_ms(5000);alarm_set_ok=1;
	 }

	if((PINB & (1 << PB3)) != 0){RTC_read_data();}
		else{alarm_min();}
}
void alarm_min()
{
	if((PINB & (1 << PB1)) != 0)//if (bit_is_clear(PINB, 1))
	 {
		 _delay_ms(60); 
		 seven_seg_M();
		//if(alarm_M<59){m_var++;  seven_seg_M();}
		//if(alarm_M>59){m_var--;  seven_seg_M();}
		//_delay_ms(5000);alarm_set_ok=1;
	 }
	 if((PINB & (1 << PB3)) != 0){RTC_read_data();}
		else{alarm_hour();}
} 


void alarm_set()
{
	
	
	////PORTB = 0xFF;
	//if(set_low) 
	//{
	//PORTA = SEG_G; _delay_ms(500); set_variable=1;//} //0b000001;}
		//if((set_variable==1) && (hour_low)) {alarm_hour(); }
		//if((set_variable==1) && (min_low))  {alarm_min();  }
		alarm_hour();
		if((PINB & (1 << PB3)) != 0){RTC_read_data();}
		else{alarm_hour();}
	////else{;}
}


void RTC_write_data(void)
{
//write(sec_register,DecimalToBCD(00));

write(min_register,DecimalToBCD(52));

write(hour_register,DecimalToBCD(10));

//write(weekday_weekend_register,DecimalToBCD(1));
//
//write(day_register,DecimalToBCD(15));
//
//write(month_register,DecimalToBCD(03));
//
//write(year_register,DecimalToBCD(15));
//
           

}


void RTC_read_data()

{          


int j,k,l,m;


read(hour_register);
hour_digits(data_Read);

read(min_register);
min_digits(data_Read);



		if(H>12){H=H-12;}

		//if(set_low)
		//{int alarm_set_ok=0;   alarm_set();}
		//H=H-12;
		
		//if(alarm_set_ok==1)
		//{
			m=H/10; //min1
			disp0_1;disp1_0;disp2_0;disp3_0;//PORTB=0x01;
			display(m);
			_delay_ms(5);
			
			l=H%10; //min2
			disp0_0;disp1_1;disp2_0;disp3_0;//PORTB=0x02;
			display(l);
			_delay_ms(5);
			
			
			k=M/10; //hour1
			disp0_0;disp1_0;disp2_1;disp3_0;//PORTB=0x04;
			display(k);
			_delay_ms(5);
			
			j=M%10; //hour1
			disp0_0;disp1_0;disp2_0;disp3_1;//PORTB=0x08;
			display(j);
			_delay_ms(5);
		//}	

}

int main(void)

{ 
	DDRA=0XFF;  //7seg data port
	DDRB=0xF0;	//bit 4-7 as i/p for switch for Alarm setting + bit 0-3 as o/p for 7seg control
	//PORTB=0x0F;
	
	//init_interrupt2();
	//set_high;

	
   //RTC_write_data();
	
	while(1)
	{
	//seven_seg();
	 // alarm_set();
	//if(set_high)
		//{int alarm_set_ok=0;   alarm_set();}
		
    RTC_read_data();
	  
	  
	}    
					

}
 

Attachments

  • RTC.JPG
    RTC.JPG
    223.9 KB · Views: 78

Many code lines are commented, including DS1307 initialization.

You have also commented the sec register initialization. If you did this when first setting the RTC, clock halt bit (CH) may be set because it's undefined at power on.

Read the datasheet.
 
@FVM:
I Agree that i had commented sec register while first time initialization because i dont want to display sec.
but after remove that comment on sec register its startedn updating.
------------------------------------------------------------

Now again i had put comment on sec....then write rtc with only HR and MIN though its work fine i.e its updating time.
For now problem solved.
 

I believe, the datasheet states clearly what to do regarding CH bit.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top