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

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Сообщение supercelt »

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

Сообщение Reflector »

[uquote="supercelt",url="/forum/viewtopic.php?p=3422284#p3422284"]Я не использую ни куб, ни HAL ни SPL.[/uquote]
Ни DS, ни RM, я правильно понял? :)
Если хочешь сам все вычислить, то нужно смотреть в регистрах RCC какой активен генератор, считать текущую частоту, потом смотреть какие на шинах делители, а для таймеров еще нужно учесть, что частота может умножаться на 2.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="supercelt",url="/forum/viewtopic.php?p=3422284#p3422284"]Я не использую ни куб, ни HAL ни SPL.[/uquote]Это значит никто кроме вас частоты не меняет. Вы их сами поставите и будете знать.

[uquote="supercelt",url="/forum/viewtopic.php?p=3422284#p3422284"]Просто обычный CMSIS.[/uquote]В любом тулчейне в стартапе есть функция, которая вызывается перед переходом в main(), предназначенная для инициализации железа. Чаще всего это SystemInit() или __low_level_init(). Там и задавайте все нужные делители.

[uquote="supercelt",url="/forum/viewtopic.php?p=3422284#p3422284"]Поэтому есть ли какая-нибудь константа или переменная, которая содержит в себе это значение? или как бы это можно было вычислить не прибегая к помощи SPL?)[/uquote]Вы можете сами её сделать. Если по ходу программы частоты не меняете, то просто задефайнить константу. Если меняете, то можно в переменную писать установленное значение.

Ну или как Reflector предложил, но это геморрой в рунтайме, да и отталкиваться надо от частоты кварца, которая неизвестна.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3422309#p3422309"]Ну или как Reflector предложил, но это геморрой в рунтайме, да и отталкиваться надо от частоты кварца, которая неизвестна.[/uquote]
Частота шин нужна почти всегда на стадии инициализации, т.е. можно спокойно все вычислять прямо на ходу, в крайнем случае полученное значение можно закешировать. И где это ты видел проекты в которых неизвестна частота кварца? :)
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Сообщение supercelt »

Кварц 8 мгц
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Reflector",url="/forum/viewtopic.php?p=3422344#p3422344"]И где это ты видел проекты в которых неизвестна частота кварца? :)[/uquote]Я имел в виду, что программа сама частоту кварца определить не может, а полагается на то значение которое программист указал ей. Не, плюс/минус трамвайная остановка конечно можно измерить, но не более.
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3422380#p3422380"]Я имел в виду, что программа сама частоту кварца определить не может, а полагается на то значение которое программист указал ей. Не, плюс/минус трамвайная остановка конечно можно измерить, но не более.[/uquote]
Ну ладно, раз "неизвестная" частота кварца такая проблема, то можно от нее избавиться... Допустим тактирование от PLL, PLL от кварца, кварц неизвестен, множитель 8, частота по ходу не меняется, какое значение частоты APB1 задефайнишь в константе? Ты же это предлагал?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

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

Сообщение supercelt »

Я просто хотел написать так что бы максимально легко было переносить на другие камни.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

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

Код: Выделить всё

  // ------------------ Тактирование -------------------------
  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;  
Мудрый кот
Сообщения: 1778
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="supercelt",url="/forum/viewtopic.php?p=3422284#p3422284"]мне нужно в программе в расчётах иметь переменную, которая содержит значение частоты шины APB1, где мой таймер.[/uquote]
В нормально написанных программах частоты шин - это не переменные, а константы. Ну или - набор констант, если в процессе работы программы она эти частоты меняет.
Соответственно никаких "функций для определения частоты" не нужно. А все частоты известны на этапе компиляции.
Ответить

Вернуться в «ARM»