Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2015:rot-control

Toto je starší verze dokumentu!


Not final

Modul pro řízení mechanického rotačního systému

  • David Krolák
  • xkrola00@stud.feec.vutbr.cz

Zadání

Prostřednictvím vývojové desky vhodně zvoleného mikrokontroléru s architekturou ARM realizujte řízení mechanického rotačního systému, skládajícího se z DC motorku a inkrementálního enkodéru. Implementujte funkce otáčení zvolenou rychlostí, natočení o požadovaný úhel a ukládání aktuální pozice v závislosti na synchronizačním signálu.

Úvod

Uvedený projekt je součástí diplomové práce na téma Modul pro verifikaci rotačních pozičních senzorů. Výstupem této práce je navrhnout řídící modul včetně komunikačního rozhraní k ovládání rotačního systému skládajícího se ze stejnosměrného motorku, inkrementálního kodéru a lineárního servozesilovače udržující nastavené otáčky konstantní.

Hardware

Text Rotační systém Text Aplikace modulu Text Koncept modulu Text Propojení s kitem

Firmware

static int8_t CDC_Control_HS  (uint8_t cmd, uint8_t* pbuf, uint16_t length)
{
  /* USER CODE BEGIN 10 */
  switch (cmd)
  {
    ...   
    case CDC_SET_LINE_CODING:
    /* Add your code here */
    tempbuf[0] = pbuf[0];
    tempbuf[1] = pbuf[1];
    tempbuf[2] = pbuf[2];
    tempbuf[3] = pbuf[3];
    tempbuf[4] = pbuf[4];
    tempbuf[5] = pbuf[5];
    tempbuf[6] = pbuf[6];
    break;
 
  case CDC_GET_LINE_CODING:
    /* Add your code here */
    pbuf[0] = tempbuf[0];
    pbuf[1] = tempbuf[1];
    pbuf[2] = tempbuf[2];
    pbuf[3] = tempbuf[3];
    pbuf[4] = tempbuf[4];
    pbuf[5] = tempbuf[5];
    pbuf[6] = tempbuf[6];
    break;    
    ...
  }
 
  return (USBD_OK);
  /* USER CODE END 10 */
}  
static int8_t CDC_Receive_HS (uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 11 */
  /* Loopback */
  CDC_Transmit_HS(Buf, *Len);
  USBD_CDC_ReceivePacket(hUsbDevice_1);
 
  /* Get data from the VCP in register */
  CDC_data_in[CDC_data_count] = UserRxBufferHS[0];
 
  if(CDC_data_in[CDC_data_count] == RETURN)
  {
      CDC_command_ready = TRUE;
      CDC_data_count = 0;
  }
  else
  {
      CDC_data_count++;
  }
 
  return (USBD_OK);
  /* USER CODE END 11 */
}
void CDC_Send_HS(char* Buf, uint16_t Len)
{
    static uint8_t sent    = 0;
    static uint8_t try_cnt = 0;
 
    while(!sent)
    {
        /* Check if is possible send data ten times maximally */
        if(((USBD_CDC_HandleTypeDef*)(hUsbDeviceHS.pClassData))->TxState == 0)
        {
            /* Data send with value check */
            if(CDC_Transmit_HS((uint8_t*)(Buf), Len) == USBD_OK)
            {
                sent = 1;
            }
        }
        else if(try_cnt > 9)
        {
            sent = 1;
        }
 
        try_cnt++;
        if(sent == 0)
        {
            HAL_Delay(1);
        }
    }
}
void MX_TIM8_Init(void)
{
  TIM_Encoder_InitTypeDef sConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
 
  htim8.Instance               = TIM8;
  htim8.Init.Prescaler         = 0;
  htim8.Init.CounterMode       = TIM_COUNTERMODE_UP;
  htim8.Init.Period            = Encoder_rep_res;
  htim8.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;
  htim8.Init.RepetitionCounter = 0;
 
  sConfig.EncoderMode  = TIM_ENCODERMODE_TI12;
  sConfig.IC1Polarity  = TIM_ICPOLARITY_RISING;
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC1Filter    = 0;
  sConfig.IC2Polarity  = TIM_ICPOLARITY_RISING;
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC2Filter    = 0;
 
  HAL_TIM_Encoder_Init(&htim8, &sConfig);
 
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig);
 
  /* Enable update interrupt */
  __HAL_TIM_CLEAR_FLAG(&htim8, TIM_SR_UIF);
  __HAL_TIM_ENABLE_IT(&htim8, TIM_DIER_UIE);
}
void MX_FMC_Init(void)
{
  FMC_SDRAM_TimingTypeDef  SdramTiming;
  FMC_SDRAM_CommandTypeDef Command;
 
  /** Perform the SDRAM1 memory initialization sequence
  */
  hsdram1.Instance                = FMC_SDRAM_DEVICE;
 
  /* hsdram1.Init */
  hsdram1.Init.SDBank             = FMC_SDRAM_BANK2;
  hsdram1.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8;
  hsdram1.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;
  hsdram1.Init.MemoryDataWidth    = FMC_SDRAM_MEM_BUS_WIDTH_16;
  hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  hsdram1.Init.CASLatency         = FMC_SDRAM_CAS_LATENCY_3;
  hsdram1.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  hsdram1.Init.SDClockPeriod      = FMC_SDRAM_CLOCK_PERIOD_2;
  hsdram1.Init.ReadBurst          = FMC_SDRAM_RBURST_DISABLE;
  hsdram1.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_1;
 
  /* SDRAM Timing configuration for 84 MHz (11.9 ns) of SD clock frequency (168MHz/2) */
  /* TMRD: 2 clock cycles */
  SdramTiming.LoadToActiveDelay    = 2;
  /* TXSR: min = 70 ns (7 times 11.9 ns) */
  SdramTiming.ExitSelfRefreshDelay = 7;
  /* TRAS: min = 42 ns (4 times 11.9 ns) */
  SdramTiming.SelfRefreshTime      = 4;
  /* TRC:  min = 63 ns (7 times 11.9 ns) */
  SdramTiming.RowCycleDelay        = 7;
  /* TWR:  2 Clock cycles */
  SdramTiming.WriteRecoveryTime    = 2;
  /* TRP:  15 ns => 2 times 11.9 ns */
  SdramTiming.RPDelay              = 2;
  /* TRCD: 15 ns => 2 times 11.9 ns */
  SdramTiming.RCDDelay             = 2;
 
  HAL_SDRAM_Init(&hsdram1, &SdramTiming);
 
  /* Send commands to the SDRAM */
  /* 1/ SDRAM clock enable command */
  Command.CommandMode            = FMC_SDRAM_CMD_CLK_ENABLE;
  Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;
  Command.AutoRefreshNumber      = 1;
  Command.ModeRegisterDefinition = 0;
 
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
  /* 2/ Insert 100 ms delay */
  HAL_Delay(100);
 
  /* 3/ Configure a PALL (precharge all) command */
  Command.CommandMode            = FMC_SDRAM_CMD_PALL;
  Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;
  Command.AutoRefreshNumber      = 1;
  Command.ModeRegisterDefinition = 0;
 
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
  /* 4/ Configure a Auto-Refresh command */
  Command.CommandMode            = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;
  Command.AutoRefreshNumber      = 8;
  Command.ModeRegisterDefinition = 0;
 
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
  /* 5/ Program the external memory mode register */
  Command.CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;
  Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;
  Command.AutoRefreshNumber      = 1;
  Command.ModeRegisterDefinition = (uint32_t)SDRAM_REG_VALUE;
 
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
  /* 6/ Set the refresh rate counter */
  HAL_SDRAM_ProgramRefreshRate(&hsdram1, REFRESH_COUNT);
  HAL_Delay(100);
}

