Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблемы с инициализацией STM32F103VE
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
A-10
Всем привет. Приобрел недавно отладочную плату на STM32F103VE, решил начать с самого простого, инициализации мк и включения единственного светодиода.
Модифицировал какой-то простейший кейловский пример, там почему-то даже не было инициализации системы тактирования, и направления портов GPIO (мб подразумевалась настройка через конфиг, хз).
В общем по мануалу и insider's guide настроил все клоки, поставил 5-ый пин порта Б на выход. Нашел косяк, и не один, в процессе отладки, оказалось, что в reset регистры надо записывать 0 после старта, в мануале об этом ни слова, хорошо что в insider's guide было пояснение.
Но СД все равно не горит. Не могу понять в чем дело..

Код выглядит так:

Код
/*----------------------------------------------------------------------------
*  Name:    Blinky.c
*  Purpose: LED Flasher for STM32
*---------------------------------------------------------------------------*/
#include <stm32f10x.h>
/*----------------------------------------------------------------------------
   Function prototypes
*---------------------------------------------------------------------------*/
void clockstart(void);
/*----------------------------------------------------------------------------
   Wait function - delay flashing
*---------------------------------------------------------------------------*/
void wait (void) {
  unsigned int countDown = 300000;                  // arbitrary int to count down

  while(countDown--);                                       // count down
}

/*----------------------------------------------------------------------------
   MAIN function
*---------------------------------------------------------------------------*/

int main (void) {
    clockstart();                                                // init start sequence
    GPIOB -> CRL |= (GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1);
                                                                    // set pin5 of PORTB to output mode, max speed 50 MHz
    GPIOB -> CRL &= 0xFF3FFFFF;                        // general purpose output push-pull

  while (1) {                                                   // loop forever
    GPIOB -> BSRR |= GPIO_BSRR_BS5;            // set pin5 to 1
    wait();                                                         // delay flashing
    GPIOB -> BSRR |= GPIO_BSRR_BR5;            // set pin5 off
    wait();
  }
}


Код
#include <stm32f10x.h>

void clockstart(void) {
//    while (!(RCC -> CR & RCC_CR_HSIRDY))                      // Wait until internal HSI will be ready
//    {
//;
//    }

    RCC -> CR |= RCC_CR_HSEON;                                // Switch to HSE oscillator
    while (!(RCC -> CR & RCC_CR_HSERDY))                      // Wait until external HSE will be ready
    {
;
    }

    RCC -> CFGR |= RCC_CFGR_PLLSRC;                        // Set PLL source clock as HSE
    RCC -> CFGR |= (RCC_CFGR_PLLMULL_0 | RCC_CFGR_PLLMULL_1 | RCC_CFGR_PLLMULL_2);
                                                                                // Set PLL multiplier x9 (72 MHz)
    RCC -> CFGR |= RCC_CFGR_SW_1;                            // PLL selected as system clock
    RCC -> CR |= RCC_CR_PLLON;                                    // Start PLL
    while (!(RCC -> CR & RCC_CR_PLLRDY))                      // Wait until PLL is locked
    {
;
    }

    RCC -> CFGR |= RCC_CFGR_PPRE1_DIV2;                    // HCLK divided by 2 (36MHz)
    RCC -> APB2ENR |= RCC_APB2ENR_IOPBEN;                // IO port B clock enable
    RCC -> APB2RSTR = 0x00000000;
    RCC -> APB1RSTR = 0x00000000;                            // release peripherals from reset    
}
ISK2010
Сама прога выполняется? А какие значения присваиваешь регистру BSRR? Т.к. тут еще отдельно есть регистр сброса выводов BRR, то я привык через него сбрасывать. Напиши так, может поможет:
GPIOB -> BSRR = 0x20; //pa5 set to high
WaitToGoldLife();
GPIOB -> BRR = 0x20; //pa5 reset
A-10
Цитата(ISK2010 @ Sep 30 2010, 23:29) *
Сама прога выполняется? А какие значения присваиваешь регистру BSRR? Т.к. тут еще отдельно есть регистр сброса выводов BRR, то я привык через него сбрасывать. Напиши так, может поможет:
GPIOB -> BSRR = 0x20; //pa5 set to high
WaitToGoldLife();
GPIOB -> BRR = 0x20; //pa5 reset
По дебагу в софте я еще не успел разобраться, кейл только недавно поставил. Попробую прогнать в дебаггере.
Железо по-крайней мере работает с тестовой прошивкой (что была с платой), СД горит и шьется она нормально. Было подозрение на стартап-код, я дефолтный использую. Во все тонкости пока не вник.
А в BSRR пишу то же 0x20, просто имя взято из хедера стандартного STM.
Попробовал - нет разницы.
Знать бы в каком направлении искать, а то думаю, ошибка в настройке тактовых, порты или вообще стартап.
ISK2010
А какое значение у GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1 ? Запиши просто и сразу вместо двух строчек одну "GPIOB -> CRL = 0x44344444;"
Ну это на случай если у тебя уже завелся МК и по проге он прыгает. А если не завелся, то попробуй пока без своего "clockstart();". Подключи к проекту готовый стартап и system_stm32f10x.c. Там кварц, PLL, AHB, APB1 и т.п. проинициализируется. Только включи тактирование GPIOB: "RCC -> APB2ENR |= RCC_APB2ENR_IOPBEN;".
A-10
Цитата(ISK2010 @ Oct 1 2010, 08:55) *
А какое значение у GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1 ? Запиши просто и сразу вместо двух строчек одну "GPIOB -> CRL = 0x44344444;"
Ну это на случай если у тебя уже завелся МК и по проге он прыгает. А если не завелся, то попробуй пока без своего "clockstart();". Подключи к проекту готовый стартап и system_stm32f10x.c. Там кварц, PLL, AHB, APB1 и т.п. проинициализируется. Только включи тактирование GPIOB: "RCC -> APB2ENR |= RCC_APB2ENR_IOPBEN;".

