Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32 и его RCC
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
011119xx
За изучение STM32 я взялся совсем недавно. Как и полагается собрал отладочную плату на STM32F103RET6 по прилагаемой схеме. В качестве отладчика использую J-Link v7, в качестве среды Keil mVision 4 (конечно не последней версии). Сделал простейший проект, основную часть программы привожу, к PC3 подключил светодиод через резистор к + питания:

Код
#include "stm32f10x.h"

ErrorStatus HSEStartUpStatus;
GPIO_InitTypeDef GPIO_InitStructure;

void RCC_Configuration(void)
{  
    // Сброс системы RCC (for debug purpose)
      RCC_DeInit();
      // Разрешение HSE
      RCC_HSEConfig(RCC_HSE_ON);
      // Ожидание готовности HSE
      HSEStartUpStatus = RCC_WaitForHSEStartUp();

      if(HSEStartUpStatus == SUCCESS)                        // Если HSE готов, то
      {
            // HCLK = SYSCLK
            RCC_HCLKConfig(RCC_SYSCLK_Div1);
            // PCLK2 = HCLK
            RCC_PCLK2Config(RCC_HCLK_Div1);
            // PCLK1 = HCLK/2
            RCC_PCLK1Config(RCC_HCLK_Div2);
            // PLLCLK = 8 МГц * 9 = 72 МГц
            RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
             // Разрешение PLL
            RCC_PLLCmd(ENABLE);
             // Ожидание готовности PLL
            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
            {}
            // Выбор PLL как источника системного тактирования
            RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
            // Ожидание готовности PLL для использования как источника системного тактирования
            while(RCC_GetSYSCLKSource() != 0x08)
            {}
      }
}

int main(void)
{
      RCC_Configuration();                           

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
      GPIO_Init(GPIOC, &GPIO_InitStructure);                

    while(1)
    {
            GPIO_SetBits( GPIOC, GPIO_Pin_3);
        GPIO_ResetBits( GPIOC, GPIO_Pin_3);
    }
}


В общем запускаю программу на выполнение по шагам. В результате вижу, что HSE не готов, не хочет включаться. Тем не менее, светодиод загорается. Много над этим думал ... В результате пришел к выводу, что кварц какой-то не совсем рабочий и решил его заменить. Поставил другой, на 6 МГц (другого на 8 МГц под рукой не оказалось). Запустил программу на выполнение по шагам. Теперь HSE запускается, бит готовности выставляется, но снова возникли проблемы уже в другом месте. Оказалось, что теперь не запускается PLL и программа зациклилась тут, естественно, что светодиод не загорается:

Код
             // Ожидание готовности PLL
            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
            {}


Долго мучился над этой проблемой, но так и не решил. Все выключил, потом решил включить отладочную плату со снятым отладчиком и в результате светодиод загорелся, что свидетельствует о том, что зацикливания не произошло и PLL все же работает.

Значит получается, что это отладчик не дает запускаться PLL?

Пробовал менять функцию RCC_Configuration на такую, то есть запускать PLL от HSI:

Код
void RCC_Configuration(void)
{  
    // Сброс системы RCC (for debug purpose)
      RCC_DeInit();
      // Разрешение HSE
      RCC_HSEConfig(RCC_HSE_ON);
      // Ожидание готовности HSE
      HSEStartUpStatus = RCC_WaitForHSEStartUp();

    // HCLK = SYSCLK
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
    // PCLK2 = HCLK
    RCC_PCLK2Config(RCC_HCLK_Div1);
    // PCLK1 = HCLK/2
    RCC_PCLK1Config(RCC_HCLK_Div2);
    // PLLCLK = 8/2 МГц * 9 = 36 МГц
    RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
    // Разрешение PLL
    RCC_PLLCmd(ENABLE);
    // Ожидание готовности PLL
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {}
    // Выбор PLL как источника системного тактирования
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    // Ожидание готовности PLL для использования как источника системного тактирования
    while(RCC_GetSYSCLKSource() != 0x08)
    {}
}


При этом PLL запускается и светодиод горит.

Почему так происходит?
topkin
Вы начали пользоваться библиотекой, так там в файле system_stm32f10x.с происходит инициализация МК до входа в main, там с помощью комментариев задаются стандартные частоты, выставьте одну из них, 36МГц вроде бы там есть, заодно посмотрите как там происходит настройка... Так же удостоверьтесь в правильности настройки проекта, я про макросы в свойствах проекта...
011119xx
Цитата(topkin @ Jan 19 2011, 10:55) *
Вы начали пользоваться библиотекой, так там в файле system_stm32f10x.с происходит инициализация МК до входа в main, там с помощью комментариев задаются стандартные частоты, выставьте одну из них, 36МГц вроде бы там есть, заодно посмотрите как там происходит настройка... Так же удостоверьтесь в правильности настройки проекта, я про макросы в свойствах проекта...


