N32L406的无外部晶体USB问题
再开发USBMCS设备的时候,测试出一个问题,在使用N32L406的无外部晶体模式的时候,如果MCU进入STOP2模式,那么退出休眠再次同电脑进行通讯的话,MSC在此电脑上面的表现可能只有一个U盘,根本无法点进去,这个地方可能是由于使用了UCDR模块导致的,而且UCDR模块也无法关闭,请问一下有没有解决方案。贴代码
这个是进入休眠的代码,进入STOP2要旁路UCDR,不然休眠好像会卡住,然后用了一个脚做了检测USB拔插的脚退出休眠的时候检测是否上电,上电的话就会延时1s,稳定USB时钟
这边是USB的初始化过程,这个DP的上下拉是参考了PC的通讯流程,要复位USB,得下拉DP10ms,如果这里不下拉,那么USB无法正常初始化 可能只有一个U盘还是确定只有? zyf部长 发表于 2023-8-27 12:00
可能只有一个U盘还是确定只有?
这个问题已经解决了,用HSI-PLL供一个48M给USB,就解决了,是由UCDR休眠重启导致时钟不准确导致的 void Adj_HSI_Value(void)
{
int32_t hsi_opt;
int32_t hsi_trim;
int8_t hsi_opt_temp;
int8_t hsi_trim_temp;
int8_t temp;
uint32_t time_out = 0xFFFFF;
RCC_ConfigLse(RCC_LSE_ENABLE,0x28);
while (RCC_GetFlagStatus(RCC_LDCTRL_FLAG_LSERD) == RESET)
{
}
/* Enable Clock Security System(CSS): this will generate an NMI exception
when HSE clock fails */
TIM9_ConfigForLSE();
RCC_EnableClockSecuritySystem(ENABLE);
#if 0 //使用 PA8调试查看波形
/*调试时先用该函数把频率调偏,然后用下面的函数自动调回来*/
AFEC_ConfigHSITrim(AFEC_HSI_OPT_NUM5,AFEC_HSI_TRIM_NUM0);
/* Output HSE clock on MCO pin
* ---------------------------------------------*/
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
GPIO_InitType GPIO_InitStructure;
GPIO_InitStruct(&GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Alternate= GPIO_AF8_MCO;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
RCC_ConfigMcoClkPre(RCC_MCO_CLK_NUM0);
RCC_ConfigMco(RCC_MCO_HSI);
#endif
//等待中断完成
while((adj_flag == 0) && (time_out != 0))
{
time_out--; //超时
}
if(time_out != 0)
{
//afec_hsi_opt位粗调 HSI 频率,步长约为 700kHz,afec_hsi_trim细调 HSI 频率,步长约为40kHz。
//(TIM工作频率 -计算频率)*2得到 16M主频差值
hsi_opt_temp = ((int32_t)16000000 - Capture/ 0.0029296875) / 1000 / 700;
hsi_trim_temp = (((int32_t)16000000- Capture/ 0.0029296875) / 1000 - 700 * hsi_opt_temp) / 40;
AFEC_GetHSITrim(&hsi_opt, &hsi_trim);
if(hsi_trim_temp > 0)
{
hsi_trim += hsi_trim_temp;
if(hsi_trim > 31)//如果调整增加超过细调范围,增加粗调一次700K
{
temp = hsi_trim / 17; // 700/40 = 17.5
hsi_opt_temp += temp;
hsi_trim = hsi_trim - 17*temp;
}
}
if(hsi_trim_temp < 0)
{
if(hsi_trim + hsi_trim_temp < 0)//如果小于0则向粗调借位
{
temp = hsi_trim_temp / 17; // 700/40 = 17.5
hsi_opt_temp += temp;
hsi_trim_temp = hsi_trim_temp - 17*temp;//temp为负数
if(hsi_trim + hsi_trim_temp < 0)//如果小于0则向粗调借位
{
temp = - 1; // 700/40 = 17.5
hsi_opt_temp += temp;
hsi_trim_temp = hsi_trim_temp - 17*temp;//temp为负数
}
}
hsi_trim += hsi_trim_temp; //最后为正数
}
hsi_opt += hsi_opt_temp;
hsi_opt &= 0xF;
hsi_trim &= 0x1F;
AFEC_ConfigHSITrim(hsi_opt << 21, hsi_trim << 16);
}
TIM9_Deinit();
}
这个是找的国民官方技术,他们帮忙用外部LSE校准了HSI,感谢
页:
[1]