STM32三种方法设计LED翻转——软件、系统SysTick()、TIM

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/D_Katter/article/details/81006424
1.方案一:软件不精确延时
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次即可!

2.方案二:系统SysTick()函数配置

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的延时。

3.方案三:定时器中断

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

猜你喜欢

转载自blog.csdn.net/D_Katter/article/details/81006424