Вы считаете, что функция SystemInit, которая в файле system_stm32f10x.с вызывается сама, тогда почему я не вижу в отдадчике результат ее работы? Да и настройка в ней такая же, что и приведена мной выше. Мне не нужна частота 36 МГц, я хочу минимум 72 МГц. А вот про макросы в свойствах проекта можно поподробнее?
topkin
Цитата(011119xx @ Jan 19 2011, 09:25) *
Вы считаете, что функция SystemInit, которая в файле system_stm32f10x.с вызывается сама, тогда почему я не вижу в отдадчике результат ее работы? Да и настройка в ней такая же, что и приведена мной выше. Мне не нужна частота 36 МГц, я хочу минимум 72 МГц. А вот про макросы в свойствах проекта можно поподробнее?

Скорее всего у вас стоит галка в свойствах проекта "Debugger -> Setup-> Run to main", вот уберите ее и вы увидите, как испольняется функция SystemInit.
Возьмите готовый проект и посмотрите его свойства, например, для того, чтобы пользоваться библиотекой ST и указать правильный камень для нее, нужно прописать в свойствах проекта "С\C++ compiler-> Preprocessor-> defined symbols" строки:
USE_STDPERIPH_DRIVER
STM32F10X_MD_VL - тип контроллера, в данном случае это medium-density value line, короче это один их контроллеров линейки STM32F100
011119xx
Цитата(topkin @ Jan 19 2011, 11:57) *
Скорее всего у вас стоит галка в свойствах проекта "Debugger -> Setup-> Run to main", вот уберите ее и вы увидите, как испольняется функция SystemInit.
Возьмите готовый проект и посмотрите его свойства, например, для того, чтобы пользоваться библиотекой ST и указать правильный камень для нее, нужно прописать в свойствах проекта "С\C++ compiler-> Preprocessor-> defined symbols" строки:
USE_STDPERIPH_DRIVER
STM32F10X_MD_VL - тип контроллера, в данном случае это medium-density value line, короче это один их контроллеров линейки STM32F100


А разве не достаточно того, что в файле stm32f10x.h есть такие строки:

Код
#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
  /* #define STM32F10X_LD */     /*!< STM32F10X_LD: STM32 Low density devices */
  /* #define STM32F10X_LD_VL */  /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */  
  /* #define STM32F10X_MD */     /*!< STM32F10X_MD: STM32 Medium density devices */
  /* #define STM32F10X_MD_VL */  /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */  
   #define STM32F10X_HD      /*!< STM32F10X_HD: STM32 High density devices */
  /* #define STM32F10X_XL */     /*!< STM32F10X_XL: STM32 XL-density devices */
  /* #define STM32F10X_CL */     /*!< STM32F10X_CL: STM32 Connectivity line devices */
#endif

#if !defined  USE_STDPERIPH_DRIVER
/**
* @brief Comment the line below if you will not use the peripherals drivers.
   In this case, these drivers will not be included and the application code will
   be based on direct access to peripherals registers
   */
  #define USE_STDPERIPH_DRIVER
#endif
sonycman
А может лучше не пользоваться всякими сомнительными библиотеками?
Имхо, прямая работа с периферией много эффективнее, хотя и несколько сложнее в освоении...
011119xx
Цитата(sonycman @ Jan 19 2011, 20:15) *
А может лучше не пользоваться всякими сомнительными библиотеками?
Имхо, прямая работа с периферией много эффективнее, хотя и несколько сложнее в освоении...

Да нет Вова, хорошая библиотека, очень облегчает освоение.

В общем моя история продолжилась тем, что купил я новый кварц на 8 МГц и поставил его, прошил, запустил отладку по шагам. HSE запускается, PLL тоже, по крайней мере, не зацикливается там, где это происходило ранее. Но вот то что отображается в окне Peripherals/RCC вызывает недоумение. Флаг PLLRDY, то стоит, то не стоит. Частоты тактирования разных модулей (те что в самом низу окна) тоже как-то отображаются, то правильно, то не правильно... Думаю может у меня версия Keil какая-то глючная или может дело в J-Link... При отключенном отладчике зацикливания не происходит и светодиод начинает мигать (добавил задержки после установки и сброса бита PC3). Но вот что интересно, если произвести сброс кнопкой, то частота работы процессора уменьшается, светодиод начинает мигать медленнее... Кто что думает по этому поводу?
Danis
Цитата(011119xx @ Jan 20 2011, 07:19) *
Кто что думает по этому поводу?


