STM32F103 Помогите с тактовой частотой

Кто любит RISC в жизни, заходим, не стесняемся.
Аватара пользователя
NemesiS2014
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс сен 29, 2013 21:14:20

STM32F103 Помогите с тактовой частотой

Сообщение NemesiS2014 »

Привет всем котам, нужна ваша помощ, немогу выставить System clock на 72 MHz используя cmsis_boot, компилятор CoCox, частота кварца 12MHz, чип STM32F103VET6, частоту выставляю так:
Спойлер

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

static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
  /* Enable HSE */    
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;  
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }  

  if (HSEStatus == (uint32_t)0x01)
  {
    /* Enable Prefetch Buffer */
    FLASH->ACR |= FLASH_ACR_PRFTBE;

    /* Flash 2 wait state */
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    

 
    /* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
    /* PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL
    /* Configure PLLs ------------------------------------------------------*/
    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
        
    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
  
    /* Enable PLL2 */
    RCC->CR |= RCC_CR_PLL2ON;
    /* Wait till PLL2 is ready */
    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
    {
    }
    
   
    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 
    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
                            RCC_CFGR_PLLMULL9); 
#else    
    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL */

    /* Enable PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* Wait till PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
    
    /* Select PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

    /* Wait till PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
  }
  else
  { /* If HSE fails to start-up, the application will have wrong clock 
         configuration. User can add here some code to deal with this error */
  }
}
в майне проверяю частоту по морганию светодиода, проверяю так:
Спойлер

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

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"



int main()
{
  SystemInit(); // Инициализация частоты

  GPIO_InitTypeDef PORT;
  //Включаем порт С и таймер 6
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
  // Настроим ноги со светодиодами на выход
  PORT.GPIO_Pin = (GPIO_Pin_9 | GPIO_Pin_8 | GPIO_Pin_6);
  PORT.GPIO_Mode = GPIO_Mode_Out_PP;
  PORT.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOC, &PORT);
  TIM6->PSC = 24000 - 1; // Настраиваем делитель что таймер тикал 1000 раз в секунду
  TIM6->ARR = 1000 ; // Чтоб прерывание случалось раз в секунду
  TIM6->DIER |= TIM_DIER_UIE; //разрешаем прерывание от таймера
  TIM6->CR1 |= TIM_CR1_CEN; // Начать отсчёт!
  NVIC_EnableIRQ(TIM6_IRQn); //Разрешение TIM6_IRQn прерывания

  while(1)
  {
	  long i=0;
	  for(i=0;i<12000000;i++) // Проверка тактовой частоты
	  {
		  //1+1;
	  }
	  GPIOC->ODR^=(GPIO_Pin_6); //Инвертируем состояние светодиода

  }

}
// Тест обработчика прерывания TIM6
void TIM6_IRQHandler(void)
{
  TIM6->SR &= ~TIM_SR_UIF; //Сбрасываем флаг UIF
  GPIOC->ODR^=(GPIO_Pin_9 | GPIO_Pin_8); //Инвертируем состояние светодиодов
}
 
сейчас в цикле for стоит значение 12000000 и светодиод моргает с частотой 1 раз в 2 секунды и так что бы я не делал.
Ведь он должен при значении 72000000 моргать 1 раз в секунду :(

Прилагаю весь проект на всякий случай.
Вложения
test3.zip
Проект
(383.28 КБ) 259 скачиваний
Реклама
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: STM32F103 Помогите с тактовой частотой

Сообщение HHIMERA »

Не знаю как в ваших кокосах-бананах... а так... при пошаговой отладке дойдя до...

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

#else    
    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL */

можно увидеть... что частота не 72МГц...
Вместо RCC_CFGR_PLLMULL9 должно быть RCC_CFGR_PLLMULL6... частота кварца то 12МГЦ...
"Я не даю готовых решений, я заставляю думать!"(С)
Реклама
Аватара пользователя
NemesiS2014
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс сен 29, 2013 21:14:20

Re: STM32F103 Помогите с тактовой частотой

Сообщение NemesiS2014 »

Поменял RCC_CFGR_PLLMULL9 на RCC_CFGR_PLLMULL6 все стало работать еще медленнее, было установлено неправильное значение кварца "HSE_VALUE" Было 8000000 поменял на 12000000, на это значение никакой реакции даже если выставить 50000000 все равно ноль на массу, ни быстрей ни медленней. Я вожусь с этим уже неделю, это проклятый сорц говорю я вам :( Помогите люди добрые.
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32F103 Помогите с тактовой частотой

Сообщение dosikus »

NemesiS2014, какая линейка выбрана И где ?
С кактусом, все всегда будет в виде танцев с бубном . :)))
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
NemesiS2014
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс сен 29, 2013 21:14:20

