DS3231 Set Alarm UC3A3

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can someone help me with setting the Alarm at DS3231 and UC3A3-Explaind?

 

This is a code that I use to set the time:


void twi_ds3231(void)
{
		uint8_t tbuffer[20];
		tbuffer[0]=0;
		tbuffer[1]=0b00000111;
		tbuffer[2]=0b00010001;
		tbuffer[3]=0b00000001;
		tbuffer[4]=0b00100101;
		tbuffer[5]=0b10000001;
		tbuffer[6]=0b00010111;
		
		
		
twim_package_t write = {
	.chip = 0b01101000,
	.addr[0] = 0x00, 
	.addr_length = sizeof (uint8_t), 
	.buffer = &tbuffer,
	.length = 7,
	.no_wait = false,
	};

// twim_write_packet(&AVR32_TWIM0,&write); // is used only first time to initialise the time
                                            //currently set as 11:07:00 25-1-2017
twim_package_t readDS3231 = {
	.chip = 0b01101000,
	.addr[0] = 0x00, 
	.addr_length = sizeof (uint8_t), //in bit!!!!!!!!!!!!!
	.buffer = &tbuffer,
	.length = 12, //#register
	.no_wait = false,
	};

  twim_read_packet(&AVR32_TWIM0,&readDS3231);
 

 

Alarm rate should be set when seconds match

So, my idea is to write tbuffer[7] (but i am not sure what to write inside the buffer: 0x0E, 0x0F, 0x07?) and compare it with tbuffer[0], which is for seconds. But my plan is not working, for now.

Any idea? :)

 

Greetings

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You also need to write A1M1, A1M2, A1M3, and A1M4 in registers 0x07 through 0x0A to configure the alarm.  To have the alarm go off only when the seconds match, that corresponds to A1M1 = 0, A1M2..4 = 1.  So the values you need to write are...

 

tbuffer[7] = 0b0XXXXXXX where X = BCD seconds value.

tbuffer[8] = 0b1XXXXXXX where X = don't care

tbuffer[9] = 0b1XXXXXXX where X = don't care

tbuffer[10] = 0b1XXXXXXX where X = don't care

 

If you want the alarm to output a signal from the ~INT/SQW pin instead of having to poll the alarm flags at address 0x0F, then you also need to configure register 0x0E.  The bits you're interested in are INTCN (bit 2) and A1IE (bit 0).  Both need to be set to 1.

Last Edited: Thu. Jan 26, 2017 - 01:06 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your response!

 

Tell me if I am wrong


void twi_ds3231_write(void)
{
		uint8_t tbuffer[20];
		tbuffer[0]=0;			//
		tbuffer[1]=0b01010111;	//
		tbuffer[2]=0b00010011;	//
		tbuffer[3]=0b00000001;	//		Zeit: 13:57:00	26-01-2017
		tbuffer[4]=0b00100110;	//
		tbuffer[5]=0b10000001;	//
		tbuffer[6]=0b00010111;	//
		
		tbuffer[7]=0b10000000;	//		Set Alarm  
		tbuffer[8]=0b10000000;	//		Alarm 1 ON, Alarm rate: once per second
		tbuffer[9]=0b10000000;	//      1 Hz square-wave
		tbuffer[10]=0b10000000;	//		
				
		tbuffer[11]=0b00000000;	//		Set Alarm 2
		tbuffer[12]=0b00000000;	//		Alarm 2 OFF
		tbuffer[13]=0b00000000;	//		set im tbuffer[14] bit 1
		
		tbuffer[14]=0b00000101;	//	Control Register, Alarm 1 Set
		tbuffer[15]=0b10000001;	//	Status Register Alarm 1 Flag enabled
		
twim_package_t writescheisse = {
	.chip = 0b01101000,
	.addr[0] = 0x00, 
	.addr_length = sizeof (uint8_t), //in bit!!!!!!!!!!!!!
	.buffer = &tbuffer,
	.length = 16,
	.no_wait = false,
	};

 twim_write_packet(&AVR32_TWIM0,&writescheisse); //vorsicht- wenn kein ack wird nicht weiter gesandt!!!
};

