Toto je starší verze dokumentu!
Not final
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.
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í.
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); }
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); }