Какая у Вас версия библиотеки? Попробуйте скачать последнюю периферийную библиотеку от ST, там множество примеров. В отладке попробуйте переключить на режим с JTAG на SDW, может поможет.
А так сразу не сказать что у Вас не так, надо разбираться….
011119xx
Цитата(Danis @ Jan 20 2011, 11:08) *
Какая у Вас версия библиотеки? Попробуйте скачать последнюю периферийную библиотеку от ST.


Версия библиотеки последняя, скачана с сайта ST.
sonycman
Цитата(011119xx @ Jan 20 2011, 07:19) *
Да нет Вова, хорошая библиотека, очень облегчает освоение.

На всякий случай, приведу свою прямую инициализацию клоков для STM32 с кварцем 8 МГц для частоты 72 МГц, может, чем то поможет:
CODE

#define FLASH_ACR_LATENCY_1 ((u8)0x02)
#define RCC_CR_HSEON ((u32)0x00010000) /* External High Speed clock enable */
#define RCC_CFGR_PLLMULL9 ((u32)0x001C0000) /* PLL input clock*9 */
#define RCC_CFGR_PLLSRC ((u32)0x00010000) /* PLL entry clock source */
#define RCC_CFGR_PPRE1_DIV2 ((u32)0x00000400) /* HCLK divided by 2 */
#define RCC_CR_HSERDY ((u32)0x00020000) /* External High Speed clock ready flag */
#define RCC_CR_PLLON ((u32)0x01000000) /* PLL enable */
#define RCC_CR_PLLRDY ((u32)0x02000000) /* PLL clock ready flag */
#define RCC_CFGR_SW_PLL ((u32)0x00000002) /* PLL selected as system clock */
#define RCC_CFGR_SWS_HSE ((u32)0x00000004) /* HSE oscillator used as system clock */
#define RCC_CFGR_SWS_PLL ((u32)0x00000008) /* PLL used as system clock */

//configure clocks
FLASH->ACR |= FLASH_ACR_LATENCY_1; //flash latency = 2 wait states
RCC->CR |= RCC_CR_HSEON;
RCC->CFGR = RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC | RCC_CFGR_PPRE1_DIV2;
while (!(RCC->CR & RCC_CR_HSERDY));
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & (RCC_CFGR_SWS_HSE | RCC_CFGR_SWS_PLL)) != RCC_CFGR_SWS_PLL);

//Enable clocking of the peripherals - all the IO ports
RCC->APB2ENR = RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN |
RCC_APB2ENR_IOPDEN;

011119xx
Сейчас мы имеем ситуацию при которой, прямое управление запуском HSE и PLL приводит к их нормальной работоспособности (на железе еще не проверял, но уважаемые мной коллеги sonycman и Ведущий_специалист это проверяли). НО! Если посмотреть на тоже самое управление, но с использованием StdLib, то можно увидеть что управление происходит теми же самыми битами и в той же последовательности и это не работает. Тогда я пришел к выводу, что например для PLL очень важно чтобы после ее включения и выставления ею флага готовности, к ней максимально быстро был кто-либо подключен. Если этого не происходит, то она выключается. При прямом управлении к PLL тут же подключается system clock, а при управлении с помощью библиотеки все происходит через подпрограммы, что приводит к дополнительным задержкам. Эти задержки и мешают в данном случае. И еще. Обязательно нужно активизировать буфер предвыборки флэш, так как это запускает конвейер на максимальную производительность. Я этого не сделал к сожалению. Осталось проверить эту теорию на практике.
pr0m
Цитата(011119xx @ Jan 21 2011, 07:37) *
Обязательно нужно активизировать буфер предвыборки флэш, так как это запускает конвейер на максимальную производительность. Я этого не сделал к сожалению. Осталось проверить эту теорию на практике.


Угумс, нужно, перед переходом на тактирование от разогнанной до 72МГц PLL - у внутренней флэшки скорость выборки порядка 40нс, и надо конфигурить на 2 waitstate-а. Иначе код из неё через раз читается, отсюда и глюки, имхо. Хотя где-то попадалось недавно - кто-то по ошибке делители непрально выставил, и в итоге STM32 якобы заработал у него аж на 150МГц. Не знаю, оверклокер какой-то biggrin.gif
011119xx
Теория на практике не подтвердилась... Буфер предвыборки у меня теперь включается... Сейчас остановился на том, что не запускается HSE, пробовал разные кварцы: и на 8МГц, и на 6МГц, и на 16МГц. Результат один. В монтаже ошибок нет... Удалось запустить PLL только от HSI, на максимальной частоте 64МГц (больше ведь там невозможно сделать от HSI, а мне бы надо 72МГц). При отладке по шагам все частоты отображаются верно, ничего не глючит. Но HSE у меня похоже крякнулся или надо плату как-то развести по другому, в общем не запускается... wacko.gif
sonycman
Цитата(011119xx @ Jan 24 2011, 08:01) *
Но HSE у меня похоже крякнулся или надо плату как-то развести по другому, в общем не запускается... wacko.gif

