读书人

STM32f103R8实验:SysTick实验中的有关

发布时间: 2013-07-09 09:50:47 作者: rapoo

STM32f103R8实验:SysTick实验中的问题
最近在看《STM32自学笔记》,仿照书上的例子写了个用SysTick查询方式定时,控制LED灯闪烁的实验程序,源代码如下:


#include "stm32f10x_lib.h"

void RCC_Configuration(void);
void GPIO_Configuration(void);
void SysTick_Configuration(void);
void Delay_Second(void);

int main(void)
{
RCC_Configuration();
GPIO_Configuration();
SysTick_Configuration();

while(1)
{
GPIO_SetBits(GPIOB, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
Delay_Second();
GPIO_ResetBits(GPIOB, GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
Delay_Second();
}

}

void RCC_Configuration(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
if(RCC_WaitForHSEStartUp() == SUCCESS)
{
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
FLASH_SetLatency(FLASH_Latency_2);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_9);//16M晶振,16/2*9 = 72M
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08);
}

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
}

void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;


GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void SysTick_Configuration(void)
{
SysTick_CounterCmd(SysTick_Counter_Disable);
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//SysTick使用HCLK/8 = 9.0MHz的时钟
SysTick_CounterCmd(SysTick_Counter_Clear);
SysTick_SetReload(9000 * 1000);// 9.0MHz的时钟定时1秒钟
}

void Delay_Second(void)
{
SysTick_CounterCmd(SysTick_Counter_Enable);
while(SysTick_GetFlagStatus(SysTick_FLAG_COUNT) == 0);
SysTick_CounterCmd(SysTick_Counter_Disable);
SysTick_CounterCmd(SysTick_Counter_Clear);
}


程序很简单,相信稍微有点STM32编程经验的人都能看懂。可是奇怪的是,我按SysTick的时钟配置的是1秒钟定时(详见程序中注释
的代码),可是实验现象是LED灯的亮灭时间根本不止1秒钟,个人感觉至少有8~9秒钟,仔细检查各个配置函数的参数设置,实在不知
道问题出在哪里,望哪位大侠百忙之中能帮我看看,感激不尽! STM32 SysTick
[解决办法]
引用:
谢谢了,我检查了一下,晶振值没有错误,我的外接晶振是16M的,实际设置的也是16M。
又单步跟踪了下程序,发现时钟初始化函数void RCC_Configuration(void)里面的RCC_WaitForHSEStartUp()函数的返回值是ERROR,也就是说等待外部时钟启动的结果是:启动失败!又检查了外部时钟的连接,线路连接都是正确的,这会真是糊涂了,外部时钟启动失败是怎么回事。。。


硬件上如果选择的负载电容与晶体谐振器搭配不当可能造成时钟电路难以起振,我通常用27pF,比较顺利。另外如果你设置了反馈电阻(并联在晶体谐振器两脚之间),需要去掉,因为STM32内置了反馈电阻。OSC_OUT脚与晶体电路之间应该串联一个限流电阻,哪怕用0R电阻,也得有个封装画在PCB上留作备用。

时钟电路硬件设计请参考ST官方应用文档AN2867《ST微控制器振荡电路设计指南》。

软件方面ST标准库里的RCC初始化流程我总觉得 HSEStartUpStatus 这个变量只读一次就去判断是否成功,如果晶体启动慢一点就错过时机了。所以改成如下流程:

void RCC_Configuration(void)
{
// RCC system reset(for debug purpose)
RCC_DeInit();

// Enable HSE (High Speed External clock)
RCC_HSEConfig(RCC_HSE_ON);

// Wait till HSE is ready
HSEStartUpStatus = RCC_WaitForHSEStartUp();

// Confirm HSE is ready, if not, re-check till it is.
while(HSEStartUpStatus != SUCCESS)
{
HSEStartUpStatus = RCC_WaitForHSEStartUp();
}

// Enable Prefetch Buffer
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

// Set flash memory latency
FLASH_SetLatency(FLASH_Latency_2);

// HCLK = SYSCLK = 72MHz
RCC_HCLKConfig(RCC_SYSCLK_Div1);

// PCLK2 = HCLK = 72MHz
RCC_PCLK2Config(RCC_HCLK_Div1);

// PCLK1 = HCLK/2 = 36MHz
RCC_PCLK1Config(RCC_HCLK_Div2);

// ADCCLK = PCLK2/6 = 12MHz (Maximum available = 14MHz)


RCC_ADCCLKConfig(RCC_PCLK2_Div6);

// On ST-ICE the PLL output clock is fixed to 72 MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

// Enable PLL
RCC_PLLCmd(ENABLE);

// Wait till PLL is ready
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{}

// Select PLL as system clock source
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

// Wait till PLL is used as system clock source
while (RCC_GetSYSCLKSource() != 0x08)
{}
}

我的晶体是8M的,具体的设置你依据自己系统参数去定。

读书人网 >单片机

热点推荐