//Cortex系统定时器SysTick提供1个24位、降序、零约束、写清除的计数器,具有灵活的控制机制
#include "stm32f10x_lib.h"
GPIO_InitTypeDef GPIO_InitStructure; //定义用于初始化配置GPIO的结构体变量
static vu32 TimingDelay; //定义为volatile类型
ErrorStatus HSEStartUpStatus; //定义枚举类型的错误状态
void TimingDelay_Decrement(void);
void RCC_Configuration(void);
void NVIC_Configuration(void);
void Delay(vu32 nTime);
int main(void)
{
#ifdef DEBUG
debug();
#endif
RCC_Configuration(); //系统时钟配置
NVIC_Configuration(); //NVIC配置
//系统默认SysTick是8分频(HCLK/8)当前系统时钟72M的话 72/8 = 9MHZ
SysTick_SetReload(9000); //如果设置9000时,计数到9000时,产生1MS中断
//该函数设置SysTick的重装载值,因为是一个24位的计数器,所以重装载值必须在1到0x00ffffff之间
//开启SysTick中断
SysTick_ITConfig(ENABLE); //使能或者失能SysTick中断,参数取值有ENABEL或DISABEL
//开启GPIOB端口 使能APB2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; //选中第6,7,8,9脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度为50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设为推挽输出模式
GPIO_Init(GPIOB, &GPIO_InitStructure); //用配置好的结构体初始化PB口
GPIO_Write(GPIOB, GPIO_Pin_6 | GPIO_Pin_8); //向GPIOB的6,8脚写数据
while (1)
{
GPIO_Write(GPIOB, (u16)~GPIO_ReadOutputData(GPIOB)); //GPIOB口状态取反
Delay(500); //延时500MS
GPIO_Write(GPIOB, (u16)~GPIO_ReadOutputData(GPIOB));
Delay(500); //延时500MS
}
}
void RCC_Configuration(void)
{
//复位RCC外部设备寄存器到默认值
RCC_DeInit();
//打开外部高速晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部高速时钟准备好
HSEStartUpStatus = RCC_WaitForHSEStartUp();
//外部高速时钟已经准别好
if(HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
//配置AHB(HCLK)时钟=SYSCLK
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//配置APB2(PCLK2)钟=AHB时钟
RCC_PCLK2Config(RCC_HCLK_Div1);
//配置APB1(PCLK1)钟=AHB 1/2时钟
RCC_PCLK1Config(RCC_HCLK_Div2);
//配置ADC时钟=PCLK2 1/4
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
//配置PLL时钟 == 外部高速晶体时钟*9
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLL频率为8*9=72MHz
[page]
//配置ADC时钟= PCLK2/4
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
//使能PLL时钟
RCC_PLLCmd(ENABLE);
//等待PLL时钟就绪
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
//配置系统时钟 = PLL时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//检查PLL时钟是否作为系统时钟
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
}
void NVIC_Configuration(void) // 设置向量表基址
{
#ifdef VECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
}
void Delay(u32 nTime) //因为SysTick定时器是1ms中断,所以此函数利用中断延时nTime MS
{
//开启SysTick计数器
SysTick_CounterCmd(SysTick_Counter_Enable); //使能或失能SysTick计数器,输入参数可以是:SysTick_Counter_Enable:使能计数器
//SysTick_Counter_Disable:失能计数器,SysTick_Counter_Clear:清除计数器值为0
TimingDelay = nTime;
while(TimingDelay != 0); //死等待 等待系统定时器的1ms中断 直到计数值达到
//如果跳出了while循环,在说明计时到,即产生了TimingDelay次的定时器中断
//关闭系统滴答
SysTick_CounterCmd(SysTick_Counter_Disable);
//清除SysTick 计数器
SysTick_CounterCmd(SysTick_Counter_Clear);
}
//中断函数的书写格式??? 我试了一下更改了函数名,中断函数就不能运行了,不知道函数名是不是确定的
//不清楚是不是系统根据函数名而确定是中断服务函数的 查了一些资料,目前还没找到明确的说明。
// 其中TimingDelay这个全局变量在使用的时候需要在stm32f10x_it.c中进行一下声明,要不然不能使用,其声明语句是:
// extern vu32 TimingDelay;
//但是在本程序中TimingDelay并没有在stm32f10x_it.c中声明,也可以使用
void SysTick_Handler(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
#ifdef DEBUG
//assert_failed编写于文件main.c或其他用户C文件中
void assert_failed(u8* file, u32 line)
{
while (1)
{
}
}
#endif
关键字:STM32 学习笔记 系统定时器 SysTick