PingPong/TODO.md
2024-09-07 00:09:34 +03:00

4.9 KiB
Raw Blame History

Работа с памятью: V Припаять i2c!!! Сохранение выстрела Загрузка выстрела По аналогии всё остальное

IR: V Добавить press and hold

Проверка железа: Проверить все PWM Проверить функции управления железом setRollersSpeed setScrewkSpeed setPos stopShooting doShot

Логика работы: Правильное переключение выстрелов с учётом repeatCount Переключение выстрелов в программе Переключение программ в макро Правильная пауза

Индикация: Текущий буфер индикации Функция отображения скорости Обратный отсчёт Индикация ошибок

Звук: Звук приёма IR Звук ошибки Звук включения

Ошибки: В некоторый момент PID регулятор выдаёт 0 и двигатель не запускается не зависимо от входного значенияPWM

uint32_t GetTimerClockFrequency(TIM_TypeDef *TIMx) { uint32_t clock_frequency = 0; uint32_t sysclk_frequency = 0; uint32_t hclk_frequency = 0; uint32_t apb1_frequency = 0; uint32_t apb2_frequency = 0;

// Определяем источник системного тактирования (SYSCLK)
switch (RCC->CFGR & RCC_CFGR_SWS) {
    case RCC_CFGR_SWS_HSI: // HSI используется как системный клок
        sysclk_frequency = 8000000; // HSI - 8 MHz
        break;
    case RCC_CFGR_SWS_HSE: // HSE используется как системный клок
        sysclk_frequency = HSE_VALUE; // Предположим, что значение HSE_VALUE определено
        break;
    case RCC_CFGR_SWS_PLL: // PLL используется как системный клок
        // Получаем значение входного тактового сигнала PLL
        if ((RCC->CFGR & RCC_CFGR_PLLSRC) == RCC_CFGR_PLLSRC_HSI_DIV2) {
            sysclk_frequency = 4000000; // HSI/2 - 4 MHz
        } else {
            sysclk_frequency = HSE_VALUE; // HSE_VALUE определено как 8 или 16 MHz
        }
        
        // Получаем множитель PLL
        uint32_t pll_mul = ((RCC->CFGR & RCC_CFGR_PLLMULL) >> 18) + 2;
        sysclk_frequency *= pll_mul;
        break;
    default:
        sysclk_frequency = 8000000; // По умолчанию HSI
        break;
}

// Определяем частоту шины AHB (HCLK)
uint32_t ahb_prescaler = (RCC->CFGR & RCC_CFGR_HPRE) >> 4;
if (ahb_prescaler < 8) {
    hclk_frequency = sysclk_frequency;
} else {
    hclk_frequency = sysclk_frequency >> ((ahb_prescaler - 7));
}

// Определяем частоту шины APB1
uint32_t apb1_prescaler = (RCC->CFGR & RCC_CFGR_PPRE1) >> 8;
if (apb1_prescaler < 4) {
    apb1_frequency = hclk_frequency;
} else {
    apb1_frequency = hclk_frequency >> ((apb1_prescaler - 3));
}

// Определяем частоту шины APB2
uint32_t apb2_prescaler = (RCC->CFGR & RCC_CFGR_PPRE2) >> 11;
if (apb2_prescaler < 4) {
    apb2_frequency = hclk_frequency;
} else {
    apb2_frequency = hclk_frequency >> ((apb2_prescaler - 3));
}

// Определяем частоту для конкретного таймера
if (TIMx == TIM1 || TIMx == TIM8) { // Таймеры на шине APB2
    clock_frequency = (apb2_prescaler == 0 ? apb2_frequency : apb2_frequency * 2);
} else { // Таймеры на шине APB1
    clock_frequency = (apb1_prescaler == 0 ? apb1_frequency : apb1_frequency * 2);
}

return clock_frequency;

}

// Функция для вычисления целевого значения uint32_t CalculateTargetCount(TIM_TypeDef *TIMx, uint32_t freq) { // Проверяем, что частота не равна нулю if (freq == 0) return 0xFFFFFFFF; // Защита от деления на ноль

// Получаем частоту тактового генератора для данного таймера
uint32_t clock_frequency = GetTimerClockFrequency(TIMx);

// Получаем значение предделителя (PSC) и ARR таймера
uint32_t psc = TIMx->PSC;
uint32_t arr = TIMx->ARR;

// Вычисляем частоту работы таймера
uint32_t timer_frequency = clock_frequency / ((psc + 1) * (arr + 1));

// Вычисляем целевое значение счетчика для заданной частоты
uint32_t target_count = timer_frequency / freq;

return target_count;

}