lib_scu.c 10.2 KB
Newer Older
W
wangyq2018 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
/***************************************************************
 *Copyright (C), 2017, Shanghai Eastsoft Microelectronics Co., Ltd
 *文件名:  lib_scu.c
 *作  者:  Liut
 *版  本:  V1.00
 *日  期:  2017/07/14
 *描  述:  系统控制模块库函数
 *备  注:  适用于 ES8P508x芯片
 本软件仅供学习和演示使用,对用户直接引用代码所带来的风险或后果不承担任何法律责任。
 ***************************************************************/
#include "lib_scu.h"

/***************************************************************
  函数名:SCU_OpenXTAL
  描  述: 开启外部时钟
  输入值:无
  输出值:无
  返回值:系统时钟源
 ***************************************************************/
void SCU_OpenXTAL(void)
{
	SCU_RegUnLock();
	SCU->SCLKEN1.XTAL_EN = 1;
	SCU->SCLKEN0.XTAL_LP = 0;
	while(SCU->SCLKEN1.XTAL_RDY == 0); //等待外部时钟稳定
	SCU_RegLock() ;
}

/***************************************************************
  函数名:SCU_NMISelect
  描  述:设置NMI不可屏蔽中断
  输入值:不可屏蔽中断
  输出值:无
  返回值:无
 ***************************************************************/
void SCU_NMISelect(SCU_TYPE_NMICS NMI_Type)
{
	  SCU_RegUnLock();
    SCU->NMICON.NMICS = NMI_Type;
	  SCU_RegLock() ;
}

/***************************************************************
  函数名:SCU_GetPWRCFlagStatus
  描  述:获取PWRC复位状态寄存器标志位状态
  输入值:PWRC寄存器标志位
  输出值:无
  返回值:RESET/SET
 ***************************************************************/
FlagStatus  SCU_GetPWRCFlagStatus(SCU_TYPE_PWRC PWRC_Flag)
{
    FlagStatus bitstatus = RESET;
    if((SCU->PWRC.Word & (uint32_t)PWRC_Flag) != (uint32_t)RESET)
        bitstatus = SET;
    else
        bitstatus = RESET;

    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() ;
}

/***************************************************************
  函数名:SCU_GetLVDFlagStatus
  描  述:获取LVDD寄存器标志位状态
  输入值:LVD寄存器标志位
  输出值:无
  返回值:RESET/SET
 ***************************************************************/
FlagStatus  SCU_GetLVDFlagStatus(SCU_TYPE_LVD0CON LVD_Flag)
{
    FlagStatus bitstatus = RESET;

    if((SCU->LVDCON.Word & (uint32_t)LVD_Flag) != (uint32_t)RESET)
        bitstatus = SET;
    else
        bitstatus = RESET;

    return  bitstatus;
}

/***************************************************************
  函数名:SCU_SysClkSelect
  描  述:选择系统时钟
  输入值:时钟源
  输出值:无
  返回值:无
 ***************************************************************/
void SCU_SysClkSelect(SCU_TYPE_SYSCLK Sysclk)
{
	  SCU_RegUnLock() ;
    SCU->SCLKEN0.CLK_SEL = Sysclk;
	  SCU_RegLock() ;
}

/***************************************************************
  函数名:SCU_GetSysClk
  描  述:获取系统时钟源
  输入值:无
  输出值:无
  返回值:系统时钟源
 ***************************************************************/
SCU_TYPE_SYSCLK SCU_GetSysClk(void)
{
    return (SCU_TYPE_SYSCLK)(SCU->SCLKEN0.CLK_SEL);
}

/***************************************************************
  函数名:SCU_HRCReadyFlag
  描  述:获取HRC稳定标志位
  输入值:无
  输出值:无
  返回值:RESET(不稳定)/SET(稳定)
 ***************************************************************/
FlagStatus SCU_HRCReadyFlag(void)
{
    FlagStatus bitstatus = RESET;

    if((SCU->SCLKEN1.HRC_RDY) != (uint32_t)RESET)
        bitstatus = SET;
    else
        bitstatus = RESET;

    return  bitstatus;
}

