Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Вычисление тактовой частоты APB1

Чт июл 19, 2018 19:52:45

Добрый вечер. У меня keil и мк stm32f405rg. мне нужно в программе в расчётах иметь переменную, которая содержит значение частоты шины APB1, где мой таймер. Я не использую ни куб, ни HAL ни SPL. Просто обычный CMSIS. Знаю что в SPL есть функция, которая вычисляет все эти частоты. Но мне не надо все, а только одна. Поэтому есть ли какая-нибудь константа или переменная, которая содержит в себе это значение? или как бы это можно было вычислить не прибегая к помощи SPL?)

Re: Вычисление тактовой частоты APB1

Чт июл 19, 2018 20:03:43

Я не использую ни куб, ни HAL ни SPL.

Ни DS, ни RM, я правильно понял? :)
Если хочешь сам все вычислить, то нужно смотреть в регистрах RCC какой активен генератор, считать текущую частоту, потом смотреть какие на шинах делители, а для таймеров еще нужно учесть, что частота может умножаться на 2.

Re: Вычисление тактовой частоты APB1

Чт июл 19, 2018 21:13:08

Я не использую ни куб, ни HAL ни SPL.
Это значит никто кроме вас частоты не меняет. Вы их сами поставите и будете знать.

Просто обычный CMSIS.
В любом тулчейне в стартапе есть функция, которая вызывается перед переходом в main(), предназначенная для инициализации железа. Чаще всего это SystemInit() или __low_level_init(). Там и задавайте все нужные делители.

Поэтому есть ли какая-нибудь константа или переменная, которая содержит в себе это значение? или как бы это можно было вычислить не прибегая к помощи SPL?)
Вы можете сами её сделать. Если по ходу программы частоты не меняете, то просто задефайнить константу. Если меняете, то можно в переменную писать установленное значение.

Ну или как Reflector предложил, но это геморрой в рунтайме, да и отталкиваться надо от частоты кварца, которая неизвестна.

Re: Вычисление тактовой частоты APB1

Чт июл 19, 2018 22:39:59

Ну или как Reflector предложил, но это геморрой в рунтайме, да и отталкиваться надо от частоты кварца, которая неизвестна.

Частота шин нужна почти всегда на стадии инициализации, т.е. можно спокойно все вычислять прямо на ходу, в крайнем случае полученное значение можно закешировать. И где это ты видел проекты в которых неизвестна частота кварца? :)

Re: Вычисление тактовой частоты APB1

Чт июл 19, 2018 22:52:15

Кварц 8 мгц

Re: Вычисление тактовой частоты APB1

Чт июл 19, 2018 23:48:36

И где это ты видел проекты в которых неизвестна частота кварца? :)
Я имел в виду, что программа сама частоту кварца определить не может, а полагается на то значение которое программист указал ей. Не, плюс/минус трамвайная остановка конечно можно измерить, но не более.

Re: Вычисление тактовой частоты APB1

Пт июл 20, 2018 00:32:09

Я имел в виду, что программа сама частоту кварца определить не может, а полагается на то значение которое программист указал ей. Не, плюс/минус трамвайная остановка конечно можно измерить, но не более.

Ну ладно, раз "неизвестная" частота кварца такая проблема, то можно от нее избавиться... Допустим тактирование от PLL, PLL от кварца, кварц неизвестен, множитель 8, частота по ходу не меняется, какое значение частоты APB1 задефайнишь в константе? Ты же это предлагал?

Re: Вычисление тактовой частоты APB1

Пт июл 20, 2018 05:54:49

Нет, не это. Я предлагал перестать заниматься рукокодоблудством и не вычислять в рантайме частоты которые вы сами же и задали. В подавляющем количестве случаев все частоты известны на этапе написания инициализации железа. И даже если они потом зачем-то меняются, то не с бухты барахты, а на фиксированные заранее просчитанные конфигурации. А иначе фиг что будет работать вообще.

