void TIMER1_IRQHandler(void) { TIMER_CompareBufSet(TIMER1, 0, PWMratio); TIMER_CompareBufSet(TIMER1, 1, PWMratio); TIMER_IntClear(TIMER1, TIMER_IF_OF); //demoCycle(); }
/**************************************************************************//** * @brief TIMER0_IRQHandler * Interrupt Service Routine TIMER0 Interrupt Line *****************************************************************************/ void TIMER0_IRQHandler(void) { /* Clear flag for TIMER0 overflow interrupt */ TIMER_IntClear(TIMER0, TIMER_IF_OF); TIMER_CompareBufSet(TIMER0, 1, value_left_wheel); TIMER_CompareBufSet(TIMER0, 2, value_right_wheel); }
/**************************************************************************//** * @brief TIMER0_IRQHandler * Interrupt Service Routine TIMER0 Interrupt Line *****************************************************************************/ void TIMER2_IRQHandler(void) { uint32_t compareValue; /* Clear flag for TIMER0 overflow interrupt */ TIMER_IntClear(TIMER2, TIMER_IF_OF); TIMER_CompareBufSet(TIMER2, 0, TIMER_CaptureGet(TIMER2, 0)); TIMER_CompareBufSet(TIMER2, 1, TIMER_CaptureGet(TIMER2, 1)); }
void motor_stop(void *ptr) { TIMER_CompareBufSet(TIMER2, 0, 0); GPIO_PinOutClear(gpioPortA, 8); light_state &= ~MOTOR_ON; if(light_state == 0) { TIMER_Enable(TIMER2,false); CMU_ClockEnable(cmuClock_TIMER2, false); } }
void pwmout_write_channel(uint32_t channel, float value) { uint32_t width_cycles = 0; if (value < 0.0f) { width_cycles = 0; } else if (value >= 1.0f) { width_cycles = PWM_TIMER->TOPB + 1; } else { width_cycles = (uint16_t)((float)PWM_TIMER->TOPB * value); } TIMER_CompareBufSet(PWM_TIMER, channel, width_cycles); }
//================================================================================ // TIMER1_enter_DefaultMode_from_RESET //================================================================================ extern void TIMER1_enter_DefaultMode_from_RESET(void) { // $[TIMER1 initialization] TIMER_Init_TypeDef init = TIMER_INIT_DEFAULT; init.enable = 0;//初始化完成后不使能 init.debugRun = 0; init.dmaClrAct = 0; init.sync = 0; init.clkSel = timerClkSelHFPerClk;//HFPERCLK时钟 init.prescale = timerPrescale2; //2分频 init.fallAction = timerInputActionNone; init.riseAction = timerInputActionNone; init.mode = timerModeUp; init.quadModeX4 = 0; init.oneShot = 0; // [TIMER1 initialization]$ // $[TIMER1 CC0 init] TIMER_InitCC_TypeDef initCC0 = TIMER_INITCC_DEFAULT; initCC0.prsInput = false; initCC0.edge = timerEdgeBoth; initCC0.mode = timerCCModePWM; initCC0.eventCtrl = timerEventEveryEdge; initCC0.filter = 0; initCC0.cofoa = timerOutputActionNone; initCC0.cufoa = timerOutputActionNone; initCC0.cmoa = timerOutputActionToggle; initCC0.coist = 0; initCC0.outInvert = 0; TIMER_InitCC(TIMER1, 0, &initCC0); // [TIMER1 CC0 init]$ /* Route CC0 to location 0 (PC11) and enable pin */ TIMER1->ROUTE |= (TIMER_ROUTE_CC0PEN | TIMER_ROUTE_LOCATION_LOC0); /* Set Top Value */ TIMER_TopSet(TIMER0, 8000000/PWM_FREQ); //PWM频率设定,此处8M是HFPERCLK频率,待定 /* Set compare value starting at 0 - it will be incremented in the interrupt handler */ TIMER_CompareBufSet(TIMER0, 0, 0); /* Enable overflow interrupt */ TIMER_IntEnable(TIMER0, TIMER_IF_OF); /* Enable TIMER0 interrupt vector in NVIC */ NVIC_EnableIRQ(TIMER0_IRQn); TIMER_Init(TIMER1, &init); }
void motor_on(uint8_t level, clock_time_t length) { CMU_ClockEnable(cmuClock_TIMER2, true); TIMER_Enable(TIMER2,true); if (level > 16) level = 16; if (level == 0) { motor_stop(NULL); } else { TIMER_CompareBufSet(TIMER2, 0, level*200); if (length > 0) ctimer_set(&motor_timer, length, motor_stop, NULL); } }
int main(void) { CHIP_Init(); CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_TIMER1, true); CMU_ClockEnable(cmuClock_TIMER3, true); // Set up TIMER1 for timekeeping TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT; timerInit.prescale = timerPrescale1024; TIMER_IntEnable(TIMER1, TIMER_IF_OF); // Enable TIMER1 interrupt vector in NVIC NVIC_EnableIRQ(TIMER1_IRQn); // Set TIMER Top value TIMER_TopSet(TIMER1, ONE_SECOND_TIMER_COUNT); TIMER_Init(TIMER1, &timerInit); // Wait for the timer to get going while (TIMER1->CNT == 0) ; // Enable LED output GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 0); // Create the object initializer for LED PWM TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT; timerCCInit.mode = timerCCModePWM; timerCCInit.cmoa = timerOutputActionToggle; // Configure TIMER3 CC channel 2 TIMER_InitCC(TIMER3, TIMER_CHANNEL, &timerCCInit); // Route CC2 to location 1 (PE3) and enable pin for cc2 TIMER3->ROUTE |= (TIMER_ROUTE_CC2PEN | TIMER_ROUTE_LOCATION_LOC1); // Set Top Value TIMER_TopSet(TIMER3, TIMER_TOP); // Set the PWM duty cycle here! TIMER_CompareBufSet(TIMER3, TIMER_CHANNEL, 0); // Create a timerInit object, based on the API default TIMER_Init_TypeDef timerInit2 = TIMER_INIT_DEFAULT; timerInit2.prescale = timerPrescale256; TIMER_Init(TIMER3, &timerInit2); enum mode_values { RAMPING_UP, HIGH, RAMPING_DOWN, LOW}; // Check for properly sized constants uint16_t delta = MAX_BRIGHTNESS - MIN_BRIGHTNESS; if ( delta == 0 || RAMP_UP_TIME_MS % delta || RAMP_DOWN_TIME_MS % delta) { DEBUG_BREAK } // Set the initial condition uint16_t mode = RAMPING_UP; uint32_t time_step = RAMP_UP_TIME_MS / delta; uint16_t brightness = MIN_BRIGHTNESS; TIMER_CompareBufSet(TIMER3, TIMER_CHANNEL, brightness); uint64_t mode_timeout = set_ms_timeout(RAMP_UP_TIME_MS); while (1) { switch (mode) { case RAMPING_UP: delay_ms(time_step); brightness++; TIMER_CompareBufSet(TIMER3, TIMER_CHANNEL, brightness); if (expired_ms(mode_timeout)) { mode = HIGH; mode_timeout = set_ms_timeout(HIGH_DURATION_MS); } break; case HIGH: if (expired_ms(mode_timeout)) { mode = RAMPING_DOWN; time_step = RAMP_DOWN_TIME_MS / delta; mode_timeout = set_ms_timeout(RAMP_DOWN_TIME_MS); } break; case RAMPING_DOWN: delay_ms(time_step); brightness--; TIMER_CompareBufSet(TIMER3, TIMER_CHANNEL, brightness); if (expired_ms(mode_timeout)) { mode = LOW; mode_timeout = set_ms_timeout(LOW_DURATION_MS); } break; case LOW: if (expired_ms(mode_timeout)) { mode = RAMPING_UP; time_step = RAMP_UP_TIME_MS / delta; mode_timeout = set_ms_timeout(RAMP_UP_TIME_MS); } break; } } }
void initPWM() // Brightness should be less than TIMER_TOP (1024) { /* Enable clocks */ CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO; CMU_ClockEnable(cmuClock_TIMER1, true); /* Set pins */ GPIO_PinModeSet(gpioPortE,10,gpioModePushPull,1); GPIO_PinModeSet(gpioPortE,11,gpioModePushPull,1); /* Select CC channel parameters */ TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventEveryEdge, .edge = timerEdgeBoth, .prsSel = timerPRSSELCh0, .cufoa = timerOutputActionNone, .cofoa = timerOutputActionNone, .cmoa = timerOutputActionToggle, .mode = timerCCModePWM, .filter = false, .prsInput = false, .coist = false, .outInvert = false, }; /* Configure CC channels */ TIMER_InitCC(TIMER1, 0, &timerCCInit); TIMER_InitCC(TIMER1, 1, &timerCCInit); /* Set which pins will be set by the timer */ TIMER1->ROUTE = TIMER_ROUTE_CC0PEN | TIMER_ROUTE_CC1PEN | TIMER_ROUTE_LOCATION_LOC1; /* Set Top Value */ TIMER_TopSet(TIMER1, TIMER_TOP); /* Set compare value starting at top - it will be incremented in the interrupt handler */ TIMER_CompareBufSet(TIMER1, 0, TIMER_TOP + 1); TIMER_CompareBufSet(TIMER1, 1, TIMER_TOP + 1); /* Select timer parameters */ TIMER_Init_TypeDef timerInit = { .enable = true, .debugRun = false, .prescale = timerPrescale16, .clkSel = timerClkSelHFPerClk, .fallAction = timerInputActionNone, .riseAction = timerInputActionNone, .mode = timerModeUp, .dmaClrAct = false, .quadModeX4 = false, .oneShot = false, .sync = false, }; /* Enable overflow interrupt */ TIMER_IntEnable(TIMER1, TIMER_IF_OF); TIMER_IntClear(TIMER1, TIMER_IF_OF); /* Enable TIMER1 interrupt vector in NVIC */ NVIC_EnableIRQ(TIMER1_IRQn); /* Configure timer */ TIMER_Init(TIMER1, &timerInit); }
void InitAudioPWM(void) { CMU_ClockEnable(cmuClock_TIMER1, true); /* Select CC channel parameters */ TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventEveryEdge, .edge = timerEdgeBoth, .prsSel = timerPRSSELCh0, .cufoa = timerOutputActionNone, .cofoa = timerOutputActionNone, .cmoa = timerOutputActionToggle, .mode = timerCCModePWM, .filter = false, .prsInput = false, .coist = false, .outInvert = false, }; /* Configure CC channel 0 */ TIMER_InitCC(TIMER1, 0, &timerCCInit); TIMER_InitCC(TIMER1, 1, &timerCCInit); //TIMER_InitCC(TIMER0, 2, &timerCCInit); // TIMER3->ROUTE |= (TIMER_ROUTE_CC0PEN | TIMER_ROUTE_CC1PEN | TIMER_ROUTE_CC2PEN | TIMER_ROUTE_LOCATION_LOC0); TIMER1->ROUTE = TIMER_ROUTE_CC0PEN | TIMER_ROUTE_CC1PEN | TIMER_ROUTE_LOCATION_LOC1; /* Set Top Value */ TIMER_TopSet(TIMER1, 255);//384 /* Set compare value starting at top - it will be incremented in the interrupt handler */ TIMER_CompareBufSet(TIMER1, 0, 256);//385 TIMER_CompareBufSet(TIMER1, 1, 256);//385 //TIMER_CompareBufSet(TIMER3, 2, RGB_PWM_TIMER_TOP + 1); /* Select timer parameters */ TIMER_Init_TypeDef timerInit = { .enable = true, .debugRun = false, .prescale = timerPrescale8, .clkSel = timerClkSelHFPerClk, .fallAction = timerInputActionNone, .riseAction = timerInputActionNone, .mode = timerModeUp, .dmaClrAct = false, .quadModeX4 = false, .oneShot = false, .sync = false, }; ///* Enable overflow interrupt */ TIMER_IntEnable(TIMER1, TIMER_IF_OF); TIMER_IntClear(TIMER1, TIMER_IF_OF); /* Enable TIMER0 interrupt vector in NVIC */ NVIC_EnableIRQ(TIMER1_IRQn); /* Configure timer */ TIMER_Init(TIMER1, &timerInit); } void TIMER1_IRQHandler(void) { int audio_Sample = 0; if(toPlay > 0) { audio_Sample = buff[(iterator = next(iterator))]; toPlay--; } else { audio_Sample = 0; } TIMER_CompareBufSet(TIMER1, 0, (audio_Sample)); TIMER_IntClear(TIMER1, TIMER_IF_OF); }
/**************************************************************************//** * @brief Main function * Main is called from __iar_program_start, see assembly startup file *****************************************************************************/ int motor_init(void) { uint32_t top_value = 0; /* Enable clock for GPIO module */ CMU_ClockEnable(cmuClock_GPIO, true); /* Enable clock for TIMER0 module */ CMU_ClockEnable(cmuClock_TIMER0, true); /* Set CC1 location 3 pin (PD2) as output */ //Left wheel GPIO_PinModeSet(gpioPortD, 2, gpioModePushPull, 0); /* Set CC2 location 3 pin (PD3) as output */ //Right wheel GPIO_PinModeSet(gpioPortD, 3, gpioModePushPull, 0); /* Select CC channel parameters */ TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventEveryEdge, .edge = timerEdgeBoth, .prsSel = timerPRSSELCh0, .cufoa = timerOutputActionNone, .cofoa = timerOutputActionNone, .cmoa = timerOutputActionToggle, .mode = timerCCModePWM, .filter = false, .prsInput = false, .coist = false, .outInvert = false, }; /* Configure CC channel 0 */ TIMER_InitCC(TIMER0, 1, &timerCCInit); TIMER_InitCC(TIMER0, 2, &timerCCInit); /* Route CC0 to location 3 (PD1) and enable pin */ TIMER0->ROUTE |= (TIMER_ROUTE_CC2PEN | TIMER_ROUTE_CC1PEN | TIMER_ROUTE_LOCATION_LOC3); /* Set Top Value */ TIMER_TopSet(TIMER0, CMU_ClockFreqGet(cmuClock_HFPER)/PWM_FREQ); top_value = CMU_ClockFreqGet(cmuClock_HFPER)/PWM_FREQ; forward_value = ((18*top_value)/200); backward_value = ((12*top_value)/200); steady_value = ((15*top_value)/200); /* Set compare value starting at 0 - it will be incremented in the interrupt handler */ TIMER_CompareBufSet(TIMER0, 1, 0); TIMER_CompareBufSet(TIMER0, 2, 0); /* Select timer parameters */ TIMER_Init_TypeDef timerInit = { .enable = true, .debugRun = true, .prescale = timerPrescale64, .clkSel = timerClkSelHFPerClk, .fallAction = timerInputActionNone, .riseAction = timerInputActionNone, .mode = timerModeUp, .dmaClrAct = false, .quadModeX4 = false, .oneShot = false, .sync = false, }; /* Enable overflow interrupt */ TIMER_IntEnable(TIMER0, TIMER_IF_OF); /* Enable TIMER0 interrupt vector in NVIC */ NVIC_EnableIRQ(TIMER0_IRQn); /* Configure timer */ TIMER_Init(TIMER0, &timerInit); return 0; }
void backlight_init() { /*init and setup PA9(Backlight) and PA8(Motor) to GPIO output and PWM*/ /* Enable clock for TIMER0 module */ CMU_ClockEnable(cmuClock_TIMER2, true); /* Set location 4 pin (PD7) as output */ GPIO_PinModeSet(gpioPortA, 8, gpioModePushPull, 0); GPIO_PinModeSet(gpioPortA, 9, gpioModePushPull, 0); /*PA8 PA9 at TIMER2 Location0 CC0(PA8) and CC1(PA9)*/ /* Select CC channel parameters */ TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventEveryEdge, .edge = timerEdgeBoth, .prsSel = timerPRSSELCh0, .cufoa = timerOutputActionNone, .cofoa = timerOutputActionNone, .cmoa = timerOutputActionToggle, .mode = timerCCModePWM, .filter = false, .prsInput = false, .coist = false, .outInvert = false, }; /* Configure CC channel 0 CC0 for PA8 */ TIMER_InitCC(TIMER2, 0, &timerCCInit); /* Configure CC channel 1 CC0 for PA9 */ timerCCInit.prsSel = timerPRSSELCh1; TIMER_InitCC(TIMER2, 1, &timerCCInit); /* Route CC0/CC1 to location 0 (PA8/PA9) and enable pin */ TIMER2->ROUTE |= (TIMER_ROUTE_CC0PEN | TIMER_ROUTE_CC1PEN | TIMER_ROUTE_LOCATION_LOC0); /* Set Top Value */ TIMER_TopSet(TIMER2, TOP); /*Set CCVB = 0 to TIMER2_CC0 and TIMER2_CC1 */ TIMER_CompareBufSet(TIMER2, 0, 0); TIMER_CompareBufSet(TIMER2, 1, 0); /* Select timer parameters */ TIMER_Init_TypeDef timerInit = { .enable = true, .debugRun = true, .prescale = timerPrescale64, .clkSel = timerClkSelHFPerClk, .fallAction = timerInputActionNone, .riseAction = timerInputActionNone, .mode = timerModeUp, .dmaClrAct = false, .quadModeX4 = false, .oneShot = false, .sync = false, }; /* Enable overflow interrupt */ TIMER_IntEnable(TIMER2, TIMER_IF_OF); /* Enable TIMER2 interrupt vector in NVIC */ NVIC_EnableIRQ(TIMER2_IRQn); /* Configure timer */ TIMER_Init(TIMER2, &timerInit); light_state = MOTOR_ON | LIGHT_ON; LIGHTLEVEL = 0; } void backlight_shutdown() { TIMER_CompareBufSet(TIMER2, 0, 0); TIMER_CompareBufSet(TIMER2, 1, 0); GPIO_PinOutClear(gpioPortA, 8); GPIO_PinOutClear(gpioPortA, 9); light_state = 0; TIMER_Enable(TIMER2,false); CMU_ClockEnable(cmuClock_TIMER2, false); } void light_stop(void *ptr) { if (LIGHTLEVEL > 2) { LIGHTLEVEL--; clock_time_t length = (clock_time_t)ptr; ctimer_set(&light_timer, length, light_stop, (void*)length); } else { TIMER_CompareBufSet(TIMER2, 1, 0); GPIO_PinOutClear(gpioPortA, 9); light_state &= ~LIGHT_ON; if(light_state == 0) { TIMER_Enable(TIMER2,false); CMU_ClockEnable(cmuClock_TIMER2, false); } } } void backlight_on(uint8_t level, clock_time_t length) { CMU_ClockEnable(cmuClock_TIMER2, true); TIMER_Enable(TIMER2,true); if (level > 8) level = 8; if (level == 0) { TIMER_CompareBufSet(TIMER2, 1, 0); } else { LIGHTLEVEL = level * 2; TIMER_CompareBufSet(TIMER2, 1, ( LIGHTLEVEL * 100)); if (length > 0) ctimer_set(&light_timer, length, light_stop, (void*)(CLOCK_SECOND/8)); } }
void PWM_Init(PWM_Settings_t PWM_Settings) { /* enable TIMER0 peripheral clock */ CMU_ClockEnable(cmuClock_TIMER0, true); /* Setup Timer Channel Configuration for PWM */ TIMER_InitCC_TypeDef TimerCCInit = { .eventCtrl = timerEventEveryEdge, /* this value will be ignored since we aren't using input capture */ .edge = timerEdgeNone, /* this value will be ignored since we aren't using input capture */ .prsSel = timerPRSSELCh0, /* this value will be ignored since we aren't using PRS */ .cufoa = timerOutputActionNone, /* no action on underflow (up-count mode) */ .cofoa = timerOutputActionSet, /* on overflow, we want the output to go high, but in PWM mode this should happen automatically */ .cmoa = timerOutputActionClear, /* on compare match, we want output to clear, but in PWM mode this should happen automatically */ .mode = timerCCModePWM, /* set timer channel to run in PWM mode */ .filter = false, /* not using input, so don't need a filter */ .prsInput = false, /* not using PRS */ .coist = false, /* initial state for PWM is high when timer is enabled */ .outInvert = false, /* non-inverted output */ }; /* Setup Timer Configuration for PWM */ TIMER_Init_TypeDef TimerPWMSetup = { .enable = true, /* start timer upon configuration */ .debugRun = true, /* run timer in debug mode */ .prescale = timerPrescale1, /* set prescaler to 1 */ .clkSel = timerClkSelHFPerClk, /* set clock source as HFPERCLK */ .fallAction = timerInputActionNone, /* no action from inputs */ .riseAction = timerInputActionNone, /* no action from inputs */ .mode = timerModeUp, /* use up-count mode */ .dmaClrAct = false, /* not using DMA */ .quadModeX4 = false, /* not using Quad Dec. mode */ .oneShot = false, /* not using one shot mode */ .sync = false, /* not synchronizing timer3 with other timers */ }; /* by default */ PWM_SetPeriod(1000ULL, 10000000ULL); TIMER_CounterSet(TIMER0, 0); /* start counter at 0 (up-count mode) */ for (uint8_t CCx = 0; CCx < PWM_NUMBER_OF_CC_CHANNELS; CCx++) { PWM_SetDuty(CCx, 0); TIMER_InitCC(TIMER0, CCx, &TimerCCInit); /* apply channel configuration to Timer0 channel 0 */ } TIMER0->ROUTE = (PWM_Settings.location << _TIMER_ROUTE_LOCATION_SHIFT); if (PWM_Settings.CC0_enable == true) { TIMER0->ROUTE |= TIMER_ROUTE_CC0PEN; } if (PWM_Settings.CC1_enable == true) { TIMER0->ROUTE |= TIMER_ROUTE_CC1PEN; } if (PWM_Settings.CC2_enable == true) { TIMER0->ROUTE |= TIMER_ROUTE_CC2PEN; } TIMER_Init(TIMER0, &TimerPWMSetup); /* apply PWM configuration to timer1 */ } void PWM_TurnOff(PWM_CC_Channel CCx) { TIMER_CompareSet(TIMER0, CCx, 0); TIMER_CompareBufSet(TIMER0, CCx, 0); g_PWM_dutyCycle[CCx] = 0; } void PWM_SetDuty(PWM_CC_Channel CCx, uint32_t duty_miliPercents) { uint32_t duty = (uint32_t)(((uint64_t)g_PWM_Period * (uint64_t)duty_miliPercents) / 10000ULL); TIMER_CompareSet(TIMER0, CCx, 0); TIMER_CompareBufSet(TIMER0, CCx, duty); g_PWM_dutyCycle[CCx] = duty; }