/***************************************************************
  函数名:SCU_XTALReadyFlag
  描  述:获取XTAL稳定标志位
  输入值:无
  输出值:无
  返回值:RESET(不稳定)/SET(稳定)
 ***************************************************************/
FlagStatus  SCU_XTALReadyFlag(void)
{
    FlagStatus bitstatus = RESET;

    if((SCU->SCLKEN1.XTAL_RDY) != (uint32_t)RESET)
        bitstatus = SET;
    else
        bitstatus = RESET;

    return  bitstatus;
}

/***************************************************************
  函数名:SCU_LOSCReadyFlag
  描  述:获取LOSC稳定标志位
  输入值:无
  输出值:无
  返回值:RESET(不稳定)/SET(稳定)
 ***************************************************************/
FlagStatus  SCU_PLLReadyFlag(void)
{
    FlagStatus bitstatus = RESET;

    if((SCU->SCLKEN1.PLL_RDY) != (uint32_t)RESET)
        bitstatus = SET;
    else
        bitstatus = RESET;

    return  bitstatus;
}

/***************************************************************
 函数名:SystemClockConfig
 描  述:系统时钟配置:内部时钟,20MHZ,打开所有外设时钟
 输入值:无
 输出值:无
 返回值:无
***************************************************************/
void SystemClockConfig(void)
{
    uint32_t Prot_Temp;

    Prot_Temp = SCU->PROT.PROT;

    if(Prot_Temp != 0)                      //写保护了
        SCU_RegUnLock();                    //解锁

    SCU_HRC_Enable();                       //使能内部20MHZ
    while(SCU_HRCReadyFlag() != SET);       //等待时钟开启
    SCU_SysClkSelect(SCU_SysClk_HRC);       //选择内部20MHZ为系统时钟
	
    SCU_SysClk_Div1();                      //系统时钟后分频1:1    
    
    SystemCoreClock = 20000000;

    if(Prot_Temp != 0)                      //写保护了
        SCU_RegLock();                      //打开写保护
}

/***************************************************************
  函数名:DeviceClockAllEnable
  描  述:打开所有外设时钟
  输入值:无
  输出值:无
  返回值:无
 ***************************************************************/
void DeviceClockAllEnable(void)
{
    uint32_t Prot_Temp;

    Prot_Temp = SCU->PROT.PROT;
    if(Prot_Temp != 0)                      //写保护了
        SCU_RegUnLock();                    //解锁

    SCU->PCLKEN0.Word = 0xFFFFFFFF;
    SCU->PCLKEN1.Word = 0xFFFFFFFF;         //打开所有外设时钟

    if(Prot_Temp != 0)                      //写保护了
        SCU_RegLock();                      //打开写保护
}

/***************************************************************
  函数名:DeviceClockAllDisable
  描  述:关闭所有外设时钟
  输入值:无
  输出值:无
  返回值:无
 ***************************************************************/
void DeviceClockAllDisable(void)
{
    uint32_t Prot_Temp;

    Prot_Temp = SCU->PROT.PROT;
    if(Prot_Temp != 0)                      //写保护了
        SCU_RegUnLock();                    //解锁

    SCU->PCLKEN0.Word = 0x00000000;         //关闭所有外设时钟,scu无法关闭
    SCU->PCLKEN1.Word = 0x00000000;

    if(Prot_Temp != 0)                      //写保护了
        SCU_RegLock();                  //打开写保护
}

/***************************************************************
  函数名:SystemClockConfig
  描  述:系统时钟选择
  输入值:CLKx 系统时钟源选择
  输出值:无
  返回值:无
 ***************************************************************/
void SystemClockSelect(SCU_TYPE_SYSCLK SYSCLKx , SCU_TYPE_CLK_SEL CLK_SEL)
{
    SCU_RegUnLock();                        //解锁

    switch(SYSCLKx)
    {
        case 0:
            SCU_HRC_Enable();
            while(SCU_HRCReadyFlag() != SET);
            break;
        case 1:
            SCU_XTAL_Enable();
            while(SCU_XTALReadyFlag() != SET);
            break;
        case 2:
            SCU_PLL_Enable();
            while(SCU_PLLReadyFlag() != SET);
            break;
        default:break;
    }

    SCU->SCLKEN0.SYSCLK_DIV = 0;
    SCU->SCLKEN0.CLK_SEL = CLK_SEL;

    SCU_RegLock();
}


