模块程序设计-STM32定时器定时功能(基于systick)

摘要:基于STM32f10x系列库设计的定时器模块,利用systick实现定时功能。

例如main里StartTimer开启eTmrID_USART2对应的定时器,定时1000ms,在while循环不断CheckTimer检测eTmrID_USART2是否到达定时1000ms时间;如果定时到达,进入执行,如果在内部重新StartTimer,即可下次循环继续上述检测。

主函数调用

#define TRUE 1
int main(void)
{
    SystemInit();
       SystickInit();  /* 定时中断初始化 */
    StartTimer(eTmrID_USART2, 1000); //串口模块 1000ms执行一次
    while(1)
    {
        if( TRUE == CheckTimer( eTmrID_USART2))    //检查串口定时的时间到达与否
        {
            ... 
            /*1s到了执行完程序之后如果需要继续定时,需要将对应的定时初始化*/
            StartTimer(eTmrID_USART2, 1000); //串口模块 1000ms执行一次
        }
    }
}

头文件(Systick's Header File):drv_systick.h

#include <stdio.h>
#include <stdint.h>
#include "stm32f10x.h"

#ifndef __DRV_SYSTICK_H
#define __DRV_SYSTICK_H


/* 等待定时器超时期间,可以让CPU进入IDLE状态, 目前是空 */
#define CPU_IDLE()

/* 定时器结构体,成员变量必须是 volatile, 否则C编译器优化时可能有问题 */
typedef struct
{
    volatile uint32_t count;    /* 计数器 */
    volatile uint8_t flag;      /* 定时到达标志  */
}SOFT_TMR;

extern __IO uint32_t LocalTime; /* 10ms */

typedef enum
{    
    eTmrID_WorkLed = 1,                   /* dis文件    工作灯闪烁定时器                  1*/
    eTmrID_APP_LIFE,                      /* 系统生命信号定时器                           2*/
    eTmrID_Modbus,                        /* drv_modbus_master文件 modbus查询500ms等待    3*/
    eTmrID_START,                         /* 启动信号计时                                 4*/
    eTmrID_STOP,                          /* 关机计时                                   5*/
}eSysTick;


extern void DelayMS(uint32_t n);
extern void StartTimer(uint8_t _id, uint32_t _period);
extern uint8_t CheckTimer(uint8_t _id);
extern void delay_us(uint32_t nus);
extern void SystickInit(void);
void SysTick_ISR(void);
extern uint16_t testtime;

#endif

源文件(Systick's Source File)drv_systick.c

#include "drv_systick.h"
#include "drv_adc.h"

/* 在此定义若干个软件定时器全局变量
注意,必须增加volatile,因为这个变量在中断和主程序中同时
被访问,有可能造成编译器错误优化。DelayMS曾出过问题
*/
#define TMR_COUNT   30     /* 软件定时器的个数 ,各个寄存器在h文件里定义*/

SOFT_TMR g_Tmr[TMR_COUNT];
/*******************************************************************************
    函数名:SoftTimerDec
    输  入: 定时器变量指针,每隔1ms减1
    输  出:
    功能说明:
*/
static void SoftTimerDec ( SOFT_TMR *_tmr )
{
    volatile uint8_t t = 1;
    if ( _tmr->flag == 0 )
    {
        if ( _tmr->count > 0 )
        {
            if ( _tmr->count >= t ) _tmr->count -= t;
            else _tmr->count = 0;

            if ( _tmr->count == 0 )
            {
                _tmr->flag = 1;
            }
        }
    }
}

/*******************************************************************************
    函数名:SysTick_ISR
    输  入:
    输  出:
    功能说明:SysTick中断服务程序,每隔1ms进入1次
*/
void SysTick_ISR ( void )
{
    volatile uint8_t i;
        static volatile u32 count;
    
        count++;
    
    for ( i = 0; i < TMR_COUNT; i++ )
    {
        SoftTimerDec ( &g_Tmr[i] );
    }        
    
        testtime++;
}

/*******************************************************************************
    函数名:DelayMS
    输  入: 延迟长度,单位1 ms. 延迟精度为正负1ms
    输  出:
    功能说明:延时函数。占用软件定时器0
*/
void DelayMS ( uint32_t n )
{
    /* 避免 n = 1 出现主程序死锁 */
    if ( n == 1 )
    {
        n = 2;
    }
    g_Tmr[0].count = n;
    g_Tmr[0].flag = 0;
    /* while 循环体最好让CPU进入IDLE状态,已降低功耗 */
    while ( 1 )
    {
//        CPU_IDLE();
        if ( g_Tmr[0].flag == 1 )
        {
            break;
        }
    }
}

/*******************************************************************************
    函数名:StartTimer
    输  入: 定时器ID (0 - 3)
    输  出:
    功能说明:
*/
void StartTimer ( uint8_t _id, uint32_t _period )
{
    if ( _id >= TMR_COUNT )
    {
        return;
    }
    g_Tmr[_id].count = _period;
    g_Tmr[_id].flag = 0;
}

/*******************************************************************************
    函数名:StartTimer
    输  入: 定时器ID (0 - 3)
    输  出: 返回 0 表示定时未到, 1表示定时到
    功能说明:
*/
uint8_t CheckTimer ( uint8_t _id )
{
    if ( _id >= TMR_COUNT )
    {
        return 0;
    }
    return g_Tmr[_id].flag;
}

/*******************************************************************************
    函数名:delay_us
    输  入: 定时时间
    输  出: 无
    功能说明:提供给IIC调用
*/
void delay_us ( uint32_t nus )
{
    uint32_t i, j;
    for ( i = 0; i < nus; i++ )
    {
        for ( j = 0; j < 200; j++ )
            ;
    }
}

void SystickInit(void)
{
    uint8_t i;
    
    for(i=0;i<TMR_COUNT;i++)
    {
        g_Tmr[i].count = 0;
        g_Tmr[i].flag  = 0;
    }
    SysTick_Config(SystemCoreClock / 1000);    //Systick倒计时一次耗时 1ms 然后中断
}

中断函数(Systick's Interrupt Function)void SysTick_Handler(void)

//Systick's Interrupt Function is located in 'stm32f10x_it.c'
void SysTick_Handler(void)
{
    SysTick_ISR();
}

猜你喜欢

转载自blog.csdn.net/qq_39478139/article/details/106227959