OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4412|回复: 3

为什么定时器中断事件无法触发ucosii任务运行

[复制链接]

20

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
186
金钱
186
注册时间
2015-1-22
在线时间
57 小时
发表于 2021-10-7 15:26:20 | 显示全部楼层 |阅读模式
10金钱
定时器3产生5S一次的中断,仿真中每次都能跳进中断,添加打印在中断里也能输出打印。但为什么中断里的全局变量标志位无法传到任务里去执行。采用信号量任务内只能执行一次。工程是在原子哥的实验35上添加的,请各位高手不吝赐教。
//**************************定时器3************************************
u8 SysBeat = 0;//系统心跳包标志位

void TIM3_Init(u16 arr, u16 psc)    //50000   7200产生5S定时
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;   //定义定时器结构体变量
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);   //使能TIM3的时钟
       
        TIM_TimeBaseInitStructure.TIM_Period=arr-1;                                   //设置自动重装载的周期值
        TIM_TimeBaseInitStructure.TIM_Prescaler=psc-1;                   //设置预分频值
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;                   //设置时钟分割
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;   //向上计数模式
        TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);   //定时器初始化函数
       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
       
        NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;   //TIM3中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;   //抢占优先级0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;   //子优先级1
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;   //使能TIM4中断通道
        NVIC_Init(&NVIC_InitStructure);   //中断优先级初始化函数
       
        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);   //TIM3中断使能
       
        TIM_Cmd(TIM3,ENABLE);   //TIM3使能
}

//定时器3中断
void TIM3_IRQHandler(void)   //TIM4中断服务函数
{
        static u8 n = 0;
        if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)        //判断是否进入TIM更新中断
        {       
                n++;
                if(n >= 2)
                {
                        n = 0;
                        SysBeat = 1;         //每10S产生一个系统心跳标志位
                }
        }
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);        //清除TIM4更新中断
}



/////////////////////////UCOSII任务设置///////////////////////////////////
//START 任务
//设置任务优先级
#define START_TASK_PRIO                              10 //开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE                                  64
//任务堆栈       
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *pdata);       
                          
//LED0任务
//设置任务优先级
#define LED0_TASK_PRIO                               7  
//设置任务堆栈大小
#define LED0_STK_SIZE                                      64
//任务堆栈       
OS_STK LED0_TASK_STK[LED0_STK_SIZE];
//任务函数
void led0_task(void *pdata);


//LED1任务
//设置任务优先级
#define LED1_TASK_PRIO                               6
//设置任务堆栈大小
#define LED1_STK_SIZE                                          64
//任务堆栈
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
//任务函数
void led1_task(void *pdata);


int main(void)
{       
        delay_init();                     //延时函数初始化       
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
        usart2_init(9600);                                //串口1初始化
        TIM3_Init(50000,7200);                                                        //系统时基初始化
        Encoder_Init();

        OSInit();   
        OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
        OSStart();       
}

          
//开始任务
void start_task(void *pdata)
{
    OS_CPU_SR cpu_sr=0;
        pdata = pdata;
          OS_ENTER_CRITICAL();                        //进入临界区(无法被中断打断)   
        OSTaskCreate(led0_task,(void *)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);                                                  
        OSTaskCreate(led1_task,(void *)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);                                           
        OSTaskSuspend(START_TASK_PRIO);        //挂起起始任务.
        OS_EXIT_CRITICAL();                                //退出临界区(可以被中断打断)
}

//LED0任务
void led0_task(void *pdata)
{                
        while(1)
        {
                if(SysBeat)                                   //定时器3产生的sysbeat标志位无法跳转到这里
                {
                        SysBeat = 0;
                        u2_printf("System running…\r\n");
                }
        };
}

//LED1任务
void led1_task(void *pdata)
{          
        while(1)
        {
        };
}


最佳答案

查看完整内容[请看2#楼]

任务里加延时啊。而且这种标志位适合裸跑的时候用。 rtos这种建议常用任务通知或者任务事件去代替标志位。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

117

帖子

0

精华

高级会员

Rank: 4

积分
559
金钱
559
注册时间
2018-10-3
在线时间
107 小时
发表于 2021-10-7 15:26:21 | 显示全部楼层
任务里加延时啊。而且这种标志位适合裸跑的时候用。 rtos这种建议常用任务通知或者任务事件去代替标志位。
回复

使用道具 举报

7

主题

480

帖子

0

精华

高级会员

Rank: 4

积分
783
金钱
783
注册时间
2021-4-15
在线时间
305 小时
发表于 2021-10-7 16:01:53 | 显示全部楼层
任务里面都不加一个 调度延时一下?就那样空跑?
日常敲键--头秃一片
回复

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2020-6-24
在线时间
10 小时
发表于 2021-10-8 10:15:52 | 显示全部楼层
日渐秃兀 发表于 2021-10-7 16:01
任务里面都不加一个 调度延时一下?就那样空跑?

回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 04:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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