Re: STM32F103 Помогите с тактовой частотой

Сообщение NemesiS2014 »

dosikus писал(а): какая линейка выбрана
Линейка VE полностью STM32F103VET6
dosikus писал(а): И где ?
Только в самом проекте а где еше можно его выбрать?
dosikus писал(а): С кактусом, все всегда будет в виде танцев с бубном.
Я уже понял, в прошлом проекте ошибку в библиотеке GPIO нашел, возился 2 дня, но с тактированием это финиш :(
Реклама
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32F103 Помогите с тактовой частотой

Сообщение dosikus »

Линейка это :
STM32F10X_LD
STM32F10X_LD_VL
STM32F10X_MD
STM32F10X_MD_VL
STM32F10X_HD
STM32F10X_HD_VL
STM32F10X_XL
STM32F10X_CL

Выбирайте свою и либо вбиваете в опции препроцессора, либо раскомментируйте строку в хэдере stm32f10x.h
Сей дефайн активно используется в system_stm32f10x.c и для расчета тактовой и для латентности Flash ...
Реклама
Аватара пользователя
NemesiS2014
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс сен 29, 2013 21:14:20

Re: STM32F103 Помогите с тактовой частотой

Сообщение NemesiS2014 »

В опциях препроцессора "Defined Symbols" вбито:
STM32F103VE
STM32F10X_HD
USE_STDPERIPH_DRIVER
__ASSEMBLY__
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32F103 Помогите с тактовой частотой

Сообщение dosikus »

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

#if !defined  HSE_VALUE
 #ifdef STM32F10X_CL   
  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
 #else 
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ <---- !!!!!!!!!!!!!!!!!!!!!
 #endif /* STM32F10X_CL */
#endif /* HSE_VALUE */
Правь здесь HSE_VALUE на свою частоту . А так же ищи где еще может быть переопределение HSE_VALUE .
Аватара пользователя
NemesiS2014
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс сен 29, 2013 21:14:20

Re: STM32F103 Помогите с тактовой частотой

Сообщение NemesiS2014 »

dosikus писал(а):Правь здесь HSE_VALUE на свою частоту
NemesiS2014 писал(а):было установлено неправильное значение кварца "HSE_VALUE" Было 8000000 поменял на 12000000, на это значение никакой реакции даже если выставить 50000000 все равно ноль на массу, ни быстрей ни медленней. Я вожусь с этим уже неделю, это проклятый сорц говорю я вам :( Помогите люди добрые.
dosikus писал(а):А так же ищи где еще может быть переопределение HSE_VALUE .
Нашел только:

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

/*!< STM32F10x Standard Peripheral Library old definitions (maintained for legacy purpose) */
#define HSEStartUp_TimeOut   HSE_STARTUP_TIMEOUT
#define HSE_Value            HSE_VALUE
#define HSI_Value            HSI_VALUE
Но HSE_Value нигде не используется.
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32F103 Помогите с тактовой частотой

Сообщение dosikus »

С кактусом сами разбирайтесь .
Могу только посоветовать собрать проект в Keil , где все просто и прозрачно ...
Аватара пользователя
NemesiS2014
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс сен 29, 2013 21:14:20

Re: STM32F103 Помогите с тактовой частотой

Сообщение NemesiS2014 »

dosikus писал(а):С кактусом сами разбирайтесь .
Могу только посоветовать собрать проект в Keil , где все просто и прозрачно ...
Блин у меня SWD только ColinkEx.

Я же говорил этот сорц проклят, ну буду дальше сам возиться. :(
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32F103 Помогите с тактовой частотой

Сообщение dosikus »

В дебаггере Keil можно например было увидеть , что настройки HSE фатальные (или кварц не завелся) и система тактируется от HSI .
Это так мысли вслух, информация к размышление...
Аватара пользователя
NemesiS2014
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс сен 29, 2013 21:14:20

Re: STM32F103 Помогите с тактовой частотой

Сообщение NemesiS2014 »

Разобрался, дело оказалось в компиляторе :)))
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32F103 Помогите с тактовой частотой

Сообщение dosikus »

Ну и ...
Аватара пользователя
NemesiS2014
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс сен 29, 2013 21:14:20

Re: STM32F103 Помогите с тактовой частотой

Сообщение NemesiS2014 »

