usb_pwr.c这个文件看文件名就知道跟功耗有关了,有很多的状态:上电、掉电、挂起、规复。
当起首是usb的上电和断电函数的界说了。
usb上电函数如下:
/*******************************************************************************
*FunctionName:PowerOn
*Deion:上电
*Input:None.
*Output:None.
*Return:USB_SUCCESS.
*******************************************************************************/
RESULTPowerOn(void)
{
u16wRegVal;
USB_Cable_Config(ENABLE);//接上上拉电阻
wRegVal=CNTR_FRES;//设置逼迫复位
_SetCNTR(wRegVal);
wInterrupt_Mask=0;//先克制全部的停止
_SetCNTR(wInterrupt_Mask);
_SetISTR(0);//打扫全部的停止标记
wInterrupt_Mask=CNTR_RESETM|CNTR_SUSPM|CNTR_WKUPM;
_SetCNTR(wInterrupt_Mask);//再打开复位停止、挂起停止、唤醒停止屏蔽位
returnUSB_SUCCESS;
}
上电的过程是:
1、固然接上D+或D-的上啦电阻,让主机可以辨认到USB;
2、设置USB控制寄存器CNTR,是USB逼迫复位
3、打开复位停止、挂起停止、唤醒停止,其他停止屏蔽位则关闭
接下去是断电的函数界说:
/*******************************************************************************
*FunctionName:PowerOff
*Deion:掉电
*Input:None.
*Output:None.
*Return:USB_SUCCESS.
*******************************************************************************/
RESULTPowerOff()
{
/*disableallintsandforceUSBreset*/
_SetCNTR(CNTR_FRES);//设置逼迫复位
_SetISTR(0);//打扫全部的停止标记
USB_Cable_Config(DISABLE);//断开上拉电阻
_SetCNTR(CNTR_FRES+CNTR_PDWN);//设置逼迫复位,而且进入断电模式
returnUSB_SUCCESS;
}
掉电的过程很简单,先逼迫复位USB,并打扫全部的停止标记,断开上拉电阻,并设置控制进入断电模式。
挂起也是USB的一种状态,所谓的挂起起始就是进入低功耗状态,一样平常的事变我不相应,除非有紧张的事变我才唤醒处理惩罚。
/*******************************************************************************
*FunctionName:Suspend
*Deion:挂起
*Input:None.
*Output:None.
*Return:USB_SUCCESS.
*******************************************************************************/
voidSuspend(void)
{
u16wCNTR;
wCNTR=_GetCNTR();//读取控制寄存器的值
wCNTR|=CNTR_FSUSP;//添加强制挂起标记
_SetCNTR(wCNTR);//进入挂起模式
wCNTR=_GetCNTR();//读取控制寄存器的值
wCNTR|=CNTR_LPMODE;//添加低功耗标记
_SetCNTR(wCNTR);//进入低功耗模式
Enter_LowPowerMode();//进入低功耗模式
}
进入挂起状态的过程跟我们平常进入停止服务函数的过程很像,固然要掩护现场了。以是usb进入挂起状态,不改变控制寄存器原来的值,只是在原来的上面添加了挂起状态和低功耗状态标记而已。
说到挂起,固然有规复了。起首的讲Resume_Init()这个函数:
/*******************************************************************************
*FunctionName:Resume_Init
*Deion:处理惩罚唤醒规复的函数
*Input:None.
*Output:None.
*Return:USB_SUCCESS.
*******************************************************************************/
voidResume_Init(void)
{
u16wCNTR;
wCNTR=_GetCNTR();
wCNTR=(~CNTR_LPMODE);
_SetCNTR(wCNTR);//进入非低功耗模式
Leave_LowPowerMode();//离开低功耗模式
_SetCNTR(IMR_MSK);//打开使能全部停止
}
这个就是唤醒的函数了,比力简单,但是比力难懂白的是规复的各个状态。
typedefenum_RESUME_STATE
{
RESUME_EXTERNAL,
RESUME_INTERNAL,
RESUME_LATER,
RESUME_WAIT,
RESUME_START,
RESUME_ON,
RESUME_OFF,
RESUME_ESOF
}RESUME_STATE;
规复有这么多的状态变革,固然有来由明白下各个状态了。
RESUME_EXTERNAL:个人明白,就想硬件复位一样,是通过某个物理硬件唤醒USB的
RESUME_INTERNAL:这个状态的唤醒应该就是软件唤醒之类的,比如收到某个停止
RESUME_LATER:表现待会儿唤醒,固然这里涉及到一个定时过程,定时时间到了在开始规复
RESUME_WAIT:这个状态表现正在等待定时过程的竣事
RESUME_START:表现USB开始要举行规复了
RESUME_ON:表现即将规复,该状态保持1毫秒~15ms内有效,主机就会对USB模块举行唤醒操纵
RESUME_OFF:表现已经规复完成了
RESUME_ESOF:个人理崩溃现,收到ESOF停止标记时,USB不答应进入挂起状态
各个状态之间的转化如下代码:
/*******************************************************************************
*FunctionName:Resume
*Deion:这是状态机处理惩罚规复操纵和时序。控制是基于Resume布局变量和
*ESOF停止调用该子程序没有改变机状态。控制规复的状态
*Input:astatemachinevalue(RESUME_STATE)
*RESUME_ESOFdoesn'tchangeResumeS.eStateallowing
*decrementingoftheESOFcounterindifferentstates.
*Output:None.
*Return:None.
*******************************************************************************/
voidResume(RESUME_STATEeResumeSetVal)
{
u16wCNTR;
if(eResumeSetVal!=RESUME_ESOF)//假如不是ESOF停止导致的
ResumeS.eState=eResumeSetVal;//ResumeS.eState设置为本身设定的值
switch(ResumeS.eState)
{
caseRESUME_EXTERNAL://RESUME_EXTERNAL外部规复
Resume_Init();
ResumeS.eState=RESUME_OFF;
break;
caseRESUME_INTERNAL://RESUME_INTERNAL内部规复
Resume_Init();
ResumeS.eState=RESUME_START;
break;
caseRESUME_LATER://RESUME_LATER定时规复
ResumeS.bESOFcnt=2;
ResumeS.eState=RESUME_WAIT;
break;
caseRESUME_WAIT://RESUME_WAIT等待计时竣事
ResumeS.bESOFcnt--;
if(ResumeS.bESOFcnt==0)
ResumeS.eState=RESUME_START;
break;
caseRESUME_START://RESUME_START开始规复
wCNTR=_GetCNTR();
wCNTR|=CNTR_RESUME;
_SetCNTR(wCNTR);//设置唤醒哀求位,将向PC主机发送唤醒哀求
ResumeS.eState=RESUME_ON;
ResumeS.bESOFcnt=10;//定时10ms,假如在这点时间内保持有效,主机将对USB模块举行唤醒操纵
break;
caseRESUME_ON://RESUME_ON
ResumeS.bESOFcnt--;//计时中
if(ResumeS.bESOFcnt==0)//计时时间到了
{
wCNTR=_GetCNTR();
wCNTR=(~CNTR_RESUME);//打扫唤醒哀求标记位
_SetCNTR(wCNTR);
ResumeS.eState=RESUME_OFF;
}
break;
caseRESUME_OFF://RESUME_OFF
caseRESUME_ESOF://RESUME_ESOF
default:
ResumeS.eState=RESUME_OFF;
break;
}
}
显着可以看到个状态的转化过程:
1、RESUME_EXTERNAL-RESUME_OFF
2、RESUME_INTERNAL-RESUME_START-RESUME_ON-RESUME_OFF
3、RESUME_WAIT-RESUME_START-RESUME_ON-RESUME_OFF
4、RESUME_ESOF-RESUME_OFF
原文链接:https://www.eeworld.com.cn/mcu/article_2016122032526.html
我要评论