За изучение 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 запускается и светодиод горит.
Почему так происходит?
Сообщение отредактировал 011119xx - Jan 19 2011, 05:04