/********************************************************* *Copyright (C), 2015, Shanghai Eastsoft Microelectronics Co., Ltd. *文件名: lib_scu.c *作 者: AE Team *版 本: V1.01 *日 期: 2021/06/09 *描 述: SCU模块库函数 *备 注: 本软件仅供学习和演示使用,对用户直接引用代码所带来的风险或后果不承担任何法律责任。 **********************************************************/ #include "lib_scu.h" /*************************************************************** 函数名:SCU_NMISelect 描 述:设置NMI不可屏蔽中断 输入值:不可屏蔽中断 输出值:无 返回值:无 ***************************************************************/ void SCU_NMISelect(SCU_TYPE_NMICS NMI_Type) { SCU_RegUnLock(); SCU->NMICON.NMICS = NMI_Type; SCU_RegLock() ; return; } /*************************************************************** 函数名:SCU_GetPWRCFlagStatus 描 述:获取PWRC复位状态寄存器标志位状态 输入值:PWRC寄存器标志位 输出值:无 返回值:RESET/SET ***************************************************************/ FlagStatus SCU_GetPWRCFlagStatus(SCU_TYPE_PWRC PWRC_Flag) { FlagStatus bitstatus = RESET; SCU_RegUnLock(); if ((SCU->PWRC.Word & (uint32_t)PWRC_Flag) != (uint32_t)RESET) bitstatus = SET; SCU_RegLock() ; return bitstatus; } /*************************************************************** 函数名:SCU_ClearPWRCFlagBit 描 述:清除PWRC复位状态寄存器标志位 输入值:PWRC寄存器标志位 输出值:无 返回值:无 ***************************************************************/ void SCU_ClearPWRCFlagBit(SCU_TYPE_PWRC PWRC_Flag) { SCU_RegUnLock() ; SCU->PWRC.Word &= ~((uint32_t)PWRC_Flag); SCU_RegLock() ; return; } /*************************************************************** 函数名:SCU_GetLVDFlagStatus 描 述:获取LVDD寄存器标志位状态 输入值:LVD寄存器标志位 输出值:无 返回值:RESET/SET ***************************************************************/ FlagStatus SCU_GetLVDFlagStatus(SCU_TYPE_LVDCON LVD_Flag) { FlagStatus bitstatus = RESET; SCU_RegLock() ; if ((SCU->LVDCON.Word & (uint32_t)LVD_Flag) != (uint32_t)RESET) bitstatus = SET; return bitstatus; } /*************************************************************** 函数名:SCU_SysClkSelect 描 述:选择系统时钟 输入值:时钟源 输出值:无 返回值:无 ***************************************************************/ void SCU_SysClkSelect(SCU_TYPE_SYSCLK Sysclk) { SCU_RegUnLock() ; SCU->SCLKEN0.CLK_SEL = Sysclk; SCU_RegLock() ; return; } /*************************************************************** 函数名:SCU_GetSysClk 描 述:获取系统时钟源 输入值:无 输出值:无 返回值:系统时钟源 ***************************************************************/ SCU_TYPE_SYSCLK SCU_GetSysClk(void) { return (SCU_TYPE_SYSCLK)(SCU->SCLKEN0.CLK_SEL); } /*************************************************************** 函数名:SCU_OpenXTAL 描 述: 开启外部时钟 输入值:无 输出值:无 返回值:系统时钟源 ***************************************************************/ void SCU_OpenXTAL(void) { SCU_RegUnLock(); SCU->SCLKEN1.XTAL_EN = 1; while (SCU->SCLKEN1.XTAL_RDY == 0); /* 等待外部时钟稳定 */ SCU_RegLock() ; } /*************************************************************** 函数名:DeviceClockAllEnable 描 述:打开所有外设时钟 输入值:无 输出值:无 返回值:无 ***************************************************************/ void DeviceClockAllEnable(void) { uint32_t prot_tmp; prot_tmp = SCU->PROT.PROT; if (prot_tmp != 0) /* 写保护了 */ SCU_RegUnLock(); /* 解锁 */ SCU->PCLKEN.Word = 0xFFFFFFFF; /* 打开所有外设时钟 */ if (prot_tmp != 0) /* 写保护了 */ SCU_RegLock(); /* 打开写保护 */ return; } /*************************************************************** 函数名:DeviceClockAllDisable 描 述:关闭所有外设时钟 输入值:无 输出值:无 返回值:无 ***************************************************************/ void DeviceClockAllDisable(void) { uint32_t prot_temp; prot_temp = SCU->PROT.PROT; if (prot_temp != 0) /* 写保护了 */ SCU_RegUnLock(); /* 解锁 */ SCU->PCLKEN.Word = 0x00000000; /* 关闭所有外设时钟,scu无法关闭 */ if (prot_temp != 0) /* 写保护了 */ SCU_RegLock(); /* 打开写保护 */ return; } /*************************************************************** 函数名: DeviceClockAllEnableButIAP 描 述: 打开除IAP模块以外所有外设时钟 输入值: 无 输出值: 无 返回值: 无 ***************************************************************/ void DeviceClockAllEnableButIAP(void) { uint32_t prot_tmp; prot_tmp = SCU->PROT.PROT; if (prot_tmp != 0) /* 写保护已开 */ SCU_RegUnLock(); /* 解锁写保护 */ SCU->PCLKEN.Word = 0xFFFFFFFB; /* 打开除IAP以外所有外设时钟 */ if (prot_tmp != 0) /* 写保护已开 */ SCU_RegLock(); /* 打开写保护 */ return; } /*************************************************************** 函数名:DeviceClock_Config 描 述:配置外设是否使能 输入值:tppe_periph :选择的外设类型 ,NewState :Disable或Enable 输出值:无 返回值:无 ***************************************************************/ void DeviceClock_Config(SUC_TYPE_Periph tppe_periph, TYPE_FUNCEN NewState) { SCU_RegUnLock(); if (NewState != Disable) { SCU->PCLKEN.Word |= tppe_periph; } else { SCU->PCLKEN.Word &= ~tppe_periph; } SCU_RegLock(); return; } /*************************************************************** 函数名:HRC_Config 描 述:HRC时钟配置,芯片上电后HRC默认16MHz 输入值: hrc_en:是否开启HRC, hrc_fre:hrc时钟频率选择, sys_hrc:系统时钟是否使用HRC时钟 内部高速时钟频率可配置为2MHz、16MHz、32MHz、48MHz 输出值:无 返回值:无 ***************************************************************/ void HRC_Config(TYPE_FUNCEN hrc_en, SCU_HRC_FRE hrc_fre, TYPE_FUNCEN sys_hrc) { SCU_RegUnLock(); if (hrc_en == Enable) { /* 如果内部高速时钟未开启或不稳定,则重新开启HRC等待HRC稳定 */ if (SCU->SCLKEN1.HRC_RDY == 0) { SCU->SCLKEN1.XTAL_EN = 0x0; SCU->SCLKEN1.HRC_EN = 0x1; while (SCU->SCLKEN1.HRC_RDY == 0x0); /* 等待HRC稳定 */ } /* 配置合适的FLASH读取访问等待时间 */ SCU->FLASHWAIT.ACCT = 0x01; /* 2Tclk完成FLASH读取 */ /* 设置HRC时钟频率 */ SCU->SCLKEN1.HRC_FRE = hrc_fre; /* 设置系统时钟源 */ if (sys_hrc == Enable) { SCU->SCLKEN0.CLK_SEL = 0x00; while (SCU->SCLKEN1.HRC_RDY == 0); /* 等待HRC稳定 */ } else { while (SCU->SCLKEN1.HRC_RDY == 0); /* 等待HRC稳定 */ } } else { /* 关闭HRC切换到LRC时钟频率 */ SCU->SCLKEN1.XTAL_EN = 0x0; SCU->SCLKEN1.HRC_EN = 0x0; /* 设置系统时钟源 */ SCU->SCLKEN0.CLK_SEL = 0x01; } SCU_RegLock(); return; } /*************************************************************** 函数名:SCU_MultTimerEnable 描 述:多个时钟同时开启(T16N0/1/2/3,P32N0) 输入值:SCU_TimerMask:可以是T16N0/1/2/3和T32N0的任意组合 输出值:无 返回值:无 ***************************************************************/ void SCU_MultTimerEnable(SCU_TIMEREN_Typedef SCU_TimerMask) { SCU_RegUnLock(); SCU->TIMEREN.Word = SCU_TimerMask.Word; SCU_RegLock(); } /*************************************************************** 函数名:SCU_MultTimerDisable 描 述:多个时钟同时关闭(T16N0/1/2/3,P32N0) 输入值:SCU_TimerMask:可以是T16N0/1/2/3和T32N0的任意组合 输出值:无 返回值:无 ***************************************************************/ void SCU_MultTimerDisable(SCU_TIMERDIS_Typedef SCU_TimerMask) { SCU_RegUnLock(); SCU->TIMERDIS.Word = SCU_TimerMask.Word; SCU_RegLock(); }