You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
304 lines
8.9 KiB
304 lines
8.9 KiB
/*********************************************************
|
|
*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();
|
|
}
|
|
|
|
|
|
|