sys_api.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "sys_type.h"
  2. #include "sys_api.h"
  3. //////////////////////////////////////////////////////////////////////////////////
  4. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  5. //ALIENTEK STM32H7开发板
  6. //系统时钟初始化
  7. //正点原子@ALIENTEK
  8. //技术论坛:www.openedv.com
  9. //创建日期:2017/6/8
  10. //版本:V1.0
  11. //版权所有,盗版必究。
  12. //Copyright(C) 广州市星翼电子科技有限公司 2014-2024
  13. //All rights reserved
  14. //********************************************************************************
  15. //修改说明
  16. //无
  17. //////////////////////////////////////////////////////////////////////////////////
  18. //使能CPU的L1-Cache
  19. void Cache_Enable(void)
  20. {
  21. SCB_EnableICache();//使能I-Cache
  22. SCB_EnableDCache();//使能D-Cache
  23. SCB->CACR|=1<<2; //强制D-Cache透写,如不开启,实际使用中可能遇到各种问题
  24. }
  25. //时钟设置函数
  26. //Fvco=Fs*(plln/pllm);
  27. //Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));
  28. //Fq=Fvco/pllq=Fs*(plln/(pllm*pllq));
  29. //Fvco:VCO频率
  30. //Fsys:系统时钟频率,也是PLL1的p分频输出时钟频率
  31. //Fq:PLL1的q分频输出时钟频率
  32. //Fs:PLL输入时钟频率,可以是HSI,CSI,HSE等.
  33. //plln:PLL1倍频系数(PLL倍频),取值范围:4~512.
  34. //pllm:PLL1预分频系数(进PLL之前的分频),取值范围:2~63.
  35. //pllp:PLL1的p分频系数(PLL之后的分频),分频后作为系统时钟,取值范围:2~128.(且必须是2的倍数)
  36. //pllq:PLL1的q分频系数(PLL之后的分频),取值范围:1~128.
  37. //CPU频率(rcc_c_ck)=sys_d1cpre_ck=400Mhz
  38. //rcc_aclk=rcc_hclk3=200Mhz
  39. //AHB1/2/3/4(rcc_hclk1/2/3/4)=200Mhz
  40. //APB1/2/3/4(rcc_pclk1/2/3/4)=100Mhz
  41. //FMC时钟频率=pll2_r_ck=((25/25)*512/2)=256Mhz
  42. //外部晶振为25M的时候,推荐值:plln=160,pllm=5,pllp=2,pllq=2.
  43. //得到:Fvco=25*(160/5)=800Mhz
  44. // Fsys=800/2=400Mhz
  45. // Fq=800/2=400Mhz
  46. //返回值:0,成功;1,失败。
  47. #ifdef USE_FULL_ASSERT
  48. //当编译提示出错的时候此函数用来报告错误的文件和所在行
  49. //file:指向源文件
  50. //line:指向在文件中的行数
  51. void assert_failed(uint8_t* file, uint32_t line)
  52. {
  53. while (1)
  54. {
  55. }
  56. }
  57. #endif
  58. //判断I_Cache是否打开
  59. //返回值:0 关闭,1 打开
  60. u8 Get_ICahceSta(void)
  61. {
  62. u8 sta;
  63. sta=((SCB->CCR)>>17)&0X01;
  64. return sta;
  65. }
  66. //判断I_Dache是否打开
  67. //返回值:0 关闭,1 打开
  68. u8 Get_DCahceSta(void)
  69. {
  70. u8 sta;
  71. sta=((SCB->CCR)>>16)&0X01;
  72. return sta;
  73. }
  74. #if defined(__clang__) //使用V6编译器(clang)
  75. //THUMB指令不支持汇编内联
  76. //采用如下方法实现执行汇编指令WFI
  77. void __attribute__((noinline)) WFI_SET(void)
  78. {
  79. __asm__("wfi");
  80. }
  81. //关闭所有中断(但是不包括fault和NMI中断)
  82. void __attribute__((noinline)) INTX_DISABLE(void)
  83. {
  84. __asm__("cpsid i \t\n"
  85. "bx lr");
  86. }
  87. //开启所有中断
  88. void __attribute__((noinline)) INTX_ENABLE(void)
  89. {
  90. __asm__("cpsie i \t\n"
  91. "bx lr");
  92. }
  93. //设置栈顶地址
  94. //addr:栈顶地址
  95. void __attribute__((noinline)) MSR_MSP(u32 addr)
  96. {
  97. __asm__("msr msp, r0 \t\n"
  98. "bx r14");
  99. }
  100. #elif defined (__CC_ARM) //使用V5编译器(ARMCC)
  101. //THUMB指令不支持汇编内联
  102. //采用如下方法实现执行汇编指令WFI
  103. __asm void WFI_SET(void)
  104. {
  105. WFI;
  106. }
  107. //关闭所有中断(但是不包括fault和NMI中断)
  108. __asm void INTX_DISABLE(void)
  109. {
  110. CPSID I
  111. BX LR
  112. }
  113. //开启所有中断
  114. __asm void INTX_ENABLE(void)
  115. {
  116. CPSIE I
  117. BX LR
  118. }
  119. //设置栈顶地址
  120. //addr:栈顶地址
  121. __asm void MSR_MSP(u32 addr)
  122. {
  123. MSR MSP, r0 //set Main Stack value
  124. BX r14
  125. }
  126. #endif