motors Module
Files:
Interface:
Function: InitMotors
Arguments: None.
Returns: None.
Description:Initializes PWM signals for the Motors
Function: SetPWMOffset
Arguments: Character representing the offset value.
Returns: None.
Description:Sets an offset to increase/decrease the magnitude of SimpleMove 
    commands.
Function: SimpleMove
Arguments: Floats representing the Left and Right duty cycles.
Returns: None.
Description:Implements Drive-Brake via and H-bridge. Sends PWM signal to the 
    robot left and right wheel. 
    -100 (full backwards) to 0 (stopped) to 100 (full forwards)
Function: ControlLawMove
Arguments: Characters representing requesting Left and Right duty cycles
Returns: None. 
Description:Sets the module level variables with the requested RPMs for use by 
    the interrupt Encoder.
Function: EncoderInterrupt
Arguments: LongByInts structure representing previous time and LongByInts structure representing current time
Returns: None.
Description:Function to run in Interrupt response routine for either encoder. Takes pointers so it
    can modify the correct variables.
Pseudo-Code:
 
void InitMotors(void)
    Enable PWM0,PWM1,PWM2,PWM3
    Set clock A and B to /4
    Set PWM Output polarity as initially high
    Set clock select to scaled clock A and B
    Set scale for A
    Set scale for B
    Map PWM output to U0, U1, U2, U3                                          
    Set all four PWM periods			      
    Initialize all for duties to 0   
  
void SetPWMOffset(unsigned char Offset)
    Return Offset
void SimpleMove(float LeftDuty, float RightDuty)
    If Left Duty is 0
        Stop Left
    Else If Left Duty > 0
        Make Left go backwards
    Else 
        Make Left go forwards
  
   If Right Duty is 0
        Stop Right
    Else If Right Duty > 0
        Make Right go backwards
    Else 
        Make Right go forwards
        
void ControlLawMove(char RequestedLeftRPM, char RequestedRightRPM)
   Set LeftRPMTarget to static variable RequestedLeftRPM
   Set RightRPMTarget to static variable RequestedRightRPM
    
static unsigned char EncoderInterrupt(LongByInts *LastTime,LongByInts ThisTime)
   If TOF is pending, and captured time after rollover handle TOF
       Increment overflow counter
       Clear flag
   Calculate Period between encoder ticks	 
   Calculate Encoder Ticks Per Minute
   Return Encoder Revolutions per Minute
        
Interrupts:
void interrupt _Vec_tim1ovf Tim0OverflowInterrupt(void)
Increments the overflow counter for timer 0, for absolute timing purposes
   Increment Overflow Counter
   Clear Overflow interrup flag
void interrupt _Vec_tim0ch4 LeftEncoder(void)
void interrupt _Vec_tim0ch5 RightEncoder(void)
Interrupt response routine for the Right Encoder - input capture
					 
   Set ThisTime to value of timer tick counter
   Call EncoderInterrupt function
   Calculate the difference between the current RPM and the previosuly measured RPM			
   Calculate LeftRPM and RightRPM
       Ignore "average out" misreads, indicated by spikes in RPM
   Start Encoder Timer
   Clear interrupt flag
void interrupt _Vec_tim0ch6 ControlLaw(void)
Interrupt response routine for updating control laws every 100ms - output compare
   
   Clear interrupt flag
   Enable Interrupts
   
   If Left Encode Timer is Expired
       Set LeftRPM to 0
   Else
       Set ThisRPM to LeftRPM;
   Calculate RPMError as LeftRPMTarget - ThisRPM;	 
   Update Error Sum as LeftSumError += RPMError
   Calculate LeftDutyRequest as ((RPMError * pGain) + (LeftSumError * iGain));
   Implement Anti-windup
   If Right Encode Timer is Expired
       Set RightRPM to 0
   Else
       Set ThisRPM to RightRPM;
   Calculate RPMError as RightRPMTarget - ThisRPM;	  
   Update Error Sum as RightSumError += RPMError
   Calculate RightDutyRequest as ((RPMError * pGain) + (RightSumError * iGain));
   Implement Anti-windup
  
   Call SimpleMove with LeftDutyRequest and RightDutyRequest
   Schedule next output compare event