找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2137|回复: 0
打印 上一主题 下一主题
收起左侧

利用stm32systic定时器用作时钟基线实现多个定时器定时

[复制链接]
跳转到指定楼层
楼主
ID:362131 发表于 2020-5-8 21:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
systick时钟基线运用,充分利用cpu性能,拒绝延时等浪费cpu时间行为

systick.c中的程序:
/*****************************************************************************************************/

SOFT_TMR g_Tmr[COUNT_TIM];

/* cpu运行时间,单位ms */
__IO uint32_t g_iRunTime = 0;

static void Soft_TimerDec(SOFT_TMR *_tmr);

/*
*********************************************************************************************************
*    函 数 名:Systick_Init
*    功能说明:初始化Systick定时器
*    形    参:无
*    返 回 值:无
*********************************************************************************************************
*/
void Systick_Init(void)
{   
    /* 清零所有的软件定时器 */
    memset(g_Tmr,0,COUNT_TIM * sizeof(g_Tmr));

    /*
        配置systic中断周期,并启动systick中断。
        这个函数在 \Libraries\CMSIS\CM3\CoreSupport\core_cm3.h
        
        Systick中断向量在(\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm\
            startup_stm32f10x_hd.s 文件中定义为 SysTick_Handler。
        SysTick_Handler函数的实现在stm32f10x_it.c 文件。
        SysTick_Handler函数调用了SysTick_ISR()函数,在本文件末尾。
    */   
    SysTick_Config(SystemCoreClock / 1000 * Systick_tim);
}

/*
*********************************************************************************************************
*    函 数 名: SysTick_ISR
*    功能说明:SysTick中断服务程序,在SysTick_Handler中调用
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
void SysTick_ISR(void)
{
    static uint8_t s_count = 0;
    uint8_t i;

    for (i = 0; i < COUNT_TIM; i++)
    {
        Soft_TimerDec(&g_Tmr[ i]);
    }

    g_iRunTime += Systick_tim;        /* cpu运行时间增Systick_tim*/
    if (g_iRunTime >= 0x9A7EC800)    /* 30天清零 */
    {
        g_iRunTime = 0;
    }
        
    s_count += Systick_tim;
    if (s_count >= 10)
    {
        s_count = 0;

        /*
            此处可加入按键的检测。按键检测每隔10ms一次就行了,一般做40ms的滤波处理就可以
            有效过滤掉机械动作造成的按键抖动。
        */
//        Key_Scan();
    }
}
/*
*********************************************************************************************************
*    函 数 名: delay_ms
*    功能说明: ms级延迟,延迟精度为正负1ms
*    形    参:n : 延迟长度,单位 ms。
*    返 回 值: 无
*********************************************************************************************************
*/
void Delay_Ms(int32_t n)
{
//    /* 避免 n = 1 出现主程序死锁 */
//    if (n <= 1)
//    {
//        n = 2;
//    }
   
    __set_PRIMASK(1);          /* 关中断 */
    g_Tmr[DELAY_TIM].count = n;
    g_Tmr[DELAY_TIM].flag = 0 ;
    __set_PRIMASK(0);          /* 开中断 */

    while (1)
    {
        CPU_IDLE();    /* 此处是空操作。用户可以定义,让CPU进入IDLE状态,以降低功耗;或实现喂狗 */

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

systick.h中的代码
/*********************************************************************************************/
#define SYSTICK_MODE    0    //0中断模式,1查询模式

/* 软件延时 */
void SoftDelay_Ms(uint16_t nms);
void SoftDelay_Us(uint16_t nus);

/**********************************************中断模式**********************************************/
#if SYSTICK_MODE == 0   

/* 目前是空操作,用户可以定义让CPU进入IDLE状态的函数和喂狗函数 */
#define CPU_IDLE()

#define Systick_tim        1        //Systic中断时间(时钟基线),单位:ms

/*
    可在此处枚举中增加若干个软件定时器
    注意:变量在中断和主程序中同时被访问,有可能造成编译器错误优化,必须增加__IO 即 volatile。
*/
enum enum_tim_id{
    DELAY_TIM = 0,    //第1个保留给Delay_Ms()使用
    USER_TIM1,
    USER_TIM2,
    USER_TIM3,
    COUNT_TIM        //软件定时器的个数
};

/* 定时器结构体 */
typedef struct
{
    volatile int32_t count;    //计数器
    volatile uint8_t flag;    //定时到达标志
}SOFT_TMR;


/* 供外部调用的函数声明 */
void Systick_Init(void);
void SysTick_ISR(void);


更多请下载源码
systick时钟基线运用.7z (453.11 KB, 下载次数: 13)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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