Re: Вычисление тактовой частоты APB1

Пт июл 20, 2018 06:09:19

Я просто хотел написать так что бы максимально легко было переносить на другие камни.

Re: Вычисление тактовой частоты APB1

Пт июл 20, 2018 07:28:21

Да в любом случае при переносе всё переделывать/перепроверять. Лучший помощник для этого - вменяемые комментарии. Сконфигурировали таймер - напишите на какую частоту и для чего используется. И желательно как можно больше инициализации в одном месте, чтобы не лазить по коду в поисках заветной частоты. Чтобы через год-два не гадать что же тут сделано и как подправить под новый камень. Я как-то так делаю

СпойлерТактирование
Код:
  // ---------- Тактирование ----------
  RCC->CR = RCC_CR_HSITRIM(16) | RCC_CR_HSION | RCC_CR_HSEON; //Включаем HSE = 16 MHz
  while(!(RCC->CR & RCC_CR_HSERDY)); 
  //Задаём источники тактирования и делители
  // SYSCLK = 72 МГц, USB = 48 МГц, PCLK1 = 36 МГц, PCLK2 = 72 МГц,  ADC = 12 МГц
  RCC->CFGR = RCC_CFGR_MCO_NOCLOCK | RCC_CFGR_USBPRE_1d5 | RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC_HSE | RCC_CFGR_ADCPRE_DIV6 |
              RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_SW_HSI;       
  RCC->CR = RCC_CR_HSITRIM(16) | RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_PLLON; // Включаем PLL
  while(!(RCC->CR & RCC_CR_PLLRDY));
  //Переключаемся на PLL с установленными ранее делителями
  RCC->CFGR = RCC_CFGR_MCO_NOCLOCK | RCC_CFGR_USBPRE_1d5 | RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC_HSE | RCC_CFGR_ADCPRE_DIV8 |
              RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_SW_PLL;   
  RCC->CR = RCC_CR_HSITRIM(16) | RCC_CR_HSEON | RCC_CR_PLLON; //Выключаем HSI

Чуть ниже таймеры
Код:
  // Конфигурация системного таймера на 200 Гц
  SysTick->LOAD = CPU_FREQ/200-1;
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
 
  // Конфигурация TIM2 для определения таймаута в UART   
  TIM2->PSC = 128-1;   // 72 МГц / 128 = 1,78 мкс
  TIM2->CCR1 = 9;      //
  TIM2->CR1 = TIM_CR1_CEN;
  TIM2->EGR = TIM_EGR_UG; 
  TIM2->SR =0;
 
  // Конфигурация TIM3 для функций Delay
  TIM3->PSC = 36000-1;   // 0.5 мс
  TIM3->EGR = TIM_EGR_UG;
  TIM3->SR =0;

  //Конфигурация TIM4 для формирования строба схемы выборки-хранения 
  TIM4->PSC = 0;     // 13.9 нс
  TIM4->ARR = 80;    // Длительность (80-74)*13.9 = 83,4 нс
  TIM4->CCR2 = 74;   // Задержка 1,04 мкс
  TIM4->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_OC2M(6);
  TIM4->SMCR = TIM_SMCR_TS_TI1FP1 | TIM_SMCR_SMS(6); 
  TIM4->CR1 = TIM_CR1_OPM;
  TIM4->EGR = TIM_EGR_UG;
  TIM4->SR =0;
  TIM4->CCER = TIM_CCER_CC2E; 

Re: Вычисление тактовой частоты APB1

Вт июл 31, 2018 08:35:27

мне нужно в программе в расчётах иметь переменную, которая содержит значение частоты шины APB1, где мой таймер.

В нормально написанных программах частоты шин - это не переменные, а константы. Ну или - набор констант, если в процессе работы программы она эти частоты меняет.
Соответственно никаких "функций для определения частоты" не нужно. А все частоты известны на этапе компиляции.
Ответить