ldrsw指令(lds什么指令)

ldrsw指令(lds什么指令)p IWDG 工作原理 p p br p p nbsp 1 当键值寄存器 IWDG KR 中写入数值 0xCC 后 独立看门狗就会被启动 计数器开始从它的复位值 0xFF 开始递减计数 当计数减到 0x00 时就会产生一个复位信号 p p br p p nbsp 2 p

大家好,我是讯享网,很高兴认识大家。




讯享网

 <p>IWDG工作原理:<p><br/><p>&nbsp; 1、当键值寄存器(IWDG_KR)中写入数值0xCC后,独立看门狗就会被启动,计数器开始从它的复位值0xFF开始递减计数,当计数减到0x00时就会产生一个复位信号。<p><br/><p>&nbsp; 2、使用IWDG_PR和IWDG_RLR寄存器配独立看门狗。<p><br/><p>  (1)IWDG_PR寄存器是用于选择驱动计数器时钟的预分频系数。<p><br/><p>  (2)当KEY_REFRESH的数值(0xAA)写入到IWDG_KR寄存器时,独立看门狗将用IWDG_RLR的数值刷新计数器的内容,从而避免了产生看门狗的复位。<p><br/><p>&nbsp; 3、IWDG_PR和IWDG_RLR寄存器具有写保护功能,要修改它们前,需首先在IWDG_KR寄存器写入KEY_ACCESS代码(0x55);在IWDG_KR写入0xAA将恢复写保护状态。<p><br/><p>&nbsp;IWDG工作细节:<p><br/><p>1、为了避免程序忙跑跑死了没反应,加上一个看门狗watchdog实时监控着程序,一旦程序没有在规定的时间喂狗,则狗叫使得单片机复位。<p><br/><p>2、Independent watchdog(IWDG)内部有时钟源(128kHz),所以即使主时钟挂了watchdog还是能继续工作的。<p><br/><p>  &nbsp;另外还有个Window watchdog (WWDG),比IWDG复杂得多,我们没有采用。<p><br/><p><img src="https://6.eewimg.cn/news/uploadfile/2019/1107/68565.png" alt="" width="666" height="188"/><p>3、由于内部是128kHz,所以watchdog能允许的最大延迟时间为510ms(当RL[7:0]= 0xFF时),最小延迟时间为2ms(当RL[7:0]= 0x00时);我们选取510ms。<p><img src="https://6.eewimg.cn/news/uploadfile/2019/1107/64914.png" alt="" width="626" height="279"/><p>  也就是说一旦打开看门狗,最迟每隔510ms就要进行喂**作,否则看门狗将会打开复位。<p><br/><p>4、看门狗的实现不难,难点在于怎样验证自己设置的看门狗是否正确,难点在与想办法测试watchdog。<p><br/><p>  &nbsp;方法是在while(1)的循环里延时510ms以上(如延时600ms),通过对相关寄存器特征值的显示查看,来判断单片机是否被复位,若被复位则验证成功。<p><br/><p>5、值得注意的是,开门狗一旦打开就无法关闭,只有通过不断的喂狗来防止复位。<p><br/><p>6、下面给出代码思路并且附带详细注释:<p><br/><p>  &nbsp;由于延时函数如果延时太久会无法实现喂**作,所以应该在原来的Delay1ms()函数的基础上,再另外定义一个newDelay()函数,目的是每次延时250ms时(即调用Delay1ms(250))喂狗;<p><br/><p><br/><p>&nbsp; 1 /*-- private variable --*/<p>&nbsp; 2 __IO uint32_t space_reloadTM = 250;//define every after 250 ms reload IWDG<p>&nbsp; 3&nbsp;<p>&nbsp; 4 /*-- private function --*/<p>&nbsp; 5 void NewDelay(__IO uint32_t nTime);//include reload IWDG<p>&nbsp; 6&nbsp;<p>&nbsp; 7 static void IWDG_Config_Enable(void);//config and enable IWDG<p>&nbsp; 8&nbsp;<p>&nbsp; 9&nbsp;<p>&nbsp;10 /*-- main function --*/<p>&nbsp;11 int main()<p>&nbsp;12 {<p>&nbsp;13 &nbsp; &nbsp; IWDG_Config_Enable(); //config and enable IWDG&nbsp;<p>&nbsp;14&nbsp;<p>&nbsp;15 &nbsp; &nbsp; //for test<p>&nbsp;16 &nbsp; &nbsp; while (1)<p>&nbsp;17 &nbsp; &nbsp; {<p>&nbsp;18 &nbsp; &nbsp; &nbsp; &nbsp; Delay1ms(600); //timeout and reset happend<p>&nbsp;19 &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<p>&nbsp;20 &nbsp; &nbsp; &nbsp; &nbsp; /*-- never runs here --*/<p>&nbsp;21 &nbsp; &nbsp; &nbsp;&nbsp;<p>&nbsp;22 &nbsp; &nbsp; &nbsp; &nbsp; //Reload IWDG counter<p>&nbsp;23 &nbsp; &nbsp; &nbsp; &nbsp; IWDG_ReloadCounter();<p>&nbsp;24 &nbsp; &nbsp; }<p>&nbsp;25 }<p>&nbsp;26&nbsp;<p>&nbsp;27&nbsp;<p>&nbsp;28&nbsp;<p>&nbsp;29 void NewDelay(__IO uint32_t nTime)<p>&nbsp;30 {<p>&nbsp;31 &nbsp; &nbsp; uint32_t time_divisor = nTime/space_reloadTM;<p>&nbsp;32 &nbsp; &nbsp; uint32_t time_remainder = nTime%space_reloadTM;<p>&nbsp;33 &nbsp; &nbsp; uint8_t i;<p>&nbsp;34 &nbsp; &nbsp;&nbsp;<p>&nbsp;35 &nbsp; &nbsp; /* every after 250ms reload IWDG */<p>&nbsp;36 &nbsp; &nbsp; for(i=0;i<time_divisor;i++)<p>&nbsp;37 &nbsp; &nbsp; {<p>&nbsp;38 &nbsp; &nbsp; &nbsp; &nbsp; Delay1ms(space_reloadTM);<p>&nbsp;39 &nbsp; &nbsp; &nbsp; &nbsp; //Reload IWDG counter<p>&nbsp;40 &nbsp; &nbsp; &nbsp; &nbsp; IWDG_ReloadCounter();<p>&nbsp;41 &nbsp; &nbsp; }<p>&nbsp;42 &nbsp; &nbsp;&nbsp;<p>&nbsp;43 &nbsp; &nbsp; /* delay the remain time */<p>&nbsp;44 &nbsp; &nbsp; Delay1ms(time_remainder);<p>&nbsp;45 &nbsp; &nbsp; //Reload IWDG counter<p>&nbsp;46 &nbsp; &nbsp; IWDG_ReloadCounter();<p>&nbsp;47 }<p>&nbsp;48 /*<p>&nbsp;49 void Delay1ms(__IO uint32_t nTime)<p>&nbsp;50 {<p>&nbsp;51 &nbsp; TimingDelay = nTime;<p>&nbsp;52&nbsp;<p>&nbsp;53 &nbsp; while (TimingDelay != 0);<p>&nbsp;54 }<p>&nbsp;55 */<p>&nbsp;56&nbsp;<p>&nbsp;57&nbsp;<p>&nbsp;58&nbsp;<p>&nbsp;59 /<p>&nbsp;60 &nbsp;* @brief &nbsp;Configures the IWDG to generate a Reset if it is not refreshed at the<p>&nbsp;61 &nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; correct time.<p>&nbsp;62 &nbsp;* @param &nbsp;None<p>&nbsp;63 &nbsp;* @retval None<p>&nbsp;64 &nbsp;*/<p>&nbsp;65 static void IWDG_Config_Enable(void)<p>&nbsp;66 {<p>&nbsp;67 &nbsp; &nbsp; /* Check if the system has resumed from IWDG reset */<p>&nbsp;68 &nbsp; &nbsp; if (RST_GetFlagStatus(RST_FLAG_IWDGF) != RESET)<p>&nbsp;69 &nbsp; &nbsp; {<p>&nbsp;70 &nbsp; &nbsp; &nbsp; &nbsp; printf("nr");<p>&nbsp;71 &nbsp; &nbsp; &nbsp; &nbsp; uart2str(uartbuff,RST->SR,8,2,&#39;0&#39;); &nbsp; //output RST register<p>&nbsp;72 &nbsp; &nbsp; &nbsp; &nbsp; printf("Timeout, RST_SR=%snr",uartbuff);<p>&nbsp;73 &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<p>&nbsp;74 &nbsp; &nbsp; &nbsp; &nbsp; printf("timeout!!!");<p>&nbsp;75 &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<p>&nbsp;76 &nbsp; &nbsp; &nbsp; &nbsp; /* IWDGF flag set */<p>&nbsp;77 &nbsp; &nbsp; &nbsp; &nbsp; /* Clear IWDGF Flag */<p>&nbsp;78 &nbsp; &nbsp; &nbsp; &nbsp; RST_ClearFlag(RST_FLAG_IWDGF);<p>&nbsp;79 &nbsp; &nbsp; }<p>&nbsp;80 &nbsp; &nbsp; else<p>&nbsp;81 &nbsp; &nbsp; {<p>&nbsp;82 &nbsp; &nbsp; &nbsp; &nbsp; //IWDGF flag is not set<p>&nbsp;83 &nbsp; &nbsp; }<p>&nbsp;84 &nbsp; &nbsp;&nbsp;<p>&nbsp;85 &nbsp; &nbsp;&nbsp;<p>&nbsp;86 &nbsp; &nbsp; /* --- IWDG Configuration --- */<p>&nbsp;87 &nbsp; &nbsp;&nbsp;<p>&nbsp;88 &nbsp; &nbsp; /* Enable IWDG (the LSI oscillator will be enabled by hardware) */<p>&nbsp;89 &nbsp; &nbsp; IWDG_Enable(); //0xCC<p>&nbsp;90 &nbsp; &nbsp;&nbsp;<p>&nbsp;91 &nbsp; &nbsp; /* IWDG timeout equal to 250 ms (the timeout may varies due to LSI frequency<p>&nbsp;92 &nbsp; &nbsp; &nbsp;dispersion) */<p>&nbsp;93 &nbsp; &nbsp; /* Enable write access to IWDG_PR and IWDG_RLR registers */<p>&nbsp;94 &nbsp; &nbsp; IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //0x55<p>&nbsp;95 &nbsp; &nbsp;&nbsp;<p>&nbsp;96 &nbsp; &nbsp; /* IWDG counter clock: LSI/128 */<p>&nbsp;97 &nbsp; &nbsp; IWDG_SetPrescaler(IWDG_Prescaler_128);<p>&nbsp;98 &nbsp; &nbsp;&nbsp;<p>&nbsp;99 &nbsp; &nbsp; /* Set counter reload value to obtain 250ms IWDG Timeout.<p>100 &nbsp; &nbsp; &nbsp;Counter Reload Value = 250ms/IWDG counter clock period<p>101 &nbsp; &nbsp; &nbsp;= 250ms / (LSI/128)<p>102 &nbsp; &nbsp; &nbsp;= 0.25s / (LsiFreq/128)<p>103 &nbsp; &nbsp; &nbsp;= LsiFreq/(128 * 4)<p>104 &nbsp; &nbsp; &nbsp;= LsiFreq/512<p>105 &nbsp; &nbsp; &nbsp;*/<p>106 &nbsp; &nbsp; IWDG_SetReload((uint8_t)(0xFF));//510ms<p>107 &nbsp; &nbsp;&nbsp;<p>108 &nbsp; &nbsp; /* Reload IWDG counter */<p>109 &nbsp; &nbsp; IWDG_ReloadCounter(); //0xAA<p>110 }<p>watchdog<p>&nbsp;<p><br/><p>  &nbsp;为了验证代码的可实现性,故意在主函数中调用Delay1ms(600),所以正确的执行结果应该是:执行Delay1ms(600),watchdog启动复位,输出timeout之类的提示;<p><br/><p>  &nbsp;其中证明是否是watchdog启动的复位:查看RST->SR(Reset status register)中Bit1的值,为1表示An IWDG reset occurred,为0表示No IWDG reset occurred。 

讯享网
小讯
上一篇 2025-05-15 18:29
下一篇 2025-05-17 20:03

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/147552.html