硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3671|回复: 6
收起左侧

[有问必答] 基于stm32 TimeBase的多路软件定时器

[复制链接]

5

主题

23

回帖

38

积分

新手上路

积分
38
发表于 2019-8-29 16:04:38 | 显示全部楼层 |阅读模式
我按照网上的思路做了个多路软件定时器,但是一直没运行起来,请硬汉帮忙
以下是代码部分:
/************************************BaseTime.c*************************************************************/


#include "BaseTime.h"
#include "bsp_led.h"
#define MAX_SOFTTIMER 4
static Timer_typedef TimerList[10];

static void BaseTime_Config(void)
{
    uint8_t i=0;
    TIM_TimeBaseInitTypeDef        TIM_TimeBaseStructure;
    //开启定时器时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);//RCC_APB1Periph_TIM7
   
    TIM_TimeBaseStructure.TIM_Period = (1000-1);//1000
    TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//71
    //初始化基本定时器
    TIM_TimeBaseInit(TIM6,&TIM_TimeBaseStructure);
    TIM_ARRPreloadConfig(TIM6, ENABLE);
    //清除计数器中断标志
    TIM_ClearFlag(TIM6,TIM_FLAG_Update);
    //开启计数器中断
    TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);
    //使能定时器
    TIM_Cmd(TIM6,ENABLE);
    for(i = 0; i < MAX_SOFTTIMER; i++) //初始化MAX_SOFTTIMER个软定时器
    {
        TimerList[i].Timeoutcnt = 1000001;//超时初值1000001
        TimerList[i].Timeout = 1000001; //超时的装载值
        TimerList[i].Timeoutfuc = (void*)0;//超时的回调函数
        TimerList[i].Parameter = (void*)0;//超时的参数
    }
}

static void BASE_TIM_NVIC_Config(void)
{
        NVIC_InitTypeDef        NVIC_InitStructure;
        //设置中断优先组
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
        //设置中断源
        NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
   
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
        
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        
        NVIC_Init(&NVIC_InitStructure);
   
}

/*SoftTimer_TimerStart:软定时器开始计时
*Input : TimerIdent-软定时器索引
*TimeOut-超时计数值
*Timeoutfuc(parameter)-超时回调函数
*parameter-传递的参数
*flag-定时方式:TIMER_ONESHOT-单次定时,TIMER_PERIOD-周期定时
*return : none
*/
void SoftTimer_TimerStart(u8 TimerIdent, u32 TimeOut, void (*Timeoutfuc)(void* parameter), void* parameter, u8 flag)
{
    if(TimerIdent >= MAX_SOFTTIMER)
    {
      return;
    }
    __disable_irq(); //关闭总中断,不可重入
    TimerList[TimerIdent].Timeoutcnt = TimeOut; //设置超时计数初值
    TimerList[TimerIdent].Timeout = TimeOut; //设置超时的转载值
    TimerList[TimerIdent].Timeoutfuc = Timeoutfuc; //设置超时的回调函数
    TimerList[TimerIdent].Parameter = parameter; //设置超时的参数
    TimerList[TimerIdent].Timerflag = flag; //设置超时标志
    __enable_irq(); //打开总中断
}



/*软定时器复位*/
void SoftTimer_TimerReset(u8 TimerIdent)
{
    if(TimerIdent >= MAX_SOFTTIMER)
    {
      return;
    }
    TimerList[TimerIdent].Timeoutcnt = 1000001; //超时初值
    TimerList[TimerIdent].Timeout = 1000001; //超时的装载值
    TimerList[TimerIdent].Timeoutfuc = (void*)0; //超时的回调函数
    TimerList[TimerIdent].Parameter = (void*)0; //超时的参数
}


/*软定时器重启,只有之前启动过的软定时器才能重启*/
void SoftTimer_TimerRestart(u8 TimerIdent, u32 TimeOut)
{
    if(TimerIdent >= MAX_SOFTTIMER)

    {
      return;
    }
    if(TimerList[TimerIdent].Timeout != 1000001)//保证这路软定时器有效且已经曾经启动过
    {
        TimerList[TimerIdent].Timeoutcnt = TimeOut;//重新设置超时时间
        TimerList[TimerIdent].Timeout = TimeOut; //重新设置超时转载值
    }
}



/*停止软定时器,停止正在计时的软定时器*/
void SoftTimer_TimerStop(u8 TimerIdent)
{
    if(TimerIdent >= MAX_SOFTTIMER)
    {
      return;
    }
    TimerList[TimerIdent].Timeoutcnt = 1000001;
}




void SoftTimer_Execute(void)
{
    u8 i = 0;
    for(i = 0; i < MAX_SOFTTIMER; i++)
    {
    if((TimerList[i].Timeoutcnt != 0) && (TimerList[i].Timeoutcnt <= 1000000))
        {
        TimerList[i].Timeoutcnt--;
        if(TimerList[i].Timeoutcnt == 0)
            {
                if(TimerList[i].Timerflag != TIMER_PERIOD)//单次计时
                {
                  TimerList[i].Timeoutcnt = 1000001;//设置超时初值,超出1000000所以不会继续计数
                }
                else//周期计时
                {
                  TimerList[i].Timeoutcnt = TimerList[i].Timeout;//重新设置超时计数值
                }
                TimerList[i].Timeoutfuc(TimerList[i].Parameter); //执行回调函数
            }
        }
    }

}





