25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

136 lines
4.1 KiB

  1. #include "sys.h"
  2. //////////////////////////////////////////////////////////////////////////////////
  3. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  4. //ALIENTEK STM32F7开发板
  5. //系统时钟初始化
  6. //正点原子@ALIENTEK
  7. //技术论坛:www.openedv.com
  8. //创建日期:2015/6/10
  9. //版本:V1.0
  10. //版权所有,盗版必究。
  11. //Copyright(C) 广州市星翼电子科技有限公司 2014-2024
  12. //All rights reserved
  13. //********************************************************************************
  14. //修改说明
  15. //无
  16. //////////////////////////////////////////////////////////////////////////////////
  17. //使能CPU的L1-Cache
  18. void Cache_Enable(void)
  19. {
  20. SCB_EnableICache();//使能I-Cache
  21. SCB_EnableDCache();//使能D-Cache
  22. SCB->CACR|=1<<2; //强制D-Cache透写,如不开启,实际使用中可能遇到各种问题
  23. }
  24. //时钟设置函数
  25. //Fvco=Fs*(plln/pllm);
  26. //Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));
  27. //Fusb=Fvco/pllq=Fs*(plln/(pllm*pllq));
  28. //Fvco:VCO频率
  29. //Fsys:系统时钟频率
  30. //Fusb:USB,SDIO,RNG等的时钟频率
  31. //Fs:PLL输入时钟频率,可以是HSI,HSE等.
  32. //plln:主PLL倍频系数(PLL倍频),取值范围:64~432.
  33. //pllm:主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63.
  34. //pllp:系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2,4,6,8.(仅限这4个值!)
  35. //pllq:USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:2~15.
  36. //外部晶振为25M的时候,推荐值:plln=432,pllm=25,pllp=2,pllq=9.
  37. //得到:Fvco=25*(432/25)=432Mhz
  38. // Fsys=432/2=216Mhz
  39. // Fusb=432/9=48Mhz
  40. //返回值:0,成功;1,失败
  41. void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq)
  42. {
  43. HAL_StatusTypeDef ret = HAL_OK;
  44. RCC_OscInitTypeDef RCC_OscInitStructure;
  45. RCC_ClkInitTypeDef RCC_ClkInitStructure;
  46. __HAL_RCC_PWR_CLK_ENABLE(); //使能PWR时钟
  47. __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//设置调压器输出电压级别,以便在器件未以最大频率工作
  48. RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE; //时钟源为HSE
  49. RCC_OscInitStructure.HSEState=RCC_HSE_ON; //打开HSE
  50. RCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON; //打开PLL
  51. RCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE; //PLL时钟源选择HSE
  52. RCC_OscInitStructure.PLL.PLLM=pllm; //主PLL和音频PLL分频系数(PLL之前的分频)
  53. RCC_OscInitStructure.PLL.PLLN=plln; //主PLL倍频系数(PLL倍频)
  54. RCC_OscInitStructure.PLL.PLLP=pllp; //系统时钟的主PLL分频系数(PLL之后的分频)
  55. RCC_OscInitStructure.PLL.PLLQ=pllq; //USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频)
  56. ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化
  57. if(ret!=HAL_OK) while(1);
  58. ret=HAL_PWREx_EnableOverDrive(); //开启Over-Driver功能
  59. if(ret!=HAL_OK) while(1);
  60. //选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2
  61. RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);
  62. RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;//设置系统时钟时钟源为PLL
  63. RCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;//AHB分频系数为1
  64. RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4;//APB1分频系数为4
  65. RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2;//APB2分频系数为2
  66. ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_7);//同时设置FLASH延时周期为7WS,也就是8个CPU周期。
  67. if(ret!=HAL_OK) while(1);
  68. }
  69. #ifdef USE_FULL_ASSERT
  70. //当编译提示出错的时候此函数用来报告错误的文件和所在行
  71. //file:指向源文件
  72. //line:指向在文件中的行数
  73. void assert_failed(uint8_t* file, uint32_t line)
  74. {
  75. while (1)
  76. {
  77. }
  78. }
  79. #endif
  80. //判断I_Cache是否打开
  81. //返回值:0 关闭,1 打开
  82. u8 Get_ICahceSta(void)
  83. {
  84. u8 sta;
  85. sta=((SCB->CCR)>>17)&0X01;
  86. return sta;
  87. }
  88. //判断I_Dache是否打开
  89. //返回值:0 关闭,1 打开
  90. u8 Get_DCahceSta(void)
  91. {
  92. u8 sta;
  93. sta=((SCB->CCR)>>16)&0X01;
  94. return sta;
  95. }
  96. //THUMB指令不支持汇编内联
  97. //采用如下方法实现执行汇编指令WFI
  98. void WFI_SET(void)
  99. {
  100. asm("WFI");
  101. }
  102. //关闭所有中断(但是不包括fault和NMI中断)
  103. void INTX_DISABLE(void)
  104. {
  105. asm("CPSID I");
  106. asm("BX LR");
  107. }
  108. //开启所有中断
  109. void INTX_ENABLE(void)
  110. {
  111. asm("CPSIE I");
  112. asm("BX LR");
  113. }
  114. //设置栈顶地址
  115. //addr:栈顶地址
  116. void MSR_MSP(u32 addr)
  117. {
  118. asm("MSR MSP, r0"); //set Main Stack value
  119. asm("BX r14");
  120. }