4.4.2 Main Code

In the main function, after initialization, the MCU will enter a while(1) loop where it will go into Standby sleep mode. The MCU is only woken when the ADC conversion is complete. The filters are then updated, and movement determination is made. To reduce the average power consumption, the peripheral clock speed is reduced before entering Standby sleep mode and increased again after waking up, to speed up updating the filters, and determine if any movement has occurred. This change in clock speed is only effective if the number of accumulated ADC samples configured in PIR_OVERSAMPLE_RATE is greater than eight. Otherwise, the time to change the clock speed is longer than the time spent doing the ADC conversions, thus increasing the power consumption.

int main(void)
{
	/* Initial clock set to 5MHz.																							*/
	/* If number of samples accumulated by the ADC is less than 16, CLKCTRL_PDIV_2X_gc in MCLKCTRLB and ADC0.CTRLB = ADC_PRESC_DIV4_gc;	*/
	/*  should be used to lower average power consumption																	*/						
	ccp_write_io((void *)&(CLKCTRL.MCLKCTRLB), CLKCTRL_PDIV_4X_gc | 1 << CLKCTRL_PEN_bp ); /* Divide main clock by 4x*/
	
	IO_init();				  /* Initialize IO pins */
	EVENT_SYSTEM_0_init();		    /* Initialize Event System */
	RTC_init();			        /* Initialize PIT */
	#ifdef PIR_DEBUG_MESSAGES
	USART_init();			      /* Initialize USART if SEND_SERIAL_DATA is defined */
	#endif
	
	ADC_0_init();			      /* Initialize the ADC */

	SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc; /* Select standby sleep mode */

	sei();				      /* Enable global interrupt */

	warm_up_and_filter_creation();	   /* Run warm-up and collect ADC data to create filters */
	
	while (1) 
	{
		/* Reduce main clock speed to lower peripheral clock tree power consumption when ADC is running in sleep mode */
		/* Only effective if ADC is configured to accumulate more that 8 samples.			  			 			  */ 
		/* If number of samples accumulated is less than 16, the line below should be removed						  */
		ccp_write_io((void *)&(CLKCTRL.MCLKCTRLB), CLKCTRL_PDIV_4X_gc | 1 << CLKCTRL_PEN_bp ); /* Divide main clock by 4x */

		sleep_mode();				/* Enter sleep mode */

		/* Increase main clock to run the code faster in active mode, this will reduce the average power consumption */
		/* If number of samples accumulated is less than 16, the line below should be removed						*/
		ccp_write_io((void *)&(CLKCTRL.MCLKCTRLB), CLKCTRL_PDIV_2X_gc | 1 << CLKCTRL_PEN_bp ); /* Divide main clock by 2x */
	
		update_average_filters();	/* Update filters with new measurement */
		check_for_movement();		/* Check if movement has happened by examining delta between filters */

		#ifdef PIR_DEBUG_MESSAGES	/* Send data to data visualizer if SEND_SERIAL_DATA is defined */
		usart_tx(adc_result, long_term_average, short_term_average, filter_delta);
		#endif
	}
}