Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема инициализации STM32F103
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
AlexandrB
Здравствуйте решил занятся STM32 и сразу же встала проблема.
Делаю простой ког мигания светодиодом.
CODE
#include "stm32f10x_gpio.h"
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#define SYSCLK_FREQ_72MHz 72000000

void delay_ms(uint32_t miliseconds)
{
unsigned long i;
for (i=0; i<miliseconds*72000; i++) {
}
}

void init_clocks()
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
/* Enable HSE */
RCC->CR &= ~((uint32_t)RCC_CR_HSION);
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;
}

RCC->CR |= ((uint32_t)RCC_CR_CSSON);// protector - with auto swithcing on HSI if HSE is bad

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;//AHB = 72MHz

/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;//72MHz

/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;//APB1 = 72/2 = 36MHz max


/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));//16-21bits unset
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);//PLL = HSE(not divided) * 9; 16,18-20 set

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

/* 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));//unset 0,1
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;//pll select as SYSCLK

/* 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 */
}

}
void init_gpio_a()
{

GPIO_InitTypeDef porta;
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA, ENABLE);
GPIO_StructInit(&porta);
porta.GPIO_Pin = GPIO_Pin_12;
porta.GPIO_Mode = GPIO_Mode_Out_PP;
porta.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&porta);

}
int main(void)
{
uint16_t uart_data=0;

init_clocks();
init_gpio_a();
while(1)
{

GPIO_SetBits(GPIOA,GPIO_Pin_12);
delay_ms(1000);
GPIO_ResetBits(GPIOA,GPIO_Pin_12);
delay_ms(1000);

}
}

Работаю в CooCox CoIDE
Version: 2.0.2
Build id: 20150213-2.0.2

Отлаживаю через китайский ST-LINKV2

Пытаюсь запустить - светодиод горит, не мигает.
Пытаюсь дебажить - все начинается хорошо но после строчки FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; (в диасемблере ldr r3, [pc, #140] ; (0x8001c20 <init_clocks+276>))
код исчезает, появляется надпись No source available for ""

Попробовал убрать функцию void init_clocks(), и работать на дефолте, все мигает, дебажит, правда время задержки между миганиями почемуто не 1 сек (1.2 примерно), хотя меняю функцию delay_ms() для работы с 8МГц.
Genadi Zawidowski
Дело древнее - но у меня работает так:
Код
#if (CPU_FREQ < 24000000ul)
    // Flash 0 wait state
    FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_0;
#elif (CPU_FREQ <= 48000000ul)
    // Flash 1 wait state
    FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_1;
#else
    // Flash 2 wait state (if freq in 24..48 MHz range - 1WS.)
    #if CPUSTYLE_STM32F10X
        FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_2;
    #else
        FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_1;
    #endif
#endif


Разбив операцию установки задержки на две (сперва сброс в "0", потом ставим что надо, возможно Вы заставляете процесоср работать в "странном" режиме.
Кстати, к коду установки clock source тоже относится.

Полностью код функции:
CODE
static void
lowlevel_stm32f10x_pll_clock(void)
{
#if WITHCPUXTAL
// внешний кварцевый резонатор
// Enable HSI
RCC->CR = (RCC->CR & ~ (RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSEBYP)) | RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY))
;
#else /* WITHCPUXTAL */
// внутренний генератор
// Enable HSI
RCC->CR = (RCC->CR & ~ (RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSEBYP)) | RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY))
;
#endif /* WITHCPUXTAL */

// Enable Prefetch Buffer
FLASH->ACR |= FLASH_ACR_PRFTBE;

#if (CPU_FREQ < 24000000ul)
// Flash 0 wait state
FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_0;
#elif (CPU_FREQ <= 48000000ul)
// Flash 1 wait state
FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_1;
#else
// Flash 2 wait state (if freq in 24..48 MHz range - 1WS.)
#if CPUSTYLE_STM32F10X
FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_2;
#else
FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | FLASH_ACR_LATENCY_1;
#endif
#endif

// PPRE2: APB high-speed prescaler (APB2)
// PPRE1: APB low-speed prescaler (APB1) = PREDIV1 bits
// HPRE: AHB prescaler

#if CPU_FREQ >= 48000000UL
// HCLK = SYSCLK, PCLK2 = HCLK, PCLK1 = HCLK/1
RCC->CFGR = (RCC->CFGR & ~ (RCC_CFGR_HPRE | RCC_CFGR_PPRE2 | RCC_CFGR_PPRE1)) |
RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV2;
#else
// HCLK = SYSCLK, PCLK2 = HCLK, PCLK1 = HCLK/1
RCC->CFGR = (RCC->CFGR & ~ (RCC_CFGR_HPRE | RCC_CFGR_PPRE2 | RCC_CFGR_PPRE1)) |
RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV1;
#endif

// STM32F10X_MD defined
// For STM32F30x:
// PLLXTPRE: This bit is the same as the LSB of PREDIV in RCC_CFGR2
// RCC_CFGR_PLLSRC_HSI_Div2
#if WITHCPUXTAL
#if (REF1_DIV != 1) && (REF1_DIV != 2)
#error REF1_DIV wrong value - 1 or 2 supported by CPU
#endif
RCC->CFGR = (RCC->CFGR & ~ (RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)) |
((REF1_DIV == 2) ? RCC_CFGR_PLLXTPRE : 0) |
RCC_CFGR_PLLSRC |
(REF1_MUL - 2) * RCC_CFGR_PLLMULL_0 |
0;
#else /* WITHCPUXTAL */
#if (REF1_DIV != 1) && (REF1_DIV != 2)
#error REF1_DIV wrong value - only 2 supported by CPU
#endif
RCC->CFGR = (RCC->CFGR & ~ (RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)) |
RCC_CFGR_PLLSRC_HSI_Div2 |
(REF1_MUL - 2) * RCC_CFGR_PLLMULL_0 |
0;
#endif /* WITHCPUXTAL */


// 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 = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;

// Wait till PLL is used as system clock source
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
;

#if WITHCPUXTAL
// HSI (8 MHz RC) off
RCC->CR &= ~ RCC_CR_HSION;
#endif

#if 0
// Тестирование тактовой частоты - подача на сигнал MCO
//RCC->CFGR = (RCC->CFGR & ~ RCC_CFGR_MCO) | RCC_CFGR_MCO_SYSCLK;
RCC->CFGR = (RCC->CFGR & ~ RCC_CFGR_MCO) | RCC_CFGR_MCO_PLL; // Смотрим PLL / 2
//RCC->CFGR = (RCC->CFGR & ~ RCC_CFGR_MCO) | RCC_CFGR_MCO_HSI;
while ((RCC->CFGR & RCC_CFGR_MCOF) == 0)
;
arm_hardware_pioa_altfn50(1U << 8, AF_SYSTEM); // PA8, AF=0: MCO

#endif
}
RadiatoR
Цитата(AlexandrB @ Nov 15 2015, 10:52) *
правда время задержки между миганиями почемуто не 1 сек (1.2 примерно), хотя меняю функцию delay_ms() для работы с 8МГц.


Время задержки не равно 1 сек, потому что вы просто считаете переменную. То, что вы ведете декремент за 1 цикл - не значит, что всего за 1 секунду будет декрементировано и проверено (а это еще такты) 72000 раз. Нормальную задержку позволяет сделать таймер.
AlexandrB
Цитата(Genadi Zawidowski @ Nov 15 2015, 15:24) *
Разбив операцию установки задержки на две (сперва сброс в "0", потом ставим что надо, возможно Вы заставляете процесоср работать в "странном" режиме.


Спасибо, кажется вы были правы! Теперь все работает sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.