打印

关于定时器中断函数做成任务函数来替换平时使用的系统延迟函数

[复制链接]
640|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
社畜一枚|  楼主 | 2018-7-5 18:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
因为一个很多的程序中会多次使用系统延迟函数,最后会导致时间的不准确,所以我想到了用定时器中断来计算时间,并且把定时器中断函数做成任务函数,在达到了我想要的定时时间,就发生一次中断,并把这个时间点用邮箱发送出去。但是如果不发送邮箱,那么通过示波器可以抓到准确的时间,但是一旦把
mptr->bFlag1ms=1; //发送1ms的邮件,     这句话加上,就不会出现时间。
下面是我的.C文件:
#include "osObjects.h"  // RTOS object definitions
#include "stm32f30x_gpio.h"
#include "timer_interrupt.h"

int8_t Flage ;  //计算时间ms次数
osThreadId tid_cyclemissionTask;

void TIMX_Init(int arr, int psc)    //初始化定时器
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //时钟结构体初始化
        NVIC_InitTypeDef NVIC_InitStruct;                           //中断结构体初始化
        GPIO_InitTypeDef  GPIO_InitStructure;              //GPIO口结构体初始化
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);         //使能PC端口时钟

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开定时器2时钟
        
    TIM_TimeBaseStructure.TIM_Period=arr;//计数周期
    TIM_TimeBaseStructure.TIM_Prescaler=psc;//分频系数
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1=0,也就是时钟分频因子为0
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式为向上计数
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);    //初始化TIM2
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                                 //PC.0 端口配置
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                                //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
        GPIO_Init(GPIOC, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOC.0
        GPIO_SetBits(GPIOC,GPIO_Pin_0);                                                 //PC.0 输出高        

        
        TIM_ARRPreloadConfig(TIM2, ENABLE);
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE );  //允许中断溢出 设置TIM2IT中断为有效中断
        
        TIM_Cmd(TIM2,ENABLE);//使能TIM2
        
        NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;     //设置中断通道为TIM2_IRQn
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;   //抢占优先级1
        NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;       //相应优先级2
        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;  //IRQ通道被使能
        NVIC_Init(&NVIC_InitStruct);    //使能TIMX外设
}


void TIM2_IRQHandler(void)     //定时器2中断服务程序
{
        T_CYCLE_MISSION  *mptr;//定义一个指向该结构体的指针
        mptr = osMailAlloc(mailCycleMission, 0);  //邮件队列中分配内存块        
        if(TIM_GetITStatus(TIM2, TIM_IT_Update))//如果TIM2中断标志位触发,也就是超时溢出           TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)  
        {
                TIM_ClearITPendingBit(TIM2,TIM_IT_Update);  //首先清除标志位
                Flage++;
                if(Flage%2 == 0){
                        GPIO_SetBits(GPIOC,GPIO_Pin_0);        
                        Flage =0;
                        //mptr->bFlag1ms=1;     //发送1ms的邮件
                }
                else{
                        GPIO_ResetBits(GPIOC,GPIO_Pin_0);        
                        //mptr->bFlag1ms=0;   
                }
                //osMailPut(mailCycleMission, mptr); //发送邮箱        
        }
}

void cyclemissionTask (void const *argument)
{
        while(1)
        {        
        
        }

}

void cyclemissionTaskCreate(void)
{
        tid_cyclemissionTask = osThreadCreate(osThread(cyclemissionTask), NULL);
}


一下是我的osObjects.h      
#ifdef osObjectsPublic
#define OS_EXTERN
#else
#define OS_EXTERN extern
#endif


typedef struct {                                 // Mail object structure
        uint8_t    bFlag1ms;
        uint8_t    bFlag10ms;
        uint8_t    bFlag50ms;
        uint8_t    bFlag1s;
} T_CYCLE_MISSION;                    //定义定时器周期的数据类型

OS_EXTERN osMailQId  mailCycleMission;                //周期任务的邮件ID定义

osMailQDef(mailCycleMission, 8, T_CYCLE_MISSION);       // 定时器周期邮件定义

osThreadDef(cyclemissionTask, osPriorityNormal, 1, 0);



最后是我的主函数
int main (void)
{
  //osKernelInitialize ();                    // initialize CMSIS-RTOS
        V_NVIC_Configuration();
        V_UsartInit();
        TIMX_Init(9999,7199);   //T=(arr+1)*(psc+1)/系统时钟频率   50MS
        //cyclemissionTaskCreate();


// osKernelStart ();                         // start thread execution
}
/**************************main(void)**************************/

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

397

主题

401

帖子

0

粉丝