Проверка тактовой частоты:

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

  while(1)
  {

	  uint32_t i=0;

	  for(i=0;i<12000000;i++) // Проверка тактовой частоты
	  {
		  __asm("nop");
	  }
	  GPIOC->ODR^=(GPIO_Pin_6); //Инвертируем состояние светодиода

  }
Оказалось так тактовую частоту не проверишь потому как 1 цикл for даже при максимальной оптимизации обрабатывается только за 6 тактов это же не асьм :?

Авот если проверять так:

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

 
int main()
{

  SystemCoreClockUpdate();
 TIM6->PSC = 36000 - 1; // Настраиваем делитель чтоб таймер тикал 2000 раз в секунду
  TIM6->ARR = 2000 ; // Чтоб прерывание случалось раз в секунду
  TIM6->DIER |= TIM_DIER_UIE; //разрешаем прерывание от таймера
  TIM6->CR1 |= TIM_CR1_CEN; // Начать отсчёт!
 while(1)
  {}
}

// Тест обработчика прерывания TIM6
void TIM6_IRQHandler(void)
{
  TIM6->SR &= ~TIM_SR_UIF; //Сбрасываем флаг UIF
  GPIOC->ODR^=(GPIO_Pin_9 | GPIO_Pin_8); //Инвертируем состояние светодиодов
}
Все так как и должно быть 1 раз в секунду :))
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32F103 Помогите с тактовой частотой

Сообщение dosikus »

NemesiS2014 писал(а):Проверка тактовой частоты:

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

  while(1)
  {

	  uint32_t i=0;

	  for(i=0;i<12000000;i++) // Проверка тактовой частоты
	  {
		  __asm("nop");
	  }
	  GPIOC->ODR^=(GPIO_Pin_6); //Инвертируем состояние светодиода

  }

УжОс на .
Компилятор то и ни причем ... :)))

Откройте для себя DWT или на крайняк SysTick что ли ...
Аватара пользователя
NemesiS2014
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс сен 29, 2013 21:14:20

Re: STM32F103 Помогите с тактовой частотой

Сообщение NemesiS2014 »

dosikus писал(а):
NemesiS2014 писал(а):Проверка тактовой частоты:

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

  while(1)
  {

	  uint32_t i=0;

	  for(i=0;i<12000000;i++) // Проверка тактовой частоты
	  {
		  __asm("nop");
	  }
	  GPIOC->ODR^=(GPIO_Pin_6); //Инвертируем состояние светодиода

  }

УжОс на .
Компилятор то и ни причем ... :)))

Откройте для себя DWT или на крайняк SysTick что ли ...
Уже открыл :)))
Кстати и еще открыл что кристалл без проблем гонится до 160Mhz :)))
Аватара пользователя
Леонид Иванович
Друг Кота
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск
Контактная информация:

Re: STM32F103 Помогите с тактовой частотой

Сообщение Леонид Иванович »

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

 
 TIM6->PSC = 36000 - 1; // Настраиваем делитель чтоб таймер тикал 2000 раз в секунду
  TIM6->ARR = 2000 ; // Чтоб прерывание случалось раз в секунду
Маленькая поправочка: значение ARR должно быть не 2000, а 2000 - 1.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: STM32F103 Помогите с тактовой частотой

Сообщение HHIMERA »

Ещё меньшая поправочка...
Уменьшать на единицу нужно PSC, ARR и RCR (если используется)...
Example update event period
The update event period is calculated as follows:
Update_event = TIM_CLK/((PSC + 1)*(ARR + 1)*(RCR + 1))
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
Alexey_N
Сверлит текстолит когтями
Сообщения: 1273
Зарегистрирован: Вт фев 01, 2011 17:56:40
Откуда: г. Жуковка, Брянская обл.

Re: STM32F103 Помогите с тактовой частотой

Сообщение Alexey_N »

Hi всем. Разбираюсь тут с STM32F103CBT6. Раскочегариваю до 72 МГц, но получаю весьма странные результаты. Сначала написал простую моргалку частотой 1Гц:
Спойлер

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

.syntax unified
.arch armv7-m
.thumb
.thumb_func

.include "include/stm32f10x.inc"

.section .code

.word 0x20005000
.word entry_point+1

entry_point:

        ldr     r6, = RCC_APB2ENR
        ldr     r0, [r6]
        orr     r0, RCC_APB2ENR_IOPBEN
        str     r0, [r6]

        ldr     r6, = GPIOB_CRL
        ldr     r0, = 0x44444433
        str     r0, [r6]

        mov     r2, 0      @ Значение 'вкл.'
        mov     r3, 0x0003 @ Значение 'выкл.'

        ldr     r6, = GPIOB_ODR

