コード例 #1
0
// Initialize timer 1 and the edge_array structure to output pulses.
//*********************************************************************
void pulse_and_edge_init ( void )
{
  uint16_t temp_u16 ;
    
  // Initial edge array setup.
  // Init edge times for all on-edges.
  edge_array [  0 ] . edge_time = US_TO_CYCLES(BANK_TO_BANK_DELTA_US * 0);
  edge_array [  9 ] . edge_time = US_TO_CYCLES(BANK_TO_BANK_DELTA_US * 1);
  edge_array [ 18 ] . edge_time = (uint16_t)US_TO_CYCLES(BANK_TO_BANK_DELTA_US * 2);
  edge_array [ 27 ] . edge_time = (uint16_t)US_TO_CYCLES(BANK_TO_BANK_DELTA_US * 3);
  // Init edge times for no-pulse edges (these edges mark time during
  // the 10ms interval without pulses).
  edge_array [ 36 ] . edge_time = (uint16_t)US_TO_CYCLES(BANK_TO_BANK_DELTA_US * 4);
  edge_array [ 37 ] . edge_time = (uint16_t)US_TO_CYCLES(12000);
  edge_array [ 38 ] . edge_time = (uint16_t)US_TO_CYCLES(16000);
  edge_array [ 39 ] . edge_time = (uint16_t)US_TO_CYCLES(19900);
  // Init the function pointers for the no-pulse edges
  edge_array[36].function_ptr =
    edge_array[37].function_ptr =
    edge_array[38].function_ptr =
    edge_array[39].function_ptr = (uint16_t)no_pulse;

  // Init remaining edges based on no pulses
  copy_pulses_to_sorted_edges ( 0, 0 ) ;
  set_edge_data_and_function_ptr ( 0, 0 ) ;
  copy_pulses_to_sorted_edges ( 8, 9 ) ;
  set_edge_data_and_function_ptr ( 9, 2 ) ;
  copy_pulses_to_sorted_edges ( 16, 18 ) ;
  set_edge_data_and_function_ptr ( 18, 4 ) ;
  copy_pulses_to_sorted_edges ( 24, 27 ) ;
  set_edge_data_and_function_ptr ( 27, 6 ) ;

  // First OCR1A is at the 10ms point, after all servo pulses are done
  edge_data_ptr = (uint16_t) ( & edge_array [ 36 ] ) ;

  // Init TCNT1 and OCR1A.  Note that the order of accesses for high/low
  // bytes of these 16-bit registers is important.  High bytes must be
  // written first.  Assume interrupts are disabled.
  temp_u16 = edge_array [ 36 ] . edge_time - NCYLES_ISR_PRE_EDGE ;
  TCNT1H = temp_u16 >> 8 ;
  TCNT1L = temp_u16 ;
  OCR1AH = temp_u16 >> 8 ;
  OCR1AL = temp_u16 ;

  // Reset the output compare flag if set
  TIFR1 = _BV(OCF1A);
	
  // Enable the output compare interrupt
  TIMSK1 |= _BV(OCIE1A);
}
コード例 #2
0
void SERVO_CONTROLLER_Init (SERVO_CONTROLLER_Frequency frequency)
{
    //Timers init
    SC_TIM1_Init(frequency);
    SC_TIM2_Init(frequency);
    SC_TIM3_Init(frequency);
    SC_TIM4_Init(frequency);
    
    //Channels init
    for (int i = 0; i < SERVO_TotalChannelsNum; i++)
    {
        SERVO_Channel *ch = &servo_channels[i];
        ch->pulseWidth_us = DEGREES_0_PULSE_US;
        ch->pulseCycles = US_TO_CYCLES(DEGREES_0_PULSE_US);
    }
}
コード例 #3
0
void SERVO_CONTROLLER_SetChannel (SERVO_ChannelId channel, uint16_t microseconds)
{
    SERVO_Channel *ch = &servo_channels[channel];
    TIM_HandleTypeDef *htim = tim_handlers_table[channel];
    int32_t timChannel = tim_channels_table[channel];
    
    if (!htim || timChannel < 0)
    {
        return;
    }
    
    uint16_t cycles = US_TO_CYCLES(microseconds);
    
    ch->pulseWidth_us = microseconds;
    ch->pulseCycles = cycles;
    
    /*
     * HAL driver set the Preload enable bit for all channels.
     * So we can write value directly to CCRx register.
     */
    switch (timChannel)
    {
        case TIM_CHANNEL_1:
            htim->Instance->CCR1 = cycles;
            break;
        case TIM_CHANNEL_2:
            htim->Instance->CCR2 = cycles;
            break;
        case TIM_CHANNEL_3:
            htim->Instance->CCR3 = cycles;
            break;
        case TIM_CHANNEL_4:
            htim->Instance->CCR4 = cycles;
            break;
        default:
            break;
    }
}