Module PWM_Module.c Description This is a PWM file for ME218B Lab 8 for Team 3. Notes Private definitions PWMTicksPerMS BitsPerNibble MsPerSecond PercentToDec PWM0_GenA_Normal PWM0_GenB_Normal PWM1_GenA_Normal PWM1_GenB_Normal Set0_DC Set100_DC RestoreDC Startup_Period_ms Period_0 Duty_0 CompareA CompareB void PWM_Init(uint8_t NumPWM) //Switch depending for PWM ports // We only want one PWM port. This corresponds to PB6 // start by enabling the clock to the PWM Module (PWM0) // enable the clock to Port B // make sure that Port B is initialized // Select the PWM clock as System Clock/32 // make sure that the PWM module clock has gotten going // disable the PWM while initializing // program generators to go to 1 at rising compare A/B, 0 on falling // compare A/B // Set the PWM period. Since we are counting both up & down, we // initialize the load register to 1/2 the desired total period. We // will also program the match compare registers to 1/2 the desired // high time // Set the initial Duty cycle on A to 50% by programming the compare // value to 1/2 the period to count up (or down). Technically, the // value to program should be Period/2 - DesiredHighTime/2, but since // the desired high time is 1/2 the period, we can skip the subtract // now configure the Port B pin to be PWM outputs // start by selecting the alternate function for PB6 // now choose to map PWM to those pins, this is a mux value of 4 that we // want to use for specifying the function on bits 6 // Enable pin 6 on Port B for digital I/O // make pin 6 on Port B an output // set the up/down count mode, enable the PWM generator and make // both generator updates locally synchronized to zero count // We want 2 PWM ports. This corresponds to PB6 and PB7. // start by enabling the clock to the PWM Module (PWM0) // enable the clock to Port B // make sure that Port B is initialized // Select the PWM clock as System Clock/32 // make sure that the PWM module clock has gotten going // disable the PWM while initializing // program generators to go to 1 at rising compare A/B, 0 on falling // compare A/B // Set the PWM period. Since we are counting both up & down, we // initialize the load register to 1/2 the desired total period. We // will also program the match compare registers to 1/2 the desired // high time // Set the initial Duty cycle on A to 50% by programming the compare // value to 1/2 the period to count up (or down). Technically, the // value to program should be Period/2 - DesiredHighTime/2, but since // the desired high time is 1/2 the period, we can skip the subtract // Set the initial Duty cycle on B to 50% like A // enable the PWM outputs // now configure the Port B pins to be PWM outputs // start by selecting the alternate function for PB6 and PB7 // now choose to map PWM to those pins, this is a mux value of 4 that // we want to use for specifying the function on bits 6 and 7 // Enable pins 6 and 7 on Port B for digital I/O // make pins 6 and 7 on Port B an output // set the up/down count mode, enable the PWM generator and make // both generator updates locally synchronized to zero count void PWM_SetFrequency(uint16_t PWMFreq, uint8_t Group) //Calculate Period_0 value=((MsPerSecond * PWMTicksPerMS) / PWMFreq) //Calculate DesiredHighTime=(Period_0 * Duty_0) / 100 //Calculate CompVal = Period_0 / 2 - DesiredHighTime / 2 //Switch depending which group //If group is DriveMotors // Set the PWM period. Since we are counting both up & down, we initialize // the load register to 1/2 the desired total period. We will also program // the match compare registers to 1/2 the desired high time // Save Period/2 for for PWM0 + PWM 0 Load // modify compare values for PWM0_BASE and PWM_O_0_CMPA //If group is AllServos // Set the PWM period. Since we are counting both up & down, we initialize // the load register to 1/2 the desired total period. We will also program // the match compare registers to 1/2 the desired high time // Save Period/2 for PWM0_BASE + PWM_O_1_LOAD and PWM1_BASE + PWM_O_1_LOAD // modify compare values for PWM0_BASE (PWM_O_1_CMPA and PWM_O_1_CMPB) and PWM1_BASE (PWM_O_1_CMPA and PWM_O_1_CMPB) //If group is RecycleEmitter // Set the PWM period. Since we are counting both up & down, we // initialize the load register to 1/2 the desired total period. We // will also program the match compare registers to 1/2 the desired // high time // Save Period/2 for PWM1_BASE + PWM_O_0_LOAD // modify compare values for (PWM1_BASE + PWM_O_0_CMPA) //If group is RobotDetEmitter // Set the PWM period. Since we are counting both up & down, we // initialize the load register to 1/2 the desired total period. We // will also program the match compare registers to 1/2 the desired // high time // Save Period/2 for PWM1_BASE + PWM_O_2_LOAD // modify compare values for (PWM0_BASE + PWM_O_0_CMPA) void PWM_SetDuty(uint8_t DutyCycle, uint8_t PinNum) // first take care of the duty cycles of 0 or 100 cases: //if DutyCycle equals 0 //Call Set0_DC with PinNum //Else if DutyCycle equals 100 //Call Set100_DC with PinNum //Else // make sure to reset the DC by calling RestoreDC // now change the correct PWM pin based on PinNum //If PinNum is MotorA // calculate what compare value should be for desired duty cycle // store that compare value into PWM port and write in PWM0_BASE + PWM_O_0_CMPA //If PinNum is MotorB // calculate what compare value should be for desired duty cycle // store that compare value into PWM port and write in PWM0_BASE + PWM_O_0_CMPB //If PinNum is RecycleServo // calculate what compare value should be for desired duty cycle // store that compare value into PWM port and write in PWM0_BASE + PWM_O_1_CMPA //If PinNum is TrashServo // calculate what compare value should be for desired duty cycle // store that compare value into PWM port and write in PWM0_BASE + PWM_O_1_CMPB //If PinNum is SortServo // calculate what compare value should be for desired duty cycle // store that compare value into PWM port and write in PWM1_BASE + PWM_O_1_CMPA //If PinNum is FlagServo // calculate what compare value should be for desired duty cycle // store that compare value into PWM port and write in PWM1_BASE + PWM_O_1_CMPB //If PinNum is RecycleEmitter // calculate what compare value should be for desired duty cycle // store that compare value into PWM port and write in PWM1_BASE + PWM_O_0_CMPA static void Set0_DC(uint8_t PinNum) // check for which pin we should be changing // if we want to change MotorA, then make changes to generator A // to program 0% DC, set the action on Zero to set the output to 0 // if we want to change MotorB, then make changes to generator B // to program 0% DC, set the action on Zero to set the output to 0 // if we want to change RecycleServo, then make changes to generator A // to program 0% DC, set the action on Zero to set the output to 0 // if we want to change TrashServo, then make changes to generator B // to program 0% DC, set the action on Zero to set the output to 0 // if we want to change SortServo, then make changes to generator A // to program 0% DC, set the action on Zero to set the output to 0 // if we want to change FlagServo, then make changes to generator B // to program 0% DC, set the action on Zero to set the output to 0 // if we want to change RecycleEmitter, then make changes to generator A // to program 0% DC, set the action on Zero to set the output to 0 static void Set100_DC(uint8_t PinNum) // check for which pin we should be changing // if we want to change MotorA, then make changes to generator A // to program 0% DC, set the action on Zero to set the output to 1 // if we want to change MotorB, then make changes to generator B // to program 0% DC, set the action on Zero to set the output to 1 // if we want to change RecycleServo, then make changes to generator A // to program 0% DC, set the action on Zero to set the output to 1 // if we want to change TrashServo, then make changes to generator B // to program 0% DC, set the action on Zero to set the output to 1 // if we want to change SortServo, then make changes to generator A // to program 0% DC, set the action on Zero to set the output to 1 // if we want to change FlagServo, then make changes to generator B // to program 0% DC, set the action on Zero to set the output to 1 // if we want to change RecycleEmitter, then make changes to generator A // to program 0% DC, set the action on Zero to set the output to 1 static void RestoreDC(uint8_t PinNum) // check for which pin we should be changing // if we want to change MotorA, then make changes to generator A // to restore the previous DC, set the action back to the normal actions // if we want to change MotorB, then make changes to generator B // to restore the previous DC, set the action back to the normal actions // if we want to change RecycleServo, then make changes to generator A // to restore the previous DC, set the action back to the normal actions // if we want to change TrashServo, then make changes to generator B // to restore the previous DC, set the action back to the normal actions // if we want to change SortServo, then make changes to generator A // to restore the previous DC, set the action back to the normal actions // if we want to change FlagServo, then make changes to generator B // to restore the previous DC, set the action back to the normal actions // if we want to change RecycleEmitter, then make changes to generator A // to restore the previous DC, set the action back to the normal actions