最近弄得一个小模块,出现这么个情况(在最高优先级任务中):一个设备上电保持:OSTimeDly(500),没有动作。然而for(u16 i=0;i<50000;i++);(大概4--5ms),完成动作,也就是我要的效果。
实测,如果将代码放到其他的用户任务中(相对来说算是低优先级任务),一切安好.....
模块图:这东西控制电流方向可做活塞运动,,,
环境:IAR+cortex-M3+ucos
其中:
1ms进入一次sysTick异常处理程序:#define OS_TICKS_PER_SEC 1000 /* Set the number of ticks in one second */--
内核时钟频率64MHz:
使用内部高速晶振HSI 提供时钟源动力:
- RCC_HSICmd(ENABLE); //使能内部高速晶振
while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY)== RESET);//等待HSI就绪
- RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);/*设置PLL时钟源及倍频系数,频率为8/2*16=64Mhz*/
也就是说:OSTimeDly(500)---时机等待500ms
下边上测试代码:
app.c:
/*通信..交互*/
static void App_Task_Agreement(void *p_arg)
{
while(1)
{
drawerStateCtr(DRV_Unlock,0);//给设备0上电并保持x时间
if(FRAME_OK()){
HandleCommand();
}
//test();
OSTimeDly(10);
}
}
设备驱动 opticalcoupler.c:
莫名其妙没效果的写法:
/*
功能:锁定和解锁指定的电磁铁
参数:
state:DRV_Lock/DRV_Unlock 锁定/解锁
num:磁铁驱动编号
*/
//u32 DRV_Lock =0x01;
//u32 DRV_Unlock =0x02;
void drawerStateCtr(u32 state,u8 num) //num:0--5 01
{
//num=num-UnknownChange;//当UnknownChange=0,样品抽拉条编号[0--5]; UnknownChange=1,则编号[1--6]
u32 tmpVal = 0;
bitsClear(num); //清除相应位
tmpVal = ~(0xfffffffc | state);//
state <<= (num*2);
tmpVal <<= (num*2+12);
drawerLock_UnlockState |= (tmpVal | state);
<span style="background-color: lime;"> OC_DCT_DRV(drawerLock_UnlockState);//写控制,理解成给设备上电就好</span>
u32 cur1=OSTimeGet();
<span style="background-color: red;"> OSTimeDly(500);//for(u16 i=0;i<50000;i++);//OSTimeDly(500);</span>
u32 cur2=OSTimeGet();
u32 diff= cur2-cur1; //<span style="background-color: red;">测试</span><span style="background-color: rgb(255, 0, 0);">OSTimeDly(500);的具体时间:结果确实是500ms</span>
bitsClear(num); //完成动作后,清除位置 防止持续供电发热
}
drawerStateCtr函数中使用OSTimeDly延时等待,情况便是:叫电磁铁往上--不动,往下--不动。
感觉就像没收到OC_DCT_DRV指令一样,因为打上断点OSTimeDly,效果ok;当然咱说OSTimeDly没起作用,也挺像。
效果正常的代码:
void drawerStateCtr(u32 state,u8 num) //num:0--5 01
{
//num=num-UnknownChange;//当UnknownChange=0,样品抽拉条编号[0--5]; UnknownChange=1,则编号[1--6]
u32 tmpVal = 0;
bitsClear(num); //清除相应位
tmpVal = ~(0xfffffffc | state);//
state <<= (num*2);
tmpVal <<= (num*2+12);
drawerLock_UnlockState |= (tmpVal | state);
OC_DCT_DRV(drawerLock_UnlockState);
u32 cur1=OSTimeGet();
<span style="background-color: lime;"> for(u16 i=0;i<50000;i++);</span>//OSTimeDly(500);<span style="background-color: lime;">//看着反汇编代码,应该4--5ms的等待时间,效果正常</span>
u32 cur2=OSTimeGet();
u32 diff= cur2-cur1;
bitsClear(num); //完成动作后,清除位置 防止持续供电发热
}
效果正常。
问题:
- 出现上边这状况的原因?
- 在写驱动程序时,是否应该脱离操作系统?(不使用操作系统的的资源,如OSTimeDly)
- 在写ad驱动程序时,不可避免的要while(),如:
void Set_Ads1256_Reset(void)
{
Write_SPI_One_Byte(ADS1256_RESET);//Reset to Power-Up Values
while (GPIO_ReadInputDataBit(GPIOB,ADDRDY));//DRDY信号为高 开始自校验,为低表示自校验完成
}
有一天ad烧了或是咋啦滴,咋办?大伙是怎么处理这类条件等待的?
先这些问题,,,大伙帮忙分析下,谢啦。
|