Test SDRAM 8 MB

static void Encoder_Emulator_Init(TIM_HandleTypeDef* htim)
{
  /* Initialize TIM1 peripheral */
  htim->Instance           = TIM1;
  htim->Init.Period        = EMU_PERIOD;
  htim->Init.Prescaler     = PSC;
  htim->Init.ClockDivision = 0;
  htim->Init.CounterMode   = TIM_COUNTERMODE_UP;
 
  HAL_TIM_OC_Init(htim);
 
  /* Configure the output compare channels */
  /* Output compare toggle mode configuration: Channel1 */
  sConfigEmulator.OCMode     = TIM_OCMODE_TOGGLE;
  sConfigEmulator.Pulse      = (EMU_PERIOD * 1)/4;
  sConfigEmulator.OCPolarity = TIM_OCPOLARITY_LOW;
 
  HAL_TIM_OC_ConfigChannel(htim, &sConfigEmulator, TIM_CHANNEL_2);
 
  /* Output compare toggle mode configuration: Channel2 */
  sConfigEmulator.Pulse      = (EMU_PERIOD * 3)/4;
  HAL_TIM_OC_ConfigChannel(htim, &sConfigEmulator, TIM_CHANNEL_3);
}

Ukázka činnosti

Text Test programu s emulovaným kodérem

Zdrojové soubory

Závěr

2015/rot-control.1453050400.txt.gz · Poslední úprava: 2016/01/17 18:06 autor: David Krolák