GPIO_CRL_MODE5_0 ((uint32_t)0x00100000) /*!< Bit 0 */
GPIO_CRL_MODE5_1 ((uint32_t)0x00200000) /*!< Bit 1 */
То есть при побитном ИЛИ они дают xx11xx.
Прогу прогнал, вроде бы проходит всю инициализацию и в основном цикле крутится, правда странно, иногда курсор вылетает за пределы функции

Готовый стартап я пробовал, с ходу не получилось, и я решил расписать вручную. Попробую еще раз, тогда я явно забывал запустить тактирование порта..
A-10
Проблема оказалась на поверхности,
Код
RCC -> CFGR |= RCC_CFGR_SW_1;                            // PLL selected as system clock
    RCC -> CR |= RCC_CR_PLLON;                                    // Start PLL
    while (!(RCC -> CR & RCC_CR_PLLRDY))                      // Wait until PLL is locked
    {
;
    }
Источник тактирования для ПЛЛ должен быть включен после запуска самой ПЛЛ, а не до, то есть так:
Код

    RCC -> CR |= RCC_CR_PLLON;                                    // Start PLL
    while (!(RCC -> CR & RCC_CR_PLLRDY))                      // Wait until PLL is locked
    {
;
    }
    RCC -> CFGR |= RCC_CFGR_SW_1;                            // PLL selected as system clock
ViKo
Судя по комментариям, не источник тактирования для ПЛЛ должен быть включен до запуска ПЛЛ, а для системных тактов должна использоваться ПЛЛ после того, как войдет в рабочий режим.
A-10
Цитата(ViKo @ Oct 7 2010, 12:22) *
Судя по комментариям, не источник тактирования для ПЛЛ должен быть включен до запуска ПЛЛ, а для системных тактов должна использоваться ПЛЛ после того, как войдет в рабочий режим.
Пардон, в коде было правильно, сюда не то скопировал
Код
RCC -> CFGR |= (RCC_CFGR_PLLMULL_0 | RCC_CFGR_PLLMULL_1 | RCC_CFGR_PLLMULL_2);
                                                    // set PLL multiplier x9 (72 MHz)  
    RCC -> CR |= RCC_CR_PLLON;                        // start PLL
    while (!(RCC -> CR & RCC_CR_PLLRDY));              // wait until PLL will be locked                                                

    RCC -> CFGR |= RCC_CFGR_PLLSRC;                    // set PLL source clock - HSE
    RCC -> CFGR |= RCC_CFGR_SW_PLL;                    // PLL selected as system clock
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.