Алексей, а кондёры кварца пробовал поварьировать? От 18 до 32 пф хотя бы.
Также на референсной схеме есть резистор 1 МОм параллельно кварцу.

Фото/гербер разводки можешь привести?
011119xx
Резистор на 1МОм пробовал ставить - не помогает. Конденсаторы к сожалению не варьировал, сейчас стоят на 22пФ... Это я попробую... Плату могу прямо сейчас только вот в таком виде показать...
011119xx
На схеме отладочной платы STM3210E-EVAL стоит дополнительный резистор 390 ом. Кто-нибудь его ставил?
shreck
Цитата(011119xx @ Jan 25 2011, 19:06) *
На схеме отладочной платы STM3210E-EVAL стоит дополнительный резистор 390 ом. Кто-нибудь его ставил?

Я ставлю (номиналом 270 ом). Кварц на 8Мгц всегда работает четко (без проблем юзаю FWlib).
ViKo
Работает ли кварцевый генератор, вы можете увидеть осциллографом. Думаю, дело не в нем.

011119xx
Цитата(ViKo @ Jan 25 2011, 16:20) *
Работает ли кварцевый генератор, вы можете увидеть осциллографом. Думаю, дело не в нем.


В чем тогда?
ViKo
Цитата(011119xx @ Jan 25 2011, 14:11) *
В чем тогда?

Та плата, что вы показали, не разведена до конца. Например, земля. И другие цепи. Во всяком случае, так показывает P-CAD. Сначала с платой разберитесь.
011119xx
Цитата(ViKo @ Jan 25 2011, 17:30) *
Та плата, что вы показали, не разведена до конца. Например, земля. И другие цепи. Во всяком случае, так показывает P-CAD. Сначала с платой разберитесь.

Не разведенные связи, которые показывает PCAD выполнены навесными перемычками. И в монтаже ошибок нет.
ViKo
Цитата(011119xx @ Jan 25 2011, 14:36) *
Не разведенные связи, которые показывает PCAD выполнены навесными перемычками. И в монтаже ошибок нет.

ПМСМ, земли мало. Полигоны предпочтительны. Или целые слои на многослойках.
sonycman
Цитата(ViKo @ Jan 25 2011, 15:59) *
ПМСМ, земли мало. Полигоны предпочтительны. Или целые слои на многослойках.

С землёй там действительно не особо, но работать должно. Никакие многослойки эстмке не нужны.
Действительно, неплохо бы глянуть осциллографом.
011119xx
Достал вчера мешочек в котором лежат кондеры на 22пФ... В нем оказалось 2 ленты, причем кондеры по виду в них отличаются... Один вид действительно похож на 22пФ, а вот другой не очень, причем и на 0,1мкФ они тоже не похожи. Как раз их я и ставил... В общем чтобы не рисковать лишний раз, убрал я с платы "22пФ" и поставил наверняка 33пФ из уже другого мешочка... HSE теперь работает... В общем проблема в этом была... А вот как у меня в мешочке с кондерами 22пФ появились еще какие-то мне не понятно... Возможно это Элитан постарался (там заказывал), тогда ему "спасибо", а если я сам их туда положил (что весьма сомнительно), то мне "спасибо".
sonycman
Цитата(011119xx @ Jan 26 2011, 07:10) *
Достал вчера мешочек в котором лежат кондеры на 22пФ... В нем оказалось 2 ленты, причем кондеры по виду в них отличаются... Один вид действительно похож на 22пФ, а вот другой не очень, причем и на 0,1мкФ они тоже не похожи.

Ну ты, Лёха, даёшь!
Ёмкость smd керамики по "похожести" определяешь? sm.gif

Купи какой нибудь средненький измеритель LC и не парься.
Уж минимальный комплект приборов разработчик должен иметь.
ViKo
Цитата(sonycman @ Jan 26 2011, 09:34) *
Купи какой нибудь средненький измеритель LC и не парься.

Да чё там измеритель LC - китайский мультиметр показывает достаточно точно, чтобы отличить 22pF от 33pF, не говоря уже от 0.1uF.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.