void delay_nms(u16 time)
{
u16 i=0;
while(time--)
{
i=12000;
while(i--);
}
}
while(1)
{
GPIO_SetBits(GPIOA,GPIO_Pin_8);
delay_nms(1000);
GPIO_ResetBits(GPIOA,GPIO_Pin_8);
delay_nms(1000);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
delay_nms(1000);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_nms(1000);
}
思路分析:
为什么是delay_nms(1000),并在延时函数中设置为12000?
这种方案的思路是利用单片机执行一句话所需要的时间,将1s的时间耗在单片机进行计数的过程中。
在http://blog.sina.com.cn/s/blog_e107fa730102vorw.html博客中写道:
如果STM32单片机的时钟用的是72 M,一个机器周期=一个时钟周期,一个指令周期等于若干个(1~6)机器周期。
这里如果取最大值6个时钟周期,那个执行一条语句需要的时间是6/72M,那么要实现1ms的时间,测有6*x/72M=1ms,算出来x=12000。
现在需要的是需要1s,则将上述减法过程执行1000次即可!
main.c
#include "stm32f10x.h"
__IO uint32_t TimingDelay;
/******************
*函数名称: LED_GPIO_Config()
*功 能:实现LED等GPIO的配置
*参 数:无
*返 回 值:无
*作 者:Katter
******************/
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_8);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
}
/******************
*函数名称: Init_SysTick(void)
*功 能:1ms中断的定时参数
*参 数:无
*返 回 值:无
*作 者:Katter
******************/
void Init_SysTick(void)
{
if(SysTick_Config(SystemCoreClock/1000))
{
while(1); //SysTick_Config等待配置成功
}
}
/******************
*函数名称: delay_ms()
*功 能:delay_ms(__IO uint32_t nTime)
*参 数:有
*返 回 值:无
*作 者:Katter
******************/
void delay_ms(__IO uint32_t nTime)
{
TimingDelay =nTime;
while(TimingDelay!=0);
}
int main(void)
{
SystemInit();
LED_GPIO_Config();
Init_SysTick();
while(1)
{
{
GPIO_SetBits(GPIOA,GPIO_Pin_8);
GPIO_ResetBits(GPIOA,GPIO_Pin_8);
delay_ms(1000);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(1000);
}
}
}
中断函数
void SysTick_Handler(void)
{
if(TimingDelay!=0x00)
{
TimingDelay--;
}
}
思路分析:
Init_SysTick(void)函数是重点。SysTick—系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。系统定时器
是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置
系统时钟 SYSCLK 等于 72M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就产
生一次中断,以此循环往复
也就是相当于只要我们配置了寄存器中的递减起始值,就可以控制中断的时间。
72M的时钟,要1ms产生一次中断,测起始的值为X/72M=1ms=72K,因此在函数的参数中赋值为SystemCoreClock/1000
这样就将递减的起始值设置成了72K,可以过1ms产生一次中断,在中断中计数1000次,就可以达到1s的延时。
u16 i;
/*******************
*函数名称: LED_GPIO_Config()
*功 能:实现LED等GPIO的配置
*参 数:无
*返 回 值:无
*作 者:Katter
********************/
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
// GPIO_SetBits(GPIOA,GPIO_Pin_8);
GPIO_ResetBits(GPIOA,GPIO_Pin_8);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
// GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
/*******************
*函数名称:RCC_Configuare()
*功 能:实现复位和系统时钟的控制
*参 数:无
*返 回 值:无
*作 者:Katter
********************/
void RCC_Configuare(void)
{
SystemInit();
RCC_ClockSecuritySystemCmd(ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
}
/*******************
*函数名称: NVIC_Configuare(void)
*功 能:设置中断管理
*参 数:无
*返 回 值:无
*作 者:Katter
********************/
void NVIC_Configuare(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************
*函数名称: TIM3_Configuare(void)
*功 能:初始化TIM3 1ms 定时
*参 数:无
*返 回 值:无
*作 者:Katter
********************/
void TIM3_Configuare(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period=10-1;
TIM_TimeBaseStructure.TIM_Prescaler=(7200-1);
TIM_TimeBaseStructure.TIM_ClockDivision=0;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_Trigger,ENABLE);
TIM_Cmd(TIM3,ENABLE);
}
int main()
{
RCC_Configuare();
LED_GPIO_Config();
NVIC_Configuare();
TIM3_Configuare();
// GPIO_ResetBits(GPIOA,GPIO_Pin_8);
while(1);
// return 0;
}
思路分析:定时器产生1s的中断,在中断中对LED实现开通和关闭。
参考资料:
STM32单片机应用与全案例实践
http://blog.sina.com.cn/s/blog_e107fa730102vorw.html
零死角玩转STM32.pdf