|
我存在两个任务,一个任务是用来进入stop,另一个任务是测试唤醒次数(任务自己挂起自己,由串口接收到数据恢复)
具体设计思路是这样子,PA10作为停机模式的唤醒管脚,串口第一个字符串是用来唤醒STOP模式,唤醒之后就作为串口的接收,串口接收到数据就恢复挂起的task2;
具体代码,如下:
//task1任务函数
void task1_task(void *p_arg)
{
u8 task1_num=0;
OS_ERR err;
OS_TICK CurTick=0;
OS_TICK DelayTick=0;
u32 delay;
CPU_SR_ALLOC();
p_arg = p_arg;
intostop=1;
while(1)
{
if(intostop)
{
CurTick=OSTimeGet(&err);
printf("Cur Tick :%d\r\n",CurTick);
// CPU_CRITICAL_ENTER();
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//开启中断
Usart_IRQ_Set(1);
// CPU_CRITICAL_EXIT();
USART_Cmd(USART1, DISABLE);
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; /* 关闭滴答定时器 */
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
Usart_IRQ_Set(0);
delay=1000; //5000 -1000
while(delay)
{
delay--;
}
CPU_CRITICAL_ENTER();
intostop=0;
SystemInit();
delay=1000; //5000 -1000
while(delay)
{
delay--;
}
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* 使能滴答定时器 */
//屏蔽Line 10中断
USART_Cmd(USART1, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
DelayTick=GetMinDelaytime();
printf("Delay Tick :%d\r\n",DelayTick);
if(CurTick+10<DelayTick)
{
OSTimeSet(CurTick+10,&err);
}
else
{
OSTimeSet(DelayTick-1,&err);
}
CPU_CRITICAL_EXIT();
OSTaskSuspend((OS_TCB*)&Task1_TaskTCB,&err);//任务1执行5次后挂起任务2
}
OSTimeDlyHMSM(0,0,0,1,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
// OSTaskResume((OS_TCB*)&Task2_TaskTCB,&err); //任务1运行10次后恢复任务2
}
}
//task2任务函数
void task2_task(void *p_arg)
{
u32 task2_num=0;
OS_ERR err;
CPU_SR_ALLOC();
p_arg = p_arg;
while(1)
{
task2_num++;
// OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
intostop=1;
// USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//开启中断
Usart_IRQ_Set(1);
OSTaskSuspend((OS_TCB*)&Task2_TaskTCB,&err);//任务1执行5次后挂起任务2
OSTaskResume((OS_TCB*)&Task1_TaskTCB,&err); //任务1运行10次后恢复任务2
CPU_CRITICAL_ENTER();
printf("唤醒任务次数:%d次\r\n",task2_num);
CPU_CRITICAL_EXIT();
}
}
void EXTI15_10_IRQHandler(void) //串口中断唤醒服务函数
{
EXTI_ClearITPendingBit(EXTI_Line10); //清除EXTI0线路挂起位
OSIntEnter();
// USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
OSIntExit();
}
void Usart_IRQ_Set(u8 en)
{
EXTI->R=1<<10; //清除LINE11上的中断标志位
if(en)EXTI->IMR|=1<<10;//不屏蔽line11上的中断
else EXTI->IMR&=~(1<<10);//屏蔽line11上的中断
}
void USART1_IRQHandler(void) //串口1中断服务程序
{
OS_ERR err;
u8 Res;
OSIntEnter();
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
OSTaskResume((OS_TCB*)&Task2_TaskTCB,&err); //任务1运行10次后恢复任务2
}
OSIntExit();
}
我本想串口唤醒一次task2后,我就把相应的接收中断给关掉,USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//开启中断,但是,跑十来次就挂了,屏蔽就可以。然后我开启Line10中断来实现屏蔽串口接收中断,这样子就可以。
汉子哥,能否帮忙看一下,搞一天了。谢谢 |
|