背景:最近做原子哥的USB例程的时候都会发现用到这个函数,目的是复位后也可以检测到设备。但我发现模拟鼠标这个源码下载到板子后99%不会枚举成功,但USB大容量存储又可以。
现况:我根据八度空间大大的DFU例程自己建了一个工程,只要引用void usb_port_set(u8 enable)这个函数,程序就会跑的特别慢,近乎死机,并且不会枚举成功(因为程序跑太慢达不到协议要求)。但删除后就能正常运行,并且枚举成功。
猜想:可能是这个函数不够完善,在关闭USB模块后,重启USB模块前,PA11,PA12只做了“软断电”处理,没有进行复位,导致在打开USB模块后系统出现异常。
修改:我在打开USB模块前将PA11 PA12进行复位。具体修改如下。
原函数:
[mw_shl_code=c,true]void usb_port_set(u8 enable)
{
RCC->APB2ENR|=1<<2; //????PORTA?±??
if(enable)_SetCNTR(_GetCNTR()&(~(1<<1)));//????????????
else
{
_SetCNTR(_GetCNTR()|(1<<1)); // ????????
GPIOA->CRH&=0XFFF00FFF;
GPIOA->CRH|=0X00033000;
PAout(12)=0;
}
}
[/mw_shl_code]
修改后:
[mw_shl_code=c,true]void usb_port_set(u8 enable)
{
RCC->APB2ENR|=1<<2; //????PORTA?±??
if(enable)
{
GPIOA->CRH&=0XFFF00FFF;
GPIOA->CRH|=0X00044000;
_SetCNTR(_GetCNTR()&(~(1<<1)));//????????????
}
else
{
_SetCNTR(_GetCNTR()|(1<<1)); // ????????
GPIOA->CRH&=0XFFF00FFF;
GPIOA->CRH|=0X00033000;
PAout(12)=0;
}
}
[/mw_shl_code]
结果:经过修改,原子哥的模拟鼠标例程百分百枚举成功。自己的程序也能正常运行。 |