tag 标签: 寄存器配置

相关博文
  • 热度 4
    2020-11-13 13:40
    1149 次阅读|
    0 个评论
    MM32 MCU内置了两个内置了两个看门狗(独立看门狗和窗口看门狗),为软件系统增加了更加安全的检测机制。 IWDG 由专门的低速时钟( LSI )驱动,即使主时钟发生故障它也仍然有效,使得它能够工作于低功耗模式下。 IWDG 最适合应用于那些需要看门狗作为一个正在主程序外,能够完全独立工作,并且对时间精度要求低的场合。 IWDG看门狗的原理是:MCU系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种情况的发生。看门狗的作用就是在一定时间内(通过递减计数器实现)没有接收喂狗信号(表示MCU未正常运行),便实现处理器的自动复位重启(发送复位信号)。 从IWDG看门狗的功能框图来看,它分为两个部分,配置寄存器在 1.8V 供电区,计数器的核心部分以及复位信号在 VDD 供电区 ( 这使得即使在停机 / 待机模式下计数器也能计数 ) ;由于处在不同的电源域,每次加载新数据时都需检测状态位。 1.IWDG超时时间计算及喂狗 IWDG的工作流程为:在键值寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗;此时计数器开始从其复位值0xFFF递减计数。当计数器计数到末尾0x000时,会产生一个复位信号(IWDG_RESET)。无论何时,只要键寄存器IWDG_KR中被写入0xAAAA,IWDG_RLR中的值就会被重新加载到计数器中从而避免产生看门狗复位。IWDG_PR和IWDG_RLR寄存器具有写保护功能。要修改这两个寄存器的值,必须先向IWDG_KR寄存器中写入0x5555。将其他值写入这个寄存器将会打乱操作顺序,寄存器将重新被保护。重装载操作(即写入0xAAAA)也会启动写保护功能。 以下为看门狗超时时间说明表: 结合上表,正确的计算IWDG看门狗超时时间的公式为: Tout=(4 * 2^PR * (RL+1) ) / 40 ms 其中Tout为看门狗溢出时间(单位为ms);PR为看门狗时钟预分频值(IWDG_PR值),范围为0~7,0对应4分频,1对应8分频,......所以时间计算公式要乘以4;RL为看门狗的重装载值(IWDG_RLR的值)。 注意事项:看门狗的时钟不是准确的 40KHz,所以在喂狗的时候,最好不要太晚了,否则有可能发生看门狗复位! 2.IWDG中断做延时功能 为了满足某些场合的需求,可将IWDG产生的复位更改配置为产生中断,从而实现类似定时器的更新中断功能。 在初始化IWDG的时候,需要将 LSI 时钟开启,将 CR bit0 位置为“溢出后产生中断 ”,以下为还需要注意的初始化代码片段: IWDG_WriteAccessCmd(0x5555); IWDG_SetPrescaler(IWDG_Prescaler); PVU_CheckStatus();//看门狗预分频更新状态位检测,该语句必须置于以上两句之后而不能在其前!!! IWDG_WriteAccessCmd(0x5555); IWDG_SetReload(Reload & 0xfff); RVU_CheckStatus();//看门狗计数器重装载值更新状态位检测,该语句必须置于以上两句之后而不能在其前!!! 以下为看门狗中断服务程序中要注意的代码片段: void WWDG_IRQHandler(void) { LED2_OFF();//用作调试,指示延时时间 CR bit1 清除IWDG中断标志 Write_Iwdg_ON(IWDG_Prescaler_4,992);//必须重新配置并开启看门狗!!! EXTI_ClearFlag(EXTI_Line24);//清除外部中断线标志,以实际芯片的映射为准 LED2_ON(); } 注意事项: IWDG 看门狗的时钟不是准确的 40KHz ,且进出中断都会消耗时间,不建议用此方式来做精准的延时 ! 3.IWDG硬件看门狗模式 在某些严苛的应用环境下软件看门狗可能都已经跑飞或者无法正常生效,就需要开启硬件看门狗来作为系统稳定运行的保障。MM32 MCU的IWDG具有软件看门狗和硬件看门狗模式,默认状态下为软件看门狗模式。 如果用户在选择字节中启动了‘硬件看门狗’功能,在系统上电复位后,看门狗会自动开始运行 而不需要软件开启看门狗;硬件看门狗开启后如同软件看门狗一样,需要及时做喂狗处理,否则系统会产生复位;该模式开启后,在调试程序时也无法停止和关闭看门狗,想要关闭则必须对选项字节对应位进行修改或者擦除 。 以下为可供参考的实现功能的样例代码片段: RCC_LSICmd(ENABLE);//LSI启动并且等待LSI起振标志位置位 while ((RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)&&temp<250) { temp++; //delay_ms(10); } =250)return 1;//LSI启动超时,出错返回 OBR&FLASH_OBR_WDG_SW)//若为软件看门狗,首次运行会进这里 { //Write_Iwdg_ON(IWDG_Prescaler_32,0xFFF);//可根据实际需求改变预分频值和重载值 FLASH_Unlock(); FLASH_UserOptionByteConfig(OB_IWDG_HW,OB_STOP_NoRST,OB_STDBY_NoRST);//改用硬件看门狗,写法一 //FLASH_ProgramOptionHalfWord(0x1ffff802,0,0x00FE);//改用硬件看门狗,写法二 FLASH_Lock(); NVIC_SystemReset();//复位以生效Flash的操作 } 注意事项: 建议不同版本的芯片都将LSI启动以保证硬件看门狗正常开启! 4.IWDG与低功耗模式 在开发中经常会用到独立看门狗(IWDG)和低功耗模式,看门狗是为了检测和解决由软件错误引起的故障,低功耗模式是为了在 CPU 不需要继续运行时进入到休眠模式用以节省电能。其中独立看门狗的时钟由独立的 RC 振荡器提供,即使在主时钟出现故障时,也仍然有效,因此可以在停止和待机模式下工作。 IWDG可以在低功耗模式下正常计数,它的复位能够使系统退出Standby模式。 IWDG与 Stop 低功耗模式共存的解决思路有——进 Stop 低功耗模式之前把 LSI 时钟关闭,这样就关掉了看门狗的时钟使得看门狗不工作;系统如果具备 RTC 功能,可以使用闹钟定时喂狗,喂完狗再继续休眠。比如看门狗复位的时间间隔为 10s 。那么在进入休眠模式前设置 RTC 闹钟中断时间为 5s 。这样每隔 5s 唤醒一次喂一次狗,便可以很好的解决这个问题。 5. 使用高速振荡器时钟计算内部LSI时钟频率 在 使用内部LSI时钟作为RTC的计数时钟 源时 , 考虑到 LSI的频率 为 40 KHz 左右 但不准确 , 在设置 RTC 的预分频值时可能需要先计算到较为准确的LSI时钟频率。通过 IWDG 复位的协助可以实现此功能,以下为大致思路: IWDG的应用案例分享到这, 原创第三篇,祝大家身体健康,工作顺利! Have fun!GGSD,DDUP!
  • 热度 20
    2015-1-16 10:11
    3683 次阅读|
    4 个评论
    锁相环 由 鉴相 器、环路滤波器 和 压控振荡器 组成。 通常鉴相器 与辅助电路分频器一般集成在一起。想要改变 VCO 的输出频率,则是通过改变分频器的分频比实现。现已 MC145146 PLL 芯片为例,对各寄存器参数配置与输出频率之间的关系做一点总结: 1. 一般结构 如下图所示, PLL 内有三个分频寄存器分别是 R 寄存器 ( 对参考时钟进行分频 ) , N 和 A 寄存器(对输出端 VCO 的频率进行分频),两路分频后的频率 进鉴相 器进行鉴相。锁定时,两路频率应该相等。 通常,在 VCO 频率在进 PLL 芯片之前会先经过一个双模预分频器,有的也集成在 PLL 芯片内。如下图的 ML12034 ,一般可实现 8/9,16/17,32/33,64/65,128/129 等分频,控制分频系数改变的是 PLL 引脚的控制电平,如下图 14 脚 MC 。 2. 频率改变原理 假设 两个鉴相频率 分别为参考源 经过 分频后的 和输出 VCO 频率 经过 分频后的 ,则有 其中, 比较好理解,就是寄存器 R, 而 由下式确定: 其中, N,A 为对应寄存器, P 为预分频器 P/P+1 的分频比。 注意:此处分频可以按照下面的理解: 其工作过程是:首先预分频器工作在 P+1 分频模式下,预分频器输出后同时输入给计数分频器 N 与 A 分频,当 A 计数满后控制预分频器工作在 P 分频模式下, N 继续计数直到满后 N 与 A 同时重置,重新开始。 在图 1 中,可以看出,计数分频器 N 输出鉴相频率 。假设 的周期为 t , 而鉴相 的周期为 T ,可以得到: 因此,分频比 。 总结: 1. 通过 R 、 N 、 A 、 P 控制 VCO 输出频率;       2. 由上式还可以看出, 鉴相频率 VCO 决定了 VCO 输出的步进频率。   3.PLL配置举例   下面以MC145146为例,用TI的430MCU为控制器,对其寄存器进行配置。由于MC145146与MSP430工作电平不同,中间用的TI的4054进行TTL到CMOS的电平转换。 根据MC145146的工作时序以及寄存器的对应关系可以看出,由A2-A0三位地址将A、N、R寄存器分7次写入数据,数据的写入方式为在数据与地址稳定后,由ST引脚的脉冲控制写入。   通过实验验证,下列程序可以对其其寄存器进行正确配置,函数还可以优化,基本原理相同。   /****************************************************** 程序功能:UpFreq 引脚定义:D3-D0:P2.3-P2.0,A2-A0:P2.7-P2.5,ST:P2.4 使用: *******************************************************/ #define CLR_ST   P2OUT=~BIT4    //ST #define SET_ST   P2OUT|= BIT4 unsigned char A=0x22; // unsigned char N1=0xB2; // unsigned char N2=0x01; // unsigned char R1=0x2C; // unsigned char R2=0x01; // /***************************************************************** 函数名称:  WriteReg 返回值  :无 *****************************************************************/ void WriteReg() {   unsigned char temp;   CLR_ST;   temp = A 0x0f;     //A取低4位   temp = temp + 0xe0;    P2OUT = 0x0f temp; //地址000   SET_ST;   CLR_ST; //写入   temp = A 0x70;    //A取高3位   temp = temp4;   temp = temp + 0xe0;   P2OUT = 0x2f temp;//地址001   SET_ST;   CLR_ST; //写入   temp = N1 0x0f;    //N1取低4位   temp = temp + 0xe0;   P2OUT = 0x4f temp; //地址002   SET_ST;   CLR_ST; //写入   temp = N1 0xf0;   temp = temp4;   temp = temp + 0xe0;   P2OUT = 0x6f temp;//地址003   SET_ST;   CLR_ST; //写入   temp = N2 0x03;    //N2取低2位   temp = temp + 0xe0;    P2OUT = 0x8f temp; //地址004   SET_ST;   CLR_ST; //写入   temp = R1 0x0f;    //R1取低4位   temp = temp + 0xe0;    P2OUT = 0xaf temp; //地址005   SET_ST;   CLR_ST; //写入   temp = R1 0xf0;   temp = temp4;   temp = temp + 0xe0;   P2OUT = 0xcf temp; //地址006   SET_ST;   CLR_ST; //写入   temp = R2 0x0f;    //R2取低2位   temp = temp + 0xe0;    P2OUT = 0xef temp; //地址007   SET_ST;   CLR_ST; //写入 }