void twi_ds3231_read(void)
{
	
	uint8_t tbuffer[20];
	
	twim_package_t readDS3231 = {
		.chip = 0b01101000,
		.addr[0] = 0x00,
		.addr_length = sizeof (uint8_t), //in bit!!!!!!!!!!!!!
		.buffer = &tbuffer,
		.length = 16, //#register lesen
		.no_wait = false,
	};

	twim_read_packet(&AVR32_TWIM0,&readDS3231);
	
	uhrzeit.tm_sec = (tbuffer[0] & 0x0f)+((tbuffer[0] & 0xf0)>>4)*10;
	uhrzeit.tm_min = (tbuffer[1] & 0x0f)+((tbuffer[1] & 0xf0)>>4)*10;
	uhrzeit.tm_hour = (tbuffer[2] & 0x0f)+(((tbuffer[2] & 0x10)+(tbuffer[2]&0x20))>>4)*10;
	uhrzeit.tm_wday = (tbuffer[3] & 0x07);
	uhrzeit.tm_mday = (tbuffer[4] & 0x0f)+((tbuffer[4] & 0xf0)>>4)*10;
	uhrzeit.tm_mon = (tbuffer[5] & 0x0f)+((tbuffer[5] & 0x10)>>4)*10;
	uhrzeit.tm_year = (tbuffer[6] & 0x0f)+((tbuffer[6] & 0xf0)>>4)*10+((tbuffer[5] & 0x80)>>7)*100 + 1900 ;

}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No matter what i write to tbuffer[14] and tbuffer[15] i am reading constat square signal on the pin SQW and also 32K (with the oscilloscope)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i haven't succeeded to set Alarm every second but settind it once in a minute works. Fo example

		uint8_t tbuffer[20];
		tbuffer[0]=0;			//
		tbuffer[1]=0b01010111;	//
		tbuffer[2]=0b00010011;	//
		tbuffer[3]=0b00000001;	//		Zeit: 13:57:00	26-01-2017
		tbuffer[4]=0b00100110;	//
		tbuffer[5]=0b10000001;	//
		tbuffer[6]=0b00010111;	//
		
		tbuffer[7]=0b00000101;	//		Set Alarm  
		tbuffer[8]=0b01010111;	//		Alarm 1 ON um xx:57:05
		tbuffer[9]=0b10000000;	//
		tbuffer[10]=0b10000000;	//		
				
		tbuffer[11]=0;	//		Set Alarm 2
		tbuffer[12]=0;	//		Alarm 2 OFF
		tbuffer[13]=0;	//		set im tbuffer[14] bit 1
		
		tbuffer[14]=0b00000101;	//	Control Register, Alarm 1 Set
		tbuffer[15]=0b10000000;	//	Status Register Alarm 1 Flag enabled  ???

The time ist set at 13:57:00 and after the upload SQW pin will go high and after 5 sec it goes low again. Well, its something. :D

@Rezer thank you very much for your help!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

m@rko wrote:

No matter what i write to tbuffer[14] and tbuffer[15] i am reading constat square signal on the pin SQW and also 32K (with the oscilloscope)

 

The constant square wave on pin SQW makes sense with the code you posted in post #3.  With the alarm set to once a second (all 4 alarm mask bits set to 1), there will be a square wave with a period of one second when INTCN is either 0 or 1, since when it's 1 your once a second alarm is enabled and when it's 0 the once a second square wave output is enabled.  The only way to stop it entirely without changing the alarm mask bits would be to write INTCN to 1 and A1IE to 0.  As for the 32kHz output, that one doesn't make any sense to me, it should be off when you set address 0x0F to 0 (the leading 1 in 0b10000000 doesn't do anything there, that's a read only bit).  Are you sure all 16 bytes are being transferred?  Have you checked the return code from twim_write_packet()?  The 32kHz signal does default to on, but should be turned off by the code you have here.

 

 

 

m@rko wrote:

i haven't succeeded to set Alarm every second but settind it once in a minute works.

 

What do you mean by once a second?  Do you really mean once per minute when the seconds match?  In the code you posted here it looks like the alarm should be going off once per hour at XX:57:05 when the minutes and seconds match, which matches the behavior you describe, and in post #3 you seem to have the once a second alarm working there.  To get once per minute you would need to do something like this:

 

tbuffer[7]=0b00000101;	//		Set Alarm
tbuffer[8]=0b11010111;	//		Alarm 1 ON um xx:xx:05
tbuffer[9]=0b10000000;	//
tbuffer[10]=0b10000000;	//	

Then, assuming the bytes are written properly, you should get an alarm every minute when seconds = 5.  Is that what you're trying to do, or am I misunderstanding?

Last Edited: Thu. Jan 26, 2017 - 07:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

it is working.

My mistake. How about to connect GND when measuring with osciloscope frown

Thank you very much. You were very helpful!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No problem, glad I could help laugh

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you maybe know how to configure single Pin at UC3A3-Xplained board to recieve interrupt from SQW Pin (DS3231) and wake the board from sleep mode?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

m@rko wrote:
Do you maybe know how to configure single Pin at UC3A3-Xplained board

The XPlained board is irrelevant here - the way to configure processor pins & interrupts is not affected by what board the chip happens to be mounted on!

 

from SQW Pin 

Again, the source of the is irrelevant here

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mhm, ok.

 

Chip is Atmel 32UC3A3256

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So the documentation you require is here:

 

http://www.atmel.com/devices/at3...

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

It appears that you are using the ASF.
The process is ;
1) use the processor datasheet to find the appropriate internal peripheral (pin-change is handled by the GPIO module),
2) search the ASF to find a 'driver' for that module (GPIO),
3) read what is in the ASF .c and .h files to see if there are functions that seems suitable. ( gpio_enable_pin_interrupt(,,) )
4) read the processor datasheet to understand what is happening and what information the ASF routines need.
5) goto 1)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@awneil and @mikech thank you very much for the answers!