因为一个很多的程序中会多次使用系统延迟函数,最后会导致时间的不准确,所以我想到了用定时器中断来计算时间,并且把定时器中断函数做成任务函数,在达到了我想要的定时时间,就发生一次中断,并把这个时间点用邮箱发送出去。但是如果不发送邮箱,那么通过示波器可以抓到准确的时间,但是一旦把
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)**************************/ |