lib_scu.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /***************************************************************
  2. *Copyright (C), 2017, Shanghai Eastsoft Microelectronics Co., Ltd
  3. *文件名: lib_scu.c
  4. *作 者: Liut
  5. *版 本: V1.00
  6. *日 期: 2017/07/14
  7. *描 述: 系统控制模块库函数
  8. *备 注: 适用于 ES8P508x芯片
  9. 本软件仅供学习和演示使用,对用户直接引用代码所带来的风险或后果不承担任何法律责任。
  10. ***************************************************************/
  11. #include "lib_scu.h"
  12. /***************************************************************
  13. 函数名:SCU_OpenXTAL
  14. 描 述: 开启外部时钟
  15. 输入值:无
  16. 输出值:无
  17. 返回值:系统时钟源
  18. ***************************************************************/
  19. void SCU_OpenXTAL(void)
  20. {
  21. SCU_RegUnLock();
  22. SCU->SCLKEN1.XTAL_EN = 1;
  23. SCU->SCLKEN0.XTAL_LP = 0;
  24. while(SCU->SCLKEN1.XTAL_RDY == 0); //等待外部时钟稳定
  25. SCU_RegLock() ;
  26. }
  27. /***************************************************************
  28. 函数名:SCU_NMISelect
  29. 描 述:设置NMI不可屏蔽中断
  30. 输入值:不可屏蔽中断
  31. 输出值:无
  32. 返回值:无
  33. ***************************************************************/
  34. void SCU_NMISelect(SCU_TYPE_NMICS NMI_Type)
  35. {
  36. SCU_RegUnLock();
  37. SCU->NMICON.NMICS = NMI_Type;
  38. SCU_RegLock() ;
  39. }
  40. /***************************************************************
  41. 函数名:SCU_GetPWRCFlagStatus
  42. 描 述:获取PWRC复位状态寄存器标志位状态
  43. 输入值:PWRC寄存器标志位
  44. 输出值:无
  45. 返回值:RESET/SET
  46. ***************************************************************/
  47. FlagStatus SCU_GetPWRCFlagStatus(SCU_TYPE_PWRC PWRC_Flag)
  48. {
  49. FlagStatus bitstatus = RESET;
  50. if((SCU->PWRC.Word & (uint32_t)PWRC_Flag) != (uint32_t)RESET)
  51. bitstatus = SET;
  52. else
  53. bitstatus = RESET;
  54. return bitstatus;
  55. }
  56. /***************************************************************
  57. 函数名:SCU_ClearPWRCFlagBit
  58. 描 述:清除PWRC复位状态寄存器标志位
  59. 输入值:PWRC寄存器标志位
  60. 输出值:无
  61. 返回值:无
  62. ***************************************************************/
  63. void SCU_ClearPWRCFlagBit(SCU_TYPE_PWRC PWRC_Flag)
  64. {
  65. SCU_RegUnLock() ;
  66. SCU->PWRC.Word &= ~((uint32_t)PWRC_Flag);
  67. SCU_RegLock() ;
  68. }
  69. /***************************************************************
  70. 函数名:SCU_GetLVDFlagStatus
  71. 描 述:获取LVDD寄存器标志位状态
  72. 输入值:LVD寄存器标志位
  73. 输出值:无
  74. 返回值:RESET/SET
  75. ***************************************************************/
  76. FlagStatus SCU_GetLVDFlagStatus(SCU_TYPE_LVD0CON LVD_Flag)
  77. {
  78. FlagStatus bitstatus = RESET;
  79. if((SCU->LVDCON.Word & (uint32_t)LVD_Flag) != (uint32_t)RESET)
  80. bitstatus = SET;
  81. else
  82. bitstatus = RESET;
  83. return bitstatus;
  84. }
  85. /***************************************************************
  86. 函数名:SCU_SysClkSelect
  87. 描 述:选择系统时钟
  88. 输入值:时钟源
  89. 输出值:无
  90. 返回值:无
  91. ***************************************************************/
  92. void SCU_SysClkSelect(SCU_TYPE_SYSCLK Sysclk)
  93. {
  94. SCU_RegUnLock() ;
  95. SCU->SCLKEN0.CLK_SEL = Sysclk;
  96. SCU_RegLock() ;
  97. }
  98. /***************************************************************
  99. 函数名:SCU_GetSysClk
  100. 描 述:获取系统时钟源
  101. 输入值:无
  102. 输出值:无
  103. 返回值:系统时钟源
  104. ***************************************************************/
  105. SCU_TYPE_SYSCLK SCU_GetSysClk(void)
  106. {
  107. return (SCU_TYPE_SYSCLK)(SCU->SCLKEN0.CLK_SEL);
  108. }
  109. /***************************************************************
  110. 函数名:SCU_HRCReadyFlag
  111. 描 述:获取HRC稳定标志位
  112. 输入值:无
  113. 输出值:无
  114. 返回值:RESET(不稳定)/SET(稳定)
  115. ***************************************************************/
  116. FlagStatus SCU_HRCReadyFlag(void)
  117. {
  118. FlagStatus bitstatus = RESET;
  119. if((SCU->SCLKEN1.HRC_RDY) != (uint32_t)RESET)
  120. bitstatus = SET;
  121. else
  122. bitstatus = RESET;
  123. return bitstatus;
  124. }
  125. /***************************************************************
  126. 函数名:SCU_XTALReadyFlag
  127. 描 述:获取XTAL稳定标志位
  128. 输入值:无
  129. 输出值:无
  130. 返回值:RESET(不稳定)/SET(稳定)
  131. ***************************************************************/
  132. FlagStatus SCU_XTALReadyFlag(void)
  133. {
  134. FlagStatus bitstatus = RESET;
  135. if((SCU->SCLKEN1.XTAL_RDY) != (uint32_t)RESET)
  136. bitstatus = SET;
  137. else
  138. bitstatus = RESET;
  139. return bitstatus;
  140. }
  141. /***************************************************************
  142. 函数名:SCU_LOSCReadyFlag
  143. 描 述:获取LOSC稳定标志位
  144. 输入值:无
  145. 输出值:无
  146. 返回值:RESET(不稳定)/SET(稳定)
  147. ***************************************************************/
  148. FlagStatus SCU_PLLReadyFlag(void)
  149. {
  150. FlagStatus bitstatus = RESET;
  151. if((SCU->SCLKEN1.PLL_RDY) != (uint32_t)RESET)
  152. bitstatus = SET;
  153. else
  154. bitstatus = RESET;
  155. return bitstatus;
  156. }
  157. /***************************************************************
  158. 函数名:SystemClockConfig
  159. 描 述:系统时钟配置:内部时钟,20MHZ,打开所有外设时钟
  160. 输入值:无
  161. 输出值:无
  162. 返回值:无
  163. ***************************************************************/
  164. void SystemClockConfig(void)
  165. {
  166. uint32_t Prot_Temp;
  167. Prot_Temp = SCU->PROT.PROT;
  168. if(Prot_Temp != 0) //写保护了
  169. SCU_RegUnLock(); //解锁
  170. SCU_HRC_Enable(); //使能内部20MHZ
  171. while(SCU_HRCReadyFlag() != SET); //等待时钟开启
  172. SCU_SysClkSelect(SCU_SysClk_HRC); //选择内部20MHZ为系统时钟
  173. SCU_SysClk_Div1(); //系统时钟后分频1:1
  174. SystemCoreClock = 20000000;
  175. if(Prot_Temp != 0) //写保护了
  176. SCU_RegLock(); //打开写保护
  177. }
  178. /***************************************************************
  179. 函数名:DeviceClockAllEnable
  180. 描 述:打开所有外设时钟
  181. 输入值:无
  182. 输出值:无
  183. 返回值:无
  184. ***************************************************************/
  185. void DeviceClockAllEnable(void)
  186. {
  187. uint32_t Prot_Temp;
  188. Prot_Temp = SCU->PROT.PROT;
  189. if(Prot_Temp != 0) //写保护了
  190. SCU_RegUnLock(); //解锁
  191. SCU->PCLKEN0.Word = 0xFFFFFFFF;
  192. SCU->PCLKEN1.Word = 0xFFFFFFFF; //打开所有外设时钟
  193. if(Prot_Temp != 0) //写保护了
  194. SCU_RegLock(); //打开写保护
  195. }
  196. /***************************************************************
  197. 函数名:DeviceClockAllDisable
  198. 描 述:关闭所有外设时钟
  199. 输入值:无
  200. 输出值:无
  201. 返回值:无
  202. ***************************************************************/
  203. void DeviceClockAllDisable(void)
  204. {
  205. uint32_t Prot_Temp;
  206. Prot_Temp = SCU->PROT.PROT;
  207. if(Prot_Temp != 0) //写保护了
  208. SCU_RegUnLock(); //解锁
  209. SCU->PCLKEN0.Word = 0x00000000; //关闭所有外设时钟,scu无法关闭
  210. SCU->PCLKEN1.Word = 0x00000000;
  211. if(Prot_Temp != 0) //写保护了
  212. SCU_RegLock(); //打开写保护
  213. }
  214. /***************************************************************
  215. 函数名:SystemClockConfig
  216. 描 述:系统时钟选择
  217. 输入值:CLKx 系统时钟源选择
  218. 输出值:无
  219. 返回值:无
  220. ***************************************************************/
  221. void SystemClockSelect(SCU_TYPE_SYSCLK SYSCLKx , SCU_TYPE_CLK_SEL CLK_SEL)
  222. {
  223. SCU_RegUnLock(); //解锁
  224. switch(SYSCLKx)
  225. {
  226. case 0:
  227. SCU_HRC_Enable();
  228. while(SCU_HRCReadyFlag() != SET);
  229. break;
  230. case 1:
  231. SCU_XTAL_Enable();
  232. while(SCU_XTALReadyFlag() != SET);
  233. break;
  234. case 2:
  235. SCU_PLL_Enable();
  236. while(SCU_PLLReadyFlag() != SET);
  237. break;
  238. default:break;
  239. }
  240. SCU->SCLKEN0.SYSCLK_DIV = 0;
  241. SCU->SCLKEN0.CLK_SEL = CLK_SEL;
  242. SCU_RegLock();
  243. }
  244. /***************************************************************
  245. 函数名:PLLClock_Config
  246. 描 述:PLL时钟配置,并设置PLL时钟为系统时钟
  247. 输入值:pll_en:是否开启PLL,pll_origin:pll时钟源选择,pll_out:pll输出频率选择,sys_pll:系统时钟是否使用PLL时钟
  248. 输出值:无
  249. 返回值:无
  250. ***************************************************************/
  251. void PLLClock_Config(TYPE_FUNCEN pll_en , SCU_PLL_Origin pll_origin ,SCU_PLL_Out pll_out,TYPE_FUNCEN sys_pll)
  252. {
  253. SCU_RegUnLock();
  254. if(pll_en == DISABLE) //如果PLL配置为禁止,则直接禁止PLL,并返回
  255. {
  256. SCU->SCLKEN0.PLL_MUX = 0;
  257. SCU->SCLKEN1.PLL_BYLOCK = 0;
  258. SCU->SCLKEN0.CLKFLT_BY = 0x00;
  259. SCU->SCLKEN1.PLL_EN = 0;
  260. return;
  261. }
  262. if((pll_origin == SCU_PLL_HRC)) //如果使用内部高速时钟,需开启内部高速时钟
  263. {
  264. if(SCU->SCLKEN1.HRC_RDY == 0)
  265. {
  266. SCU->SCLKEN1.HRC_EN = 1;
  267. while(SCU->SCLKEN1.HRC_RDY == 0); //等待HRC开启
  268. }
  269. }
  270. if((pll_origin == SCU_PLL_XTAL_32K)
  271. || (pll_origin == SCU_PLL_XTAL_4M)
  272. ||(pll_origin == SCU_PLL_XTAL_8M)
  273. || (pll_origin == SCU_PLL_XTAL_16M)
  274. || (pll_origin == SCU_PLL_XTAL_20M)) //如果使用外部时钟,需开启外部时钟
  275. {
  276. if(SCU->SCLKEN1.XTAL_RDY == 0)
  277. {
  278. SCU->SCLKEN1.XTAL_EN = 1;
  279. SCU->SCLKEN0.XTAL_LP = 0;
  280. while(SCU->SCLKEN1.XTAL_RDY == 0); //等待XTAL开启
  281. }
  282. }
  283. switch(pll_origin)
  284. {
  285. case SCU_PLL_HRC:
  286. SCU->SCLKEN1.PLL_REF_SEL = 0x00;
  287. break;
  288. case SCU_PLL_LRC:
  289. SCU->SCLKEN1.PLL_REF_SEL = 0x02;
  290. break;
  291. case SCU_PLL_XTAL_32K:
  292. SCU->SCLKEN1.PLL_REF_SEL = 0x03;
  293. break;
  294. case SCU_PLL_XTAL_4M:
  295. SCU->SCLKEN1.PLL_REF_SEL = 0x04;
  296. break;
  297. case SCU_PLL_XTAL_8M:
  298. SCU->SCLKEN1.PLL_REF_SEL = 0x05;
  299. break;
  300. case SCU_PLL_XTAL_16M:
  301. SCU->SCLKEN1.PLL_REF_SEL = 0x06;
  302. break;
  303. case SCU_PLL_XTAL_20M:
  304. SCU->SCLKEN1.PLL_REF_SEL = 0x07;
  305. break;
  306. default:
  307. break;
  308. }
  309. SCU->SCLKEN1.PLL_48M_SEL = pll_out; //配置PLL输出为32或48Mhz
  310. SCU->SCLKEN1.PLL_EN = 1;
  311. while(SCU->SCLKEN1.PLL_RDY == 0);
  312. if(sys_pll == ENABLE)
  313. {
  314. if(pll_out == SCU_PLL_32M)
  315. {
  316. SCU->SCLKEN0.CLKFLT_BY = 0;
  317. }
  318. else
  319. {
  320. SCU->SCLKEN0.CLKFLT_BY = 0x55; //48M 时钟滤波旁路
  321. }
  322. SCU->SCLKEN1.PLL_BYLOCK = 1;
  323. SCU->SCLKEN0.PLL_MUX = 1;
  324. }
  325. else
  326. {
  327. SCU->SCLKEN0.PLL_MUX = 0;
  328. SCU->SCLKEN1.PLL_BYLOCK = 0;
  329. SCU->SCLKEN0.CLKFLT_BY = 0x00;
  330. }
  331. SCU_RegLock();
  332. }
  333. /*************************END OF FILE**********************/