loop:
        str     r2, [r6] @ Сброс бита 1, включение светодиода
        ldr     r1, = 0x145850
delay1:
        subs    r1, 1
        bne     delay1
        
        str     r3, [r6] @ Установка бита 1, выключение светодиода
        ldr     r1, = 0x145850
delay2:
        subs    r1, 1
        bne     delay2

        b       loop
Все отлично. Затем запустил внешний генератор на 8МГц и умножитель на 9 и получил частоту моргания - 3,85Гц !!. Как так?
Но, как только я меняю способ установки бит у регистра CFGR в том месте где устанавливается коэффициент умножения 9 (дописываю nop или любую другую пустую команду или использую movw/movt), то частота меняется до 4.5Гц. Почему? Что за глюк?

Полный исходник:
Спойлер

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

.syntax unified
.arch armv7-m
.thumb
.thumb_func

.include "include/stm32f10x.inc"

.section .code

.word 0x20005000
.word entry_point+1

entry_point:

        ldr     r6, = RCC_APB1ENR
        ldr     r0, [r6]
        orr     r0, RCC_APB1ENR_PWREN
        str     r0, [r6]

        ldr     r6, = FLASH_ACR
        ldr     r0, [r6]
        orr     r0, FLASH_ACR_LATENCY_2 + FLASH_ACR_PRFTBE
        str     r0, [r6]

        ldr     r6, = RCC_CR
        ldr     r0, [r6]
        orr     r0, RCC_CR_HSEON
        str     r0, [r6]

wait_hse:
        ldr     r0, [r6]
        tst     r0, RCC_CR_HSERDY
        beq     wait_hse

        @ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        ldr     r0, = RCC_CFGR
        ldr     r4, [r0]
        orr     r4, RCC_CFGR_PLLSRC + RCC_CFGR_PPRE1_DIV2 + RCC_CFGR_PPRE2_DIV2
        orr     r4, RCC_CFGR_PLLMULL9
        str     r4, [r0]

        ldr     r6, = RCC_CR
        ldr     r0, [r6]
        orr     r0, RCC_CR_PLLON
        str     r0, [r6]
wait_pll:
        ldr     r0, [r6]
        tst     r0, RCC_CR_PLLRDY
        beq     wait_pll

        ldr     r6, = RCC_CFGR
        ldr     r0, [r6]
        orr     r0, RCC_CFGR_SW_PLL
        str     r0, [r6]
wait_sws:
        ldr     r0, [r6]
        tst     r0, RCC_CFGR_SWS_PLL
        beq     wait_sws

        ldr     r6, = RCC_APB2ENR
        ldr     r0, [r6]
        orr     r0, RCC_APB2ENR_IOPBEN
        str     r0, [r6]

        ldr     r6, = GPIOB_CRL
        ldr     r0, = 0x44444433
        str     r0, [r6]

        mov     r2, 0      @ Значение 'вкл.'
        mov     r3, 0x0003 @ Значение 'выкл.'

        ldr     r6, = GPIOB_ODR

loop:
        str     r2, [r6] @ Сброс бита 1, включение светодиода
        ldr     r1, = 0x145850
delay1:
        subs    r1, 1
        bne     delay1
        
        str     r3, [r6] @ Установка бита 1, выключение светодиода
        ldr     r1, = 0x145850
delay2:
        subs    r1, 1
        bne     delay2

        b       loop

.section .preinit_array
.include "include/flash.inc"
.section .sram
.include "include/sram.inc"

.end
UPD. глюк вродь пропал, когда добавил пустые вектора (хотя не думаю, что в этом дело), но все равно не понятно, как могут получится такие частоты при кварце 8МГц, если при работе от внутреннего генератора частота была 1Гц:
1Гц - x2 PLL
1,28Гц - x3 PLL
1,71Гц - x4 PLL
3,42Гц - x8 PLL
3,85Гц - x9 PLL

UPD2. Кажется я понял почему частоты ниже - сказывается установленная при инициализации задержка флеш памяти и инструкции читаются медленнее, что необходимо для работы на высоких частотах, но пока что не понятно почему она не кратная ...

UPD3. А не кратны, подозреваю, что из-за включенного механизма предвыборки.
Индукционный нагреватель - 20% (наладка). TIG сварка - 10% (детальки)
ВЧ генератор 150МГц - 80% (наладка). Мостовой ИИП - 40% (подкл. ОС).
Ответить

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