野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 15386|回复: 2

stm32 systick 软件定时器函数使用

[复制链接]
发表于 2015-7-20 23:45:29 | 显示全部楼层 |阅读模式
大家好,
stm32 systick 软件定时器有几个函数,大家交流下,怎么使用,thanks
/*
*********************************************************************************************************
*        函 数 名: StartTimer
*        功能说明: 启动一个定时器,并设置定时周期。
*        形    参:        _id     : 定时器ID,值域【1,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。
*                                                  定时器ID = 0 已用于DelayMS()函数
*                                _period : 定时周期,单位10us
*        返 回 值: 无
*********************************************************************************************************
*/
void StartTimer(uint8_t _id, volatile uint32_t _period)
{
        if (_id >= TMR_COUNT)
        {
                /* while(1); 死机 */
                return;
        }

//        __set_PRIMASK(1);                  /* 关中断 */
        g_Tmr[_id].count = _period;
        g_Tmr[_id].flag = 0;
//        __set_PRIMASK(0);                  /* 开中断 */
       

}

/*
*********************************************************************************************************
*        函 数 名: CheckTimer
*        功能说明: 检测定时器是否超时
*        形    参:        _id     : 定时器ID,值域【1,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。
*                                                  0 用于
*                                _period : 定时周期,单位10us
*        返 回 值: 返回 0 表示定时未到, 1表示定时到
*********************************************************************************************************
*/
uint8_t CheckTimer(uint8_t _id)
{
        if (_id >= TMR_COUNT)
        {
                return 0;
        }

        if (g_Tmr[_id].flag == 1)
        {
                g_Tmr[_id].flag = 0;
                return 1;
        }
        else
        {
                return 0;
        }
       
//        return g_Tmr[_id].flag;
}

请大侠指点,多谢
回复

使用道具 举报

发表于 2015-7-21 08:50:25 | 显示全部楼层
你两个函数不够完整吧,应该还有中断函数部分才能正常使用
配套光盘有systick例程,你可以看看
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-7-21 21:42:24 | 显示全部楼层
这是整个的,想用软件定时器,比如StartTimer(2, 10000);用函数CheckTimer(2)检测定时时间是否到
                        if( CheckTimer(2) )   /* 判断定时器超时时间 */
                        {
                                LED2_ON;
                                LED3_OFF;
                        }
但是不起作用,大家交流下
#include "bsp_SysTick.h"
#include "bsp_key.h"
#include <stdio.h>

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

#define Delay_ms(x) Delay_10us(100*x)         //1ms

typedef struct
{
        volatile uint32_t count;        /* 计数器 */
        volatile uint8_t flag;                /* 定时到达标志 */
}SOFT_TMR;
static __IO u32 TimingDelay;

#define TMR_COUNT        4                                                /* 软件定时器的个数 */
SOFT_TMR g_Tmr[TMR_COUNT];    /*bsp_SysTick.h*/

/* 全局运行时间,单位10ms,用于uIP */
__IO int32_t g_iRunTime = 0;

/**
  * @brief  启动系统滴答定时器 SysTick
  * @param  无
  * @retval 无
  */
void SysTick_Init(void)
{       
        uint8_t i;
       
        /* 清零所有的软件定时器 */
        for (i = 0; i < TMR_COUNT; i++)
        {
                g_Tmr[i].count = 0;
                g_Tmr[i].flag = 0;
        }
        /* SystemCoreClock / 1000    1ms中断一次
         * SystemCoreClock / 100000         10us中断一次
         * SystemCoreClock / 1000000 1us中断一次
         */
//        if(SysTick_Config(SystemCoreClock / 100000))        // ST3.5.0
//        {
//                /* Capture error */
//                while (1);
//        }
        SysTick_Config(SystemCoreClock / 100000);
                // 关闭滴答定时器  
        SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}

/**
        * @function Delay_10us
  * @brief   us延时程序,10us为一个单位
  * @param  
  *        @arg nTime: Delay_10us( 1 ) 则实现的延时为 1 * 10us = 10us
  * @retval  无
  */
