看文档上面介绍IWDG使用的内部低速时钟LSI,大约40K,可是当我配置IWDG预分频为32,装载值位2500(40K/16),也就是2秒钟不喂狗重启,但我测试下来结果却是10秒钟不喂狗才重启。这是为何,40K的LSI不可能误差这么多吧?IWDG配置如下:IWDG_SetPrescaler(IWDG_Prescaler_32); IWDG_SetReload(40000 / 16); 另外我测试了下RTC也使用内部的40K LSI,来实现秒中断,测试下来1分钟触发58次,也就是说LSI的误差在1/30左右。 看到有关文档上结束如下: 看门狗超时时间(40kHz的输入时钟(LSI))(1)
“这些时间是按照40kHz时钟给出。实际上, MCU内部的RC频率会在30kHz到60kHz之间变化。 此外,即使RC振荡器的频率是精确的,确切的时序仍然依赖于APB接口时钟与RC振荡器时钟 之间的相位差,因此总会有一个完整的RC周期是不确定的。” APB接口时钟与RC振荡器时钟之间的相位差,请问会对IWDG的时钟产生这么大的影响吗?有没有大神知道的? |
【MCU实战经验】基于STM32F103C8T6的hart总线调试器设计
求教STM32F103进入STOP模式后用外部中断唤醒的问题
基于STM32F103RCT6的无源蜂鸣器音乐播放(生日快乐歌)
STM32F103c8t6有没有DAC 功能?
STM32F103x中文数据手册
新手求教,为何在我电脑上找不到STM32F1Xx.h文件
金龙107例程汇总(STM32F107)
万利STM32F107VC 原理图
STM32F103 ADC多通道检测必须要DMA吗?
【官方例程】STM32F107以太网官方例程
或者说配置写进去没有?
初始化步骤如下:
void IWDG_Init(void)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(IWDG_Prescaler_32);
IWDG_SetReload(CLK_LSI / 16);
IWDG_ReloadCounter();
IWDG_Enable();
}
然后通过串口打印会读的寄存器值PR RLR SR_PVU SR_RVU如下:
PR[6], RLR[2500], PVU[0], RVU[0]
预分频寄存器PR的值却是默认的256分频!!!
于是做了如下处理:
void IWDG_Init(void)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
while(IWDG_GetFlagStatus(IWDG_FLAG_PVU));
IWDG_SetPrescaler(IWDG_Prescaler_32);
while(IWDG_GetFlagStatus(IWDG_FLAG_RVU));
IWDG_SetReload(CLK_LSI / 16);
IWDG_ReloadCounter();
IWDG_Enable();
}
实验测试,却是陷入上面的死循环,MCU起不来了。于是继续测试:
uint16 ptimeout;
uint16 rtimeout;
void IWDG_Init(void)
{
ptimeout = 0;
rtimeout = 0;
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
while(IWDG_GetFlagStatus(IWDG_FLAG_PVU))
{
ptimeout ++;
if (ptimeout >= 500)
{
break;
}
}
IWDG_SetPrescaler(IWDG_Prescaler_32);
while(IWDG_GetFlagStatus(IWDG_FLAG_RVU))
{
rtimeout ++;
if (rtimeout >= 500)
{
break;
}
}
IWDG_SetReload(CLK_LSI / 16);
IWDG_ReloadCounter();
IWDG_Enable();
}
初始化后打印的结果如下:
PR[6], RLR[2500], PVU[0], RVU[0], ptimeout[500], rtimeout[0]
原来是硬件上一直没有将SR_PVU清0.。。。
无奈在上点开机几秒钟之后,再次手动初始化IWDG,此时再查下寄存器终于好了:
PR[3], RLR[2500], PVU[0], RVU[0], ptimeout[0], rtimeout[0]
那么问题又来了,为什么刚开机初始化时,SR_PVU一直不清0呢,有没有大神遇到过这种情况呀?
好像只要这样就可以的