void BaseTime_Init(void)
{

        BASE_TIM_NVIC_Config();
        BaseTime_Config();
}
/***********************************************BaseTime.c end********************************************************************************************/



/***********************************************BaseTime.h************************************************************************************************/


#ifndef __BSP_BASETIME_H
#define __BSP_BASETIME_H

#include "stm32f10x.h"

#define            BASIC_TIM_IRQ               TIM6_IRQn
#define            BASIC_TIM_IRQHandler        TIM6_IRQHandler


#define TIMER_ONESHOT 0 //单次定时
#define TIMER_PERIOD 1 //周期定时


typedef struct __TIMER
{
    u32 Timeoutcnt; //超时计数值
    u32 Timeout; //超时重装值
    void (*Timeoutfuc)(void* parameter); //超时回调函数
    void* Parameter; //回调传递的参数
    u8 Timerflag; //超时方式
}Timer_typedef;








void BaseTime_Init(void);

void SoftTimer_TimerStart(u8 TimerIdent, u32 TimeOut, void (*Timeoutfuc)(void* parameter), void* parameter, u8 flag);

void SoftTimer_TimerReset(u8 TimerIdent);

void SoftTimer_TimerRestart(u8 TimerIdent, u32 TimeOut);

void SoftTimer_TimerStop(u8 TimerIdent);

void SoftTimer_Execute(void);

#endif    /*__BSP_BASETIME_H*/
/**************************************BaseTime.h end***************************************************************************/

/************************************BASIC_TIM_IRQHandler****************************************/

void BASIC_TIM_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM6,TIM_IT_Update)!= RESET)
    {

        SoftTimer_Execute();



        TIM_ClearITPendingBit(TIM6,TIM_FLAG_Update);
    }
}

/************************************BASIC_TIM_IRQHandler end****************************************/
/*************************************int main(void)**************************************************/

/*软定时器0超时回调函数*/
void SoftTimer0Callback(void *parameter)
{
    printf("%s\r\n", (char *)parameter);
    LED1_TOGGLE;
}

/*软定时器1超时回调函数*/
void SoftTimer1Callback(void *parameter)
{
    LED2_TOGGLE;
    printf("%s\r\n", (char *)parameter);
}

int main(void)
{

        
        LED_GPIO_Config();
        USART_CONFIG();
        BaseTime_Init();

        while(1)
        {

                SoftTimer_TimerStart(0, 2000, SoftTimer0Callback, (void*)"SoftTimer0 timeout", TIMER_ONESHOT);//打开软定
                SoftTimer_TimerStart(1, 1000, SoftTimer1Callback, (void*)"SoftTimer1 timeout", TIMER_PERIOD);//打开软定   
                delay(1000);
                delay(1000);
                delay(1000);
                SoftTimer_TimerStop(1);//关闭软定时器1
                printf("SoftTimer stop!\r\n");
                delay(1000);
                delay(1000);
                delay(1000);
                SoftTimer_TimerRestart(1, 500);//软定时器1重启,设置新的定时时间
                printf("SoftTimer restart, timeout:500ms!\r\n");
                delay(1000);
                delay(1000);
                delay(1000);
                SoftTimer_TimerReset(1); //软定时器1复位
                printf("SoftTimer reset!\r\n");

        }
}

/***********************************main end**********************************************************/


回复

使用道具 举报

5

主题

23

回帖

38

积分

新手上路

积分
38
 楼主| 发表于 2019-8-29 16:07:14 | 显示全部楼层
SoftTimer_TimerStart 貌似没运行,不知道为啥?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107046
QQ
发表于 2019-8-29 16:15:10 | 显示全部楼层
使用我们的bsp_timer.C即可
回复

使用道具 举报

5

主题

23

回帖

38

积分

新手上路

积分
38
 楼主| 发表于 2019-8-29 16:20:27 | 显示全部楼层
在哪里啊,没找到地址
回复

使用道具 举报

5

主题

23

回帖

38

积分

新手上路

积分
38
 楼主| 发表于 2019-8-29 16:22:06 | 显示全部楼层
eric2013 发表于 2019-8-29 16:15
使用我们的bsp_timer.C即可

在哪里?没找到地址呢
回复

使用道具 举报

36

主题

1445

回帖

1553

积分

至尊会员

积分
1553
发表于 2019-8-30 00:01:30 | 显示全部楼层
ZSR20181017 发表于 2019-8-29 16:22
在哪里?没找到地址呢

下载例程,例程里面的bsp软件包里有
回复

使用道具 举报

2

主题

569

回帖

575

积分

金牌会员

积分
575
发表于 2019-8-30 00:15:11 | 显示全部楼层
楼主C语言水平还有待提高,软定时器网上很多,
重复造轮子没什么意思,给两个例子给你参考
https://github.com/0x1abin/MultiTimer
https://github.com/lmooml/SmartTimer
回复

使用道具 举报

73

主题

1200

回帖

1419

积分

至尊会员

积分
1419
发表于 2020-6-6 12:22:31
leiyitan 发表于 2019-8-30 00:15
楼主C语言水平还有待提高,软定时器网上很多,
重复造轮子没什么意思,给两个例子给你参考
https://githu ...

不错的

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-15 10:44 , Processed in 0.248050 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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