void Delay_10us(__IO u32 nTime)
{
        TimingDelay = nTime;       

        // 使能滴答定时器  
        SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;

        while(TimingDelay != 0);
}

/**
        * @function SoftTimerDec
  * @brief    定时器变量指针,每隔1ms减1
  * @param  
  *
        @arg
  * @retval  
  */
static void SoftTimerDec(SOFT_TMR *_tmr)
{
        if (_tmr->flag == 0)
        {
                if (_tmr->count > 0)
                {
                        if (--_tmr->count == 0)
                        {
                                _tmr->flag = 1;
                        }
                }
        }
}

/**
        * @function SysTick_ISR
  * @brief    SysTick中断服务程序,每隔10us进入1次
  * @param  
  *        @arg
  * @retval  
  */
void SysTick_ISR(void)
{
        static uint8_t s_count = 0;
        uint8_t i;

        for (i = 0; i < TMR_COUNT; i++)
        {
                SoftTimerDec(&g_Tmr[i]);
        }

//        g_iRunTime++;        /* 全局运行时间每10us增1 */       
//        if (g_iRunTime == 0x7FFFFFFF)
//        {
//                g_iRunTime = 0;
//        }

        /* 所有按键的检测,按键检测每隔10ms一次,
        一般做40ms的滤波处理就可以有效过滤掉机械动作造成的按键抖动。
        */
        if (++s_count >= 10)    /* 10us * 10 = 100us every time*/
        {
                s_count = 0;

                KeyPro();                /* 该函数在 bsp_key.c 中实现 */
        }
}

/**
        * @function DelayMS
  * @brief   ms延时程序,1ms为一个单位
  * @param   延时函数,占用软件定时器0
  *        @arg
  * @retval  
  */
void DelayMS(uint32_t n)
{
        if (n == 1)     /* 避免 n = 1 出现主程序死锁 */
        {
                n = 2;
        }
       
        g_Tmr[0].count = n;
        g_Tmr[0].flag = 0;
       
        while (1)
        {
                CPU_IDLE();      /* 此处是空操作。用户可以定义,让CPU进入IDLE状态,以降低功耗;或实现喂狗 */

                if (g_Tmr[0].flag == 1)            /* 等待延迟时间到 */
                {
                        break;
                }
        }
}

/**
        * @function TimingDelay_Decrement
  * @brief  获取节拍程序
  * @param  无
  * @retval 无
  * @attention  在SysTick 中断函数 SysTick_Handler()调用
  */
void TimingDelay_Decrement(void)
{
        if(TimingDelay != 0x00)
        {
                TimingDelay--;
        }
}

/*
*********************************************************************************************************
*        函 数 名: StartTimer
*        功能说明: 启动一个定时器,并设置定时周期。
*        形    参:        _id     : 定时器ID,值域【1,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。
*                                                  定时器ID = 0 已用于DelayMS()函数
*                                _period : 定时周期,单位10us
*        返 回 值: 无
*********************************************************************************************************
*/
void StartTimer(uint8_t _id, volatile uint32_t _period)
{
        if (_id >= TMR_COUNT)
        {
                /* while(1); 死机 */
                return;
        }

//        __set_PRIMASK(1);                  /* 关中断 */
        g_Tmr[_id].count = _period;
        g_Tmr[_id].flag = 0;
//        __set_PRIMASK(0);                  /* 开中断 */
       
}

/*
*********************************************************************************************************
*        函 数 名: CheckTimer
*        功能说明: 检测定时器是否超时
*        形    参:        _id     : 定时器ID,值域【1,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。
*                                                  0 用于
*                                _period : 定时周期,单位10us
*        返 回 值: 返回 0 表示定时未到, 1表示定时到
*********************************************************************************************************
*/
uint8_t CheckTimer(uint8_t _id)
{
        if (_id >= TMR_COUNT)
        {
                return 0;
        }

        if (g_Tmr[_id].flag == 1)
        {
                g_Tmr[_id].flag = 0;
                return 1;
        }
        else
        {
                return 0;
        }
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 01:51 , Processed in 0.027388 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表