/** \brief Sets the period of the given timer, and restarts it from 0. * * Restarts the timer from 0, incrementing by 1 every timer clock cycle, and * changes the period of the timer to the given value. This also clears any CC * channels on the timer. * * \param[in] timer the timer to set (TIMER0 or TIMER1) * \param[in] period the new timer period (TOP) */ static void SM_timer_set_period(SM_timer_t timer, uint16_t period) { if (timer == SM_TIMER_NEEDLE) { TC_SetCount(&TIMER_RING, 0x0000); TC_SetPeriod(&TIMER_NEEDLE, period); } else { TC_SetCount(&TIMER_RING, 0x0000); TC_SetPeriod(&TIMER_RING, period); } }
void setup_Timer(){ //16 ms TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV8_gc ); //TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1024_gc ); TC_SetPeriod( &TCC0, 0xFA00 ); //Es el periodo o TOP Value para que se active la interrupciĆ³n. (Equivale a 16ms) //TC_SetPeriod( &TCC0, 0x7A12 ); }
void startup(void) { SET_PHASE_STATE_5_MOT2(); TCC0.CNT = 0; while (TCC0.CNT < 65535) {} /* TCF0.CCBBUF = startupPwms[0]; SET_PHASE_STATE_0_MOT2(); TCC0.CNT = 0; while (TCC0.CNT < startupDelays[0]) {} TCF0.CCBBUF = startupPwms[1]; SET_PHASE_STATE_1_MOT2(); TCC0.CNT = 0; while (TCC0.CNT < startupDelays[1]) {} TCF0.CCBBUF = startupPwms[2]; SET_PHASE_STATE_2_MOT2(); TCC0.CNT = 0; while (TCC0.CNT < startupDelays[2]) {} TCF0.CCBBUF = startupPwms[3]; SET_PHASE_STATE_3_MOT2(); TCC0.CNT = 0; while (TCC0.CNT < startupDelays[3]) {} TCF0.CCBBUF = startupPwms[4]; SET_PHASE_STATE_4_MOT2(); TCC0.CNT = 0; while (TCC0.CNT < startupDelays[4]) {} */ TCF0.CCBBUF = startupPwms[5]; TCE0.CCBBUF = startupPwms[5]/2; TC_SetPeriod( &TCD1, 65535 ); //~ xxx TC1_ConfigClockSource( &TCD1, TC_CLKSEL_DIV64_gc ); TC1_ConfigClockSource( &TCD1, TC_CLKSEL_DIV4_gc ); //TC1_ConfigClockSource( &TCD1, TC_CLKSEL_DIV64_gc); TC1_SetOverflowIntLevel (&TCD1, TC_OVFINTLVL_LO_gc); missedCommFlag = 1; SET_PHASE_STATE_0_MOT2(); motor2State = 0; //~ while (TCC0.CNT < startupDelays[5]) {} //~ while (1); }
// This function initializes the PWMs void Init_PWM( void ) { // Set PWM outputs MOTOR_OUTPUT.DIRSET = 0x03; // PD0/PD1 set as outputs // Configure timer TC0_ConfigWGM(&MOTOR_TIMER, TC_WGMODE_SS_gc); TC0_EnableCCChannels(&MOTOR_TIMER, TC0_CCAEN_bm|TC0_CCBEN_bm); TC_SetCompareA(&MOTOR_TIMER, 0); TC_SetCompareB(&MOTOR_TIMER, 0); TC_SetPeriod(&MOTOR_TIMER, MAX_PWM); TC0_ConfigClockSource(&MOTOR_TIMER, TC_CLKSEL_DIV1_gc); // 32MHz }
// Configures PWM output on compare a b and c for single slope pwm, with hires, and clk source as sys clk void configPWM (volatile TC0_t * tc, HIRES_t * hires, uint16_t period) { TC_SetPeriod (tc, period ); TC0_ConfigWGM (tc, TC_WGMODE_NORMAL_gc ); // set to single slope pwm generation mode TC0_EnableCCChannels (tc, TC0_CCAEN_bm); // enable compare A TC0_EnableCCChannels (tc, TC0_CCBEN_bm); // enable compare B TC0_EnableCCChannels (tc, TC0_CCCEN_bm); // enable compare C TC0_EnableCCChannels (tc, TC0_CCDEN_bm); // enable compare D //~ TC0_SetCCAIntLevel (tc, TC_CCAINTLVL_HI_gc); TC0_SetCCBIntLevel (tc, TC_CCBINTLVL_LO_gc); //~ TC0_SetCCCIntLevel (tc, TC_CCCINTLVL_HI_gc); //~ TC0_SetCCDIntLevel (tc, TC_CCDINTLVL_HI_gc); TC0_SetOverflowIntLevel (tc, TC_OVFINTLVL_LO_gc); PMIC.CTRL |= PMIC_HILVLEN_bm; TC0_ConfigClockSource (tc, TC_CLKSEL_DIV1_gc); HIRES_Enable (hires, HIRES_HREN_TC0_gc); }
void battery_init() { PORTD.DIRSET = PIN4_bm | PIN5_bm | PIN6_bm; // battery level indicator PORTD.OUT = 0x00; PORTC.DIRSET = PIN7_bm; // signal to stop the boost converters PORTC.OUTSET = PIN7_bm; // start with the converters stopped to avoid power // surges on the battery. When the voltage recovers // the converters will be enabled again PORTC.DIRCLR = PIN6_bm; // input V_USB_CHG PORTE.DIRCLR = PIN3_bm; // input CHG_STAT // update once for each second (1Hz) TC_SetPeriod(&TCE0, 31250); TC0_ConfigClockSource(&TCE0, TC_CLKSEL_DIV256_gc); TC0_ConfigWGM(&TCE0, TC_WGMODE_NORMAL_gc); TC0_EnableCCChannels(&TCE0, TC0_CCAEN_bm); TC0_SetCCAIntLevel(&TCE0, TC_CCAINTLVL_LO_gc); }
int main( void ) { /* To toggle a LED, set pin 0 as output and high so the LED is default off. */ LEDPORT.OUTSET = PIN0_bm; LEDPORT.DIRSET = PIN0_bm; //Add code here that sets the timer compare value for channel A //ie. CCA register for the TCC0 /* We need to start the counter with correct prescaling, * and make it count to a specific TOP value, as we did in task1. * To do this we use the driver functions supplied in TC_driver.c, study the source * file to see how the timer is configured */ TC_SetPeriod(&TCC0, 0xFFFF); TC0_ConfigClockSource(&TCC0, TC_CLKSEL_DIV64_gc); /* This code turn on the LED on compare match, and turn the LED off on timer overflow */ while(1) { if((TCC0.INTFLAGS & TC0_OVFIF_bm) != 0) { TCC0.INTFLAGS = TC0_OVFIF_bm; // Clear the TC_OVFIF by writing a logical 1 to the flag LEDPORT.OUTSET = PIN0_bm; // Turn off LED } if((TCC0.INTFLAGS & TC0_CCAIF_bm) !=0) { TCC0.INTFLAGS = TC0_CCAIF_bm; //Clear the TC_CCAIF by writing a logical 1 to the flag TCC0.CCABUF += 0x1000; //Update the CCABUF register with a new value to change the LED on time. LEDPORT.OUTCLR = PIN0_bm; //Turn on LED } } }
void TCE0_init() { /* Select a Waveform Genreation mode and the CC channels to use*/ TC0_ConfigWGM( &TCE0, TC_WGMODE_SS_gc ); TC0_EnableCCChannels( &TCE0, TC0_CCAEN_bm); // only CCA is used TC_SetPeriod( &TCE0, 60000); /* The corresponding port pins MUST be output for the Waveform to be visible */ PORTE.DIRSET = 0xFF; PORTE.OUTSET = 0xFF; //set port high to switch LEDs off, take INVEN into account /* To have inverted ouput on some pins we set the corresponding INVEN bit for the pin*/ TC0_ConfigClockSource(&TCE0, TC_CLKSEL_DIV1_gc); }
void configDelayTimer (volatile TC0_t * tc) { TC_SetPeriod (tc, (uint16_t)65535); // set tc period TC0_ConfigWGM (tc, TC_WGMODE_NORMAL_gc); // normal timer countermode TC0_ConfigClockSource (tc, TC_CLKSEL_DIV1024_gc); }
int main( void ) { /* To change the duty cycle for the PWM for the LED control, use a variable to increase/decrease the * CCx registers once for each period */ int16_t pwm_delta = 300; // Add code to select a Single Slope PWM as Waveform Generation mode. // This is done by setting the WGM bits,in the CTRLB register for the TC. /* Add code to enable the CC channels we wish to use. Each channel must be separately enabled * by setting the corresponding CCxEN bits in the CTRLB register for the TC. * Code for enabling CCA is already added, but add code to enable CCB, CCC and CCD */ TCE0.CTRLB |= TC0_CCAEN_bm; //Insert code to enable CC for the other channels, B, C and D. /* The corresponding port pins MUST be ouput for the Waveform to be visible * on the pin. For TCE0 the corresponding port is PORTE, and pin 0 to 3 for * CC channel A to D */ PORTE.DIRSET = 0x0F; /* Note how the inverted signal is always controlled from the Port pin configuration in XMEGA * This can be used with all other peripherals connected to the pin to have inverted output. * Below is example code on how you can set inverted ouput on a pin using the Pin Control Register*/ //PORTE.PIN0CTRL &= ~PORT_INVEN_bm; /* Set a compare value for each compare channel, just as in task2. * The compare value decide the PWM duty cycle for the waveform. * * Code for CC channel A is added, add code for channel B, C, and D * with the compare value 3000 */ TC_SetCompareA(&TCE0, 3000); //Insert function calls to set the other compare values /* Using the TC_driver we set the Period and * start the timer with no prescaling */ TC_SetPeriod(&TCE0, 60000); TC0_ConfigClockSource(&TCE0, TC_CLKSEL_DIV1_gc); while(1) { /* The code check if the overflow flag is set, * if so it clears the flag and sets a new duty cycle for all * CC channels */ /* Check if overflow flag (OVFIF) is set, * clear flag and set a new duty cycle */ if(TC_GetOverflowFlag(&TCE0) != 0) { TC_ClearOverflowFlag(&TCE0); //Clear the IF by writing a logical 1 to the flag if(TCE0.CCA >= 59000) { //Some "random" values above 0 and below TOP is selected pwm_delta = -300; //for the PWM changes, and make the LED look ok. } else if(TCE0.CCA <= 5000) { pwm_delta = +300; } TCE0.CCABUF += pwm_delta; //Change the compare value to change duty cycle TCE0.CCBBUF += pwm_delta; TCE0.CCCBUF += pwm_delta; TCE0.CCDBUF += pwm_delta; } } }
void setup_Timer2(){ //1 min TC1_ConfigClockSource( &TCC1, TC_CLKSEL_DIV1024_gc ); TC_SetPeriod( &TCC1, 0x8000 ); //Es el periodo o TOP Value para que se active la interrupciĆ³n. (Equivale a 1030ms) }
// This function initializes system tick void Init_SysTick( void ) { TC_SetPeriod(&TCF0, 124); // 125 ticks at 31.25KHz = 4ms periods TC0_ConfigClockSource(&TCF0, TC_CLKSEL_DIV1024_gc); // 32MHz/1024=31.25KHz TC0_SetOverflowIntLevel(&TCF0, TC_OVFINTLVL_LO_gc); // Enable interrupts for overflow }