初级会员

- 积分
- 186
- 金钱
- 186
- 注册时间
- 2015-1-22
- 在线时间
- 57 小时
|
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这种建议常用任务通知或者任务事件去代替标志位。
|