예제 #1
0
파일: task5.c 프로젝트: LaneTee/xmega-intro
int main(void)
{
	facilitatePowersaving();		// Pull-ups and PR Registers
	initHardware();					// Switches, LEDs, Sleep, Interrupt

	sei();							// Enable global interrupts

/* === Initialization of TWI Module === */

	// Enable internal pull-up on PD0, PD1 for correct TWI operation
	PORTCFG.MPCMASK = 0x03;
	TWIPORT.PIN0CTRL = (TWIPORT.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc;

	/* Initialize TWI master. */
	TWI_MasterInit(&twiMaster,
	               &TWI,
	               TWI_MASTER_INTLVL_LO_gc,
	               TWI_BAUDSETTING);

	/* Initialize TWI slave. */
	TWI_SlaveInitializeDriver(&twiSlave, &TWI, TWI_SlaveProcessData);
	TWI_SlaveInitializeModule(&twiSlave,
	                          OWN_ADDRESS,
	                          TWI_SLAVE_INTLVL_LO_gc);

/* === End Initialization === */


	while (1) {
			
			// Try to sleep while we are waiting for button press
			while (READ_SWITCHES == 0x00){ //See board.h for READ_SWITCHES define.
				sleep();
				}
			_delay_ms(5);	// Debounce switch			

			sendBuffer[0] = READ_SWITCHES;
			TWI_MasterWrite(&twiMaster,		// Module
	                    OTHER_ADDRESS,		// Which slave
	                    &sendBuffer[0],		// What to send
	                    1);					// Send how much

			/* Wait until transaction is complete. Required TWI interrupts will be executed while waiting */
			while (twiMaster.status != TWIM_STATUS_READY); 
			
			// Wait for user to release button.
			while (READ_SWITCHES != 0x00); //See board.h for READ_SWITCHES define.
	}
	
}
int main(void)
{
	facilitatePowersaving();
	
	// Configure switches
	PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time
	SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc;

	SWITCHPORT.DIRCLR = 0xff; // Set port as input

	// Set up interrupt on buttons
	SWITCHPORT.INTCTRL = (SWITCHPORT.INTCTRL & ~PORT_INT0LVL_gm) | PORT_INT0LVL_LO_gc;
	SWITCHPORT.INT0MASK = 0x0F;

	// Configure LEDs
	PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time
	LEDPORT.PIN0CTRL = PORT_INVEN_bm; // Invert input to turn the leds on when port output value is 1

	LEDPORT.DIRSET = 0xff; 	// Set port as output
	LEDPORT.OUT = 0x02;  // Set initial value


	// Enable low interrupt level in PMIC and enable global interrupts.
	PMIC.CTRL |= PMIC_LOLVLEN_bm;
	sei();

	// Main loop.
	char pressed = 0;
	while (1) {
// == Button 0 pressed
		if (((SWITCHPORT.IN & SW_ACTIVE) | pressed) == 0x00) {		
			_delay_ms(5); // Debounce switch
			pressed = 1; // Used for toggling
			LEDPORT.OUTSET = SW_ACTIVE; // Toggle led

			SLEEP.CTRL &= ~SLEEP_SEN_bm;	// Disable sleep


// == Button 1 pressed
		} else if (((SWITCHPORT.IN & SW_IDLE) | pressed) == 0x00) {	
			_delay_ms(5); // Debounce switch
			pressed = 1; // Used for toggling
			LEDPORT.OUT = SW_IDLE; // Toggle led

			SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_IDLE_gc;
			SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep, else SLEEP-instruction is ineffective.

 // == Button 2 pressed
		} else if (((SWITCHPORT.IN & SW_STBY) | pressed) == 0x00) {
			_delay_ms(5); // Debounce switch
			pressed = 1; // Used for toggling.
			LEDPORT.OUT = SW_STBY; // Toggle led		


			SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_STDBY_gc;
			SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep

// == Button 3 pressed
		} else if (((SWITCHPORT.IN & SW_PWDN) | pressed) == 0x00) {
			_delay_ms(5); // Debounce switch
			pressed = 1; // Used for toggling.
			LEDPORT.OUT = SW_PWDN;


			SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_PDOWN_gc;
			SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep

// == Buttons released
		} else if ( (SWITCHPORT.IN & (SW_ACTIVE | SW_IDLE | SW_STBY | SW_PWDN)) == 0x0F) {
			pressed = 0;
			LEDPORT.OUT = 0x00;
			sleep();
		}


	}
	
}
int main(void)
{
	facilitatePowersaving();

	// Configure switches
	PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time
	SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; //Enable pull-up to get a defined level on the switches

	SWITCHPORT.DIRCLR = 0xff; // Set port as input

	// Configure LEDs
	PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time
	LEDPORT.PIN0CTRL = PORT_INVEN_bm; // Invert input to turn the leds on when port output value is 1

	LEDPORT.DIRSET = 0xff; 	// Set port as output
	LEDPORT.OUT = 0x00;  // Set initial value


	// Set up ADCB0 on PB0 to read temp sensor. More of this can be achieved by using driver from appnote AVR1300
	PORTQ.PIN2CTRL = (PORTQ.PIN2CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLDOWN_gc;	// This pin must be grounded to "enable" NTC-resistor
	PORTB.DIRCLR = PIN0;
	PORTB.PIN0CTRL = (PORTB.PIN0CTRL & ~PORT_OPC_gm);

	ADC_CalibrationValues_Load(&ADCB);  // Load factory calibration data for ADC
	ADCB.CH0.CTRL = (ADCB.CH0.CTRL & ~ADC_CH_INPUTMODE_gm) | ADC_CH_INPUTMODE_SINGLEENDED_gc; // Single ended input
	ADCB.CH0.MUXCTRL = (ADCB.CH0.MUXCTRL & ~ADC_CH_MUXPOS_gm) | ADC_CH_MUXPOS_PIN0_gc; // Pin 0 is input	
	ADCB.REFCTRL = (ADCB.REFCTRL & ~ADC_REFSEL_gm) | ADC_REFSEL_VCC_gc;	// Internal AVCC/1.6 as reference

	ADCB.CTRLB |= ADC_FREERUN_bm; // Free running mode
	ADCB.PRESCALER = (ADCB.PRESCALER & ~ADC_PRESCALER_gm) | ADC_PRESCALER_DIV512_gc; // Divide clock by 1024.
	ADCB.CTRLB = (ADCB.CTRLB & ~ADC_RESOLUTION_gm) | ADC_RESOLUTION_8BIT_gc; // Set 8 bit resolution
	ADCB.CTRLA |= ADC_ENABLE_bm; // Enable ADC
	

	// Set up DMA CH0 to transfer from ADC to LEDS. We only read low byte.
	DMA_Enable();
	DMA_SetupBlock( 
                    &DMA.CH0,
			        (void const *) &(ADCB.CH0RES), 
                    DMA_CH_SRCRELOAD_NONE_gc, 
                    DMA_CH_SRCDIR_FIXED_gc,
			        (void const *) &(LEDPORT.OUT), 
                    DMA_CH_DESTRELOAD_NONE_gc, 
                    DMA_CH_DESTDIR_FIXED_gc,
			        1, 
                    DMA_CH_BURSTLEN_1BYTE_gc, 
                    0,
                    true
                );
    DMA_EnableSingleShot( &DMA.CH0 );
	DMA_SetTriggerSource( &DMA.CH0, DMA_CH_TRIGSRC_ADCB_CH0_gc ); // ADC Channel 0 is trigger source.
	


	// Set up interrupt on button 0, or else we can't come back from IDLE
	SWITCHPORT.INTCTRL = (SWITCHPORT.INTCTRL & ~PORT_INT0LVL_gm) | PORT_INT0LVL_LO_gc;
	SWITCHPORT.INT0MASK = SWITCHMASK_ACTIVE;
	SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_ISC_gm) | PORT_ISC_FALLING_gc;


	// Enable low interrupt level in PMIC and enable global interrupts.
	PMIC.CTRL |= PMIC_LOLVLEN_bm;
	sei();

	// Main loop.
	while (1) {

		if ((SWITCHPORT.IN & SWITCHMASK_ACTIVE) == 0x00)
		{
		// Button 0 pressed. Enter ACTIVE mode again.
			DMA_DisableChannel( &DMA.CH0 );

			SLEEP.CTRL &= ~SLEEP_SEN_bm;	// Disable sleep. sleep() is now ineffective.

		} else if ((SWITCHPORT.IN & SWITCHMASK_IDLE) == 0x00)	
	    {	
		// Button 1 pressed. Enter Idle mode
			DMA_EnableChannel( &DMA.CH0 );			

			// Set and enable sleep.
			SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_IDLE_gc;
			SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep.

		} else if (SLEEP.CTRL & SLEEP_SEN_bm) {
			 	// We are in wanting-to-sleep mode, but were awake.
				sleep();
	
		} else { 
			// Do active sampling and transfer of ADC data.
			LEDPORT.OUT = ADCB.CH0RES & 0xFF;
		}

	}
	
}
int main(void)
{
	facilitatePowersaving();

	// Configure switches
	PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time
	SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; //Enable pull-up to get a defined level on the switches
	SWITCHPORT.DIRCLR = 0xff; // Set port as input

	// Set up interrupt on buttons
	SWITCHPORT.INTCTRL = (SWITCHPORT.INTCTRL & ~PORT_INT0LVL_gm) | PORT_INT0LVL_LO_gc;
	SWITCHPORT.INT0MASK = 0x0F;

	// Configure LEDs
	PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time
	LEDPORT.PIN0CTRL = PORT_INVEN_bm; // Invert input to turn the leds on when port output value is 1

	LEDPORT.DIRSET = 0xff; 	// Set port as output
	LEDPORT.OUT = 0x01;  // Set initial value

	// Set up RTC timer and overflow interrupt
	CLK.RTCCTRL = (CLK.RTCCTRL & ~CLK_RTCSRC_gm) | CLK_RTCSRC_TOSC_gc; // Choose 1kHz input from external 32kHz oscillator as RTC source as this is most power-efficient.
	CLK.RTCCTRL	|= CLK_RTCEN_bm;	// Enable RTC
	
	// Now we have 1024 ticks per second.	
	// We set the period to 2048, resulting in 1Hz toggling of the LED.
	RTC.PER = 2048;
	RTC.CTRL = (RTC.CTRL & ~RTC_PRESCALER_gm) | RTC_PRESCALER_DIV1_gc; // Set RTC prescaler 1
	RTC.INTCTRL = (RTC.INTCTRL & ~RTC_COMPINTLVL_gm) | RTC_COMPINTLVL_LO_gc; // Enable LO interrupt on compare match
	
	// Set up sleep registers
	SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_PDOWN_gc;
	SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep, else SLEEP-instruction is ineffective.


	// Enable low interrupt level in PMIC and enable global interrupts.
	PMIC.CTRL |= PMIC_LOLVLEN_bm;
	sei();

	// Main loop.
	char pressed = 0;
	while (1) {

// == Button 0 pressed
		if (((SWITCHPORT.IN & SW_TOSC) | pressed) == 0x00) {		
			_delay_ms(5); // Debounce switch
			pressed = 1; // Used for toggling
			LEDPORT.OUTSET = SW_TOSC; // Toggle led
			
			CLK.RTCCTRL = (CLK.RTCCTRL & ~CLK_RTCSRC_gm) | CLK_RTCSRC_TOSC_gc;

// == Button 1 pressed
		} else if (((SWITCHPORT.IN & SW_RCOSC) | pressed) == 0x00) {	
			_delay_ms(5); // Debounce switch
			pressed = 1; // Used for toggling
			LEDPORT.OUT = SW_RCOSC; // Toggle led
			
			CLK.RTCCTRL = (CLK.RTCCTRL & ~CLK_RTCSRC_gm) | CLK_RTCSRC_RCOSC_gc;

 // == Button 2 pressed
		} else if (((SWITCHPORT.IN & SW_ULP) | pressed) == 0x00) {
			_delay_ms(5); // Debounce switch
			pressed = 1; // Used for toggling.
			LEDPORT.OUT = SW_ULP; // Toggle led		

			CLK.RTCCTRL = (CLK.RTCCTRL & ~CLK_RTCSRC_gm) | CLK_RTCSRC_ULP_gc;

// == Buttons released
		} else if ( (SWITCHPORT.IN & (SW_TOSC | SW_RCOSC | SW_ULP )) == 0x07) {
			pressed = 0;
			LEDPORT.OUTCLR = 0x0F;
			sleep();
		}


	}

}
예제 #5
0
int main(void)
{
  //! set the power reduction register to minimize current consumption
  init_power_reduction();
  //! set CPU clock to 32MHz and enables the DFLL32MHz
  clock_init();           
  //! initialize the LCD module
  init_lcd();
  //! display all the segments in LCD
  lcd_show_all();        
  //! initialize the GPIO pins
  init_ioport();
  //! initializes the UART
  init_UART();
  //! load the calibration data from flash
  ADC_CalibrationValues_Load(&ADCA);
  //! get the ADC offset value
  get_offset();
  //! initialize the ADC
  init_ADC();
  //! load the calibration value from eeprom
  init_eeprom();
  //! initilize RTC to external clock and 1 sec interrupt
  rtc_init();
  //! initilize the timer
  init_timer();  

  while(1)
    {
      //! rtc_flag is set
      if (rtc_flag == 1)
      {
        //! perform the calculation of metering paramters
        calculate();
        //for debugging
        if(cover_open_flag ==1)
        PORTD.OUTTGL = PIN3_bm;
        //TCC1.CTRLA = ( TCC1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc;
        TCC1.INTCTRLA = (TCC1.INTCTRLA & ~(TC1_OVFINTLVL_gm | TC1_ERRINTLVL_gm))|TC1_OVFINTLVL0_bm;
        //! if power on detected
        if(power_status_flag == POWER_ON_DETECTED) 
        {
          //! change the clock frequency to 32MHz
          CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );
          //! switch off the battery
          PORTD.PIN4CTRL	= PORT_OPC_WIREDANDPULL_gc;
          //PORTD.OUTSET	= PIN4_bm;
          //! initialize gpio pins
          init_ioport();
          //! change the sleep mode to ideal sleep
          SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm)| SLEEP_SMODE_IDLE_gc;
          //! enable ADC & Timer
          ADC_Enable(&ADCA);
          TCC1.CTRLA = ( TCC1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc;
          //! initialize lcd module
          init_lcd();
          //! update power status flag
          power_status_flag = POWERED_UP;
        }
        //! update the LCD display
        lcd_disp_key();
        tamper_check();
        if( active_power[0] > max_demand )
        {
          max_demand = active_power[0];
        }
        //! check for calibration flag and proceed and call the appropriate calibration funtion
        if(calibration_flag != 0)
        {
          //! checking the calibration flag for calibrating the date & time
          if (calibration_flag == 1)
          { calibrate_time_date();  }
          //! checking the calibration flag for calibrating the voltage
          else if (calibration_flag == 2)
          { calibrate_voltage();    }
          //! checking the calibration flag for calculating the offset value
          else if (calibration_flag == 3)
          { calibrate_no_load();    }
          //! checking the calibration flag for calculating the phase angle variation
          else if (calibration_flag == 4)
          { calibrate_phase();	    }
          //! checking the calibration flag for calculating watt varition
          else if (calibration_flag == 5)
          { calibrate_watt();       }
          else if (calibration_flag == 6)
          //! checking the calibration flag for calibrating the current            
          { calibrate_current();    }
        }
        rtc_flag = 0;
        __watchdog_reset();
      }
      //! checking the power_status, if power off is detected
      else if(power_status_flag == POWER_OFF_DETECTED)
      {
        //! switch on the battery
        PORTD.PIN4CTRL	= PORT_OPC_WIREDAND_gc;
        //PORTD.OUTCLR  = PIN4_bm;
        //! change the sleep mode to power save mode
        SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm)| SLEEP_SMODE_PSAVE_gc;  
        //! switch off the LCD
        lcd_command(LCD_COMMAND,0x02);
        //! change reset the gpio pin
        facilitatePowersaving();
        //! disable the ADC
        ADC_Disable(&ADCA);
        //! disable the timer
        TCC1.CTRLA = ( TCC1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_OFF_gc;
        //! clear all the varilable used in for energy calculation
        meter_flush();
        //! reduce the cpu clock frequency to minimize power consumption
        CLKSYS_Prescalers_Config( CLK_PSADIV_64_gc, CLK_PSBCDIV_1_1_gc );
        //! update power status flag
        power_status_flag = POWER_OFF;
        __watchdog_reset();
      }
      //! goes to sleep
      SLEEP.CTRL |=  SLEEP_SEN_bm;
      asm("sleep");
    }
}