zoukankan      html  css  js  c++  java
  • 基于Systick系统时钟延时的LED闪烁灯

    1、回顾我们的51 单片机编程,当我们需要做系统延迟的时候,最常采用的一
    种方式就是使用for 循环的空语句等待来实现。

    当然,在STM32 里面也可以这么实现。但是在STM32 的Cortex 内核里面,有个比其更加精准的定时器专业用于

    系统定时,我们称之为Cortex 系统定时器(SysTick,系统滴答)。

    Systick 就是一个定时器而已,只是它放在了NVIC(中断事件)中,

    主要的目的是为了给操作系统提供一个硬件上的中断(号称滴答中断)。

    这样,只要设置好其中断的时间,就可以每隔一定时间跳入其处理程序,

    通过这种方式,我们可以做一些分时的任务处理。

    然而,由于我们刚刚接触STM32,因此我们本课程内容,仅仅是

    用其做一些延迟函数的处理。可能有些同学有疑问,微控制器的定时器资源一般

    比较丰富,比如STM32 存在8 个定时器,为啥还要再提供一个SYSTICK?原因就
    是所有基于ARM Cortex_M3 内核的控制器都带有SysTick 定时器,这样就方便了
    程序在不同的器件之间的移植。而使用RTOS 的第一项工作往往就是将其移植到
    开发人员的硬件平台上,由于SYSTICK 的存在无疑降低了移植的难度。具体
    Systick 的概述,请参考《Cortex-M3 权威指南》179 页。

    关于SysTick 的编程
    流程如下:
     配置系统时钟;
     配置SysTick;
     写SysTick 中断处理函数;
     编写delay 延迟函数;

    第一步:

    先让我们来设置系统时钟。关于系统时钟的配置,我们可以直接使
    用默认的固件库函数“void SystemInit(void);”,这个函数在固件库手册上面
    是没有的,一旦使用默认配置之后,整个STM32 的系统时钟就会被配置成:
    SYSCLK(系统时钟) = 72MHZ(系统最高允许时钟);
    AHB 总线时钟= 72MHZ(AHB 最高允许时钟);
    APB1 总线时钟= 36MHZ(APB1 最高允许时钟);
    APB2 总线时钟= 72MHZ(APB2 最高允许时钟);

    第二步:

    配置SysTick。我们在设置SysTick 的时候,只用到“core_cm3.h”
    文件的函数“__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)”。
    这个函数在固件库里面是没有介绍的,因为这个函数是在“core_m3.h”里面定
    义的,所以不属于STM32 固件库的范畴。参考《STM32F10xxx 参考手册》第80
    页的STM32 系统时钟框图,我们可以知道,系统时钟(AHB,此时为72MHz)经8
    分频或者不分频之后产生的时钟给Systick 作为时钟震荡源,因此此时的
    Systick 默认为频率为72MHz,如果需要使用8 分频之后的频率,可以使用函数
    “SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);”,因此我们只
    需要把Systick 设置成72000 时(计算方式:(1/72000000Hz)*72000 次=1ms),
    就能产生1ms 时间基准,说白了就是一个中断信号。

    见函数void Systick_Init(void)配置

    第三步:

    编写Systick 的中断处理函数。对于STM32 所有的中断处理函数,
    我们都可以在对应的“startup_stm32f10x_xx.s”里面找到其入口。比如,在做
    Systick 中断处理的时候,我们选择的入口地址就是“SysTick_Handler”。因
    此,我们可以写如下的代码,如程序片段6 所示。同时,需要把“stm32f10x_it.c”
    里面的“SysTick_Handler”入口屏蔽,不然会报错。

     1 __IO uint32_t TimingDelay;
     2 void TimingDelay_Decrement(void)
     3 {
     4 if (TimingDelay != 0x00)
     5 {
     6 TimingDelay--;
     7 }
     8 }
     9 void SysTick_Handler(void)
    10 {
    11 TimingDelay_Decrement();
    12 }

    第四步,写delay_ms函数

    1 void delay_ms(__IO uint32_t nTime)//延迟函数,设置为US
    2 {
    3 TimingDelay = nTime;//时钟滴答数
    4 while(TimingDelay != 0);
    5 }

    以上只是Systick的配置,下面是一个完整实现LED灯闪烁的代码

    下面包含四个文件:分别是mian.c文件、timer.c文件、timer.h文件、led.c文件、led.h文件

    mian.c文件、

     1 #include "stm32f10x.h"   // 相当于51单片机中的  #include <reg51.h>
     2 #include "timer.h"
     3 #include "led.h"
     4 int main(void)
     5 {
     6     SystemInit();//初始化系统,使得系统频率为72MHZ
     7     systick_init();//配置Systick,使得1ms产生
     8     led_gpio_init();//LED灯的配置,要用到LED灯就要配置
     9     while(1)
    10     {
    11         GPIO_SetBits(GPIOB,GPIO_Pin_5);
    12         delay_ms(1000);//延时1s
    13         GPIO_ResetBits(GPIOB,GPIO_Pin_5);
    14         delay_ms(1000);
    15     }
    16 }

    timer.c文件、

     1 #include "timer.h"
     2 #include "stm32f10x.h"
     3 __IO uint32_t TimingDelay;//相当于宏定义一个TimingDelay
     4 void systick_init()
     5 {
     6     //配置Systick重载值,系统时钟为72MHZ
     7     //设置72000,中断时间:72000*(1/72000000)=1ms
     8     //有返回值,返回0则装在成功
     9     if(SysTick_Config(72000)==1)
    10     {
    11         while(1);
    12             
    13     }
    14 }
    15 
    16 
    17 
    18 void TimingDelay_Decrement(void)
    19 {
    20     if(TimingDelay !=0x00)
    21     {
    22         TimingDelay--;
    23     }
    24 }
    25 /*中断处理函数,中断一次减1ms*/
    26 void SysTick_Handler(void)
    27 {
    28     TimingDelay_Decrement();//调用上面的函数
    29 }
    30 
    31 
    32 
    33 void delay_ms(__IO uint32_t nTime)
    34 {
    35     TimingDelay = nTime;//时钟滴答数
    36     while(TimingDelay !=0);
    37 }
    38     

    注意:这里需要做一个细节!!

    在stm32f10x_it.c文件里面的void SysTick_Handler(void)这个函数注释掉。

    看截图:

    timer.h文件、

     1 #ifndef _TIMER_H_
     2 #define _TIMER_H_
     3 
     4 #include "stm32f10x_tim.h"
     5 #include "stm32f10x_rcc.h"
     6 #include "stm32f10x_it.h"
     7 #include "misc.h"
     8 
     9 extern __IO uint32_t TimingDelay;
    10 
    11 void systick_init();
    12 void delay_ms(__IO uint32_t nTime);
    13 #endif

    led.c文件、

     1 #include "led.h"
     2 #include "stm32f10x_gpio.h"
     3 //GPIO初始化
     4 void led_gpio_init()
     5 {
     6     GPIO_InitTypeDef gpio;
     7     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
     8     gpio.GPIO_Mode=GPIO_Mode_Out_PP;
     9     gpio.GPIO_Pin=GPIO_Pin_5;
    10     gpio.GPIO_Speed=GPIO_Speed_50MHz;
    11     GPIO_Init(GPIOB,&gpio);
    12 }

    led.h文件

    1 #ifndef _LED_H_
    2 #define _LED_H_
    3 
    4 
    5 void led_gpio_init();
    6 
    7 #endif
  • 相关阅读:
    2.Android之按钮Button和编辑框EditText学习
    《DSP using MATLAB》Problem 3.8
    《DSP using MATLAB》Problem 3.7
    《DSP using MATLAB》Problem 3.6
    《DSP using MATLAB》Problem 3.5
    《DSP using MATLAB》Problem 3.4
    《DSP using MATLAB》Problem 3.3
    《DSP using MATLAB》Problem 3.2
    《DSP using MATLAB》Problem 3.1
    《DSP using MATLAB》Problem 2.20
  • 原文地址:https://www.cnblogs.com/kinson/p/7967332.html
Copyright © 2011-2022 走看看