/***************************************************************
  函数名:PLLClock_Config
  描  述:PLL时钟配置,并设置PLL时钟为系统时钟
  输入值:pll_en:是否开启PLL,pll_origin:pll时钟源选择,pll_out:pll输出频率选择,sys_pll:系统时钟是否使用PLL时钟
  输出值:无
  返回值:无
 ***************************************************************/
void PLLClock_Config(TYPE_FUNCEN pll_en , SCU_PLL_Origin  pll_origin ,SCU_PLL_Out pll_out,TYPE_FUNCEN sys_pll)
{
    SCU_RegUnLock();

    if(pll_en == DISABLE)  //如果PLL配置为禁止,则直接禁止PLL,并返回
    {
        SCU->SCLKEN0.PLL_MUX = 0;
        SCU->SCLKEN1.PLL_BYLOCK = 0;
        SCU->SCLKEN0.CLKFLT_BY = 0x00;
        SCU->SCLKEN1.PLL_EN = 0;
        return;
    }

    if((pll_origin == SCU_PLL_HRC))         //如果使用内部高速时钟,需开启内部高速时钟
    {
        if(SCU->SCLKEN1.HRC_RDY == 0)
        {
            SCU->SCLKEN1.HRC_EN = 1;
            while(SCU->SCLKEN1.HRC_RDY == 0);  //等待HRC开启
        }
    }

    if((pll_origin == SCU_PLL_XTAL_32K)
       || (pll_origin == SCU_PLL_XTAL_4M)
       ||(pll_origin == SCU_PLL_XTAL_8M)
       || (pll_origin == SCU_PLL_XTAL_16M)
       || (pll_origin == SCU_PLL_XTAL_20M))          //如果使用外部时钟,需开启外部时钟
    {
        if(SCU->SCLKEN1.XTAL_RDY == 0)
        {
            SCU->SCLKEN1.XTAL_EN = 1;
					  SCU->SCLKEN0.XTAL_LP = 0;
            while(SCU->SCLKEN1.XTAL_RDY == 0);  //等待XTAL开启
        }
    }

    switch(pll_origin)
    {
        case SCU_PLL_HRC:
            SCU->SCLKEN1.PLL_REF_SEL = 0x00;
            break;
        case SCU_PLL_LRC:
            SCU->SCLKEN1.PLL_REF_SEL = 0x02;
            break;
        case SCU_PLL_XTAL_32K:
            SCU->SCLKEN1.PLL_REF_SEL = 0x03;
            break;
        case SCU_PLL_XTAL_4M:
            SCU->SCLKEN1.PLL_REF_SEL = 0x04;
            break;
        case SCU_PLL_XTAL_8M:
            SCU->SCLKEN1.PLL_REF_SEL = 0x05;
            break;
        case SCU_PLL_XTAL_16M:
            SCU->SCLKEN1.PLL_REF_SEL = 0x06;
            break;
        case SCU_PLL_XTAL_20M:
            SCU->SCLKEN1.PLL_REF_SEL = 0x07;
            break;
        default:
            break;
    }

    SCU->SCLKEN1.PLL_48M_SEL = pll_out;   //配置PLL输出为32或48Mhz

    SCU->SCLKEN1.PLL_EN = 1;
    while(SCU->SCLKEN1.PLL_RDY == 0);


    if(sys_pll == ENABLE)
    {

        if(pll_out == SCU_PLL_32M)
        {
          SCU->SCLKEN0.CLKFLT_BY = 0;
        }
        else
        {
          SCU->SCLKEN0.CLKFLT_BY = 0x55;  //48M 时钟滤波旁路
        }
        SCU->SCLKEN1.PLL_BYLOCK = 1;
        SCU->SCLKEN0.PLL_MUX = 1;
    }
    else
    {
        SCU->SCLKEN0.PLL_MUX = 0;
        SCU->SCLKEN1.PLL_BYLOCK = 0;
        SCU->SCLKEN0.CLKFLT_BY = 0x00;
    }

    SCU_RegLock(); 
}

/*************************END OF FILE**********************/