396 lines
10 KiB
C
396 lines
10 KiB
C
#include "sys.h"
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
|
||
|
||
//STM32H7开发板
|
||
//系统时钟初始化
|
||
|
||
//STM32H7工程模板-HAL库函数版本
|
||
//DevEBox 大越创新
|
||
//淘宝店铺:mcudev.taobao.com
|
||
//淘宝店铺:shop389957290.taobao.com
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////
|
||
|
||
|
||
|
||
/*******************************************************************************/
|
||
|
||
//使能CPU的L1-Cache
|
||
|
||
//STM32H7工程模板-HAL库函数版本
|
||
//DevEBox 大越创新
|
||
//淘宝店铺:mcudev.taobao.com
|
||
//淘宝店铺:shop389957290.taobao.com
|
||
|
||
/*******************************************************************************/
|
||
|
||
void Cache_Enable(void)
|
||
{
|
||
SCB_EnableICache();//使能I-Cache
|
||
SCB_EnableDCache();//使能D-Cache
|
||
SCB->CACR|=1<<2; //强制D-Cache透写,如不开启,实际使用中可能遇到各种问题
|
||
}
|
||
|
||
|
||
|
||
|
||
/*******************************************************************************/
|
||
|
||
//时钟设置函数
|
||
//Fvco=Fs*(plln/pllm);
|
||
//Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));
|
||
//Fq=Fvco/pllq=Fs*(plln/(pllm*pllq));
|
||
|
||
//Fvco:VCO频率
|
||
//Fsys:系统时钟频率,也是PLL1的p分频输出时钟频率
|
||
//Fq:PLL1的q分频输出时钟频率
|
||
//Fs:PLL输入时钟频率,可以是HSI,CSI,HSE等.
|
||
|
||
//plln:PLL1倍频系数(PLL倍频),取值范围:4~512.
|
||
//pllm:PLL1预分频系数(进PLL之前的分频),取值范围:2~63.
|
||
//pllp:PLL1的p分频系数(PLL之后的分频),分频后作为系统时钟,取值范围:2~128.(且必须是2的倍数)
|
||
//pllq:PLL1的q分频系数(PLL之后的分频),取值范围:1~128.
|
||
|
||
//CPU频率(rcc_c_ck)=sys_d1cpre_ck=400Mhz
|
||
//rcc_aclk=rcc_hclk3=200Mhz
|
||
//AHB1/2/3/4(rcc_hclk1/2/3/4)=200Mhz
|
||
//APB1/2/3/4(rcc_pclk1/2/3/4)=100Mhz
|
||
//FMC时钟频率=pll2_r_ck=((25/25)*512/2)=256Mhz
|
||
|
||
//外部晶振为25M的时候,推荐值:plln=160,pllm=5,pllp=2,pllq=2.
|
||
//得到:Fvco=25*(160/5)=800Mhz
|
||
// Fsys=800/2=400Mhz
|
||
// Fq=800/2=400Mhz
|
||
//返回值:0,成功;1,失败。
|
||
|
||
//STM32H7工程模板-HAL库函数版本
|
||
//DevEBox 大越创新
|
||
//淘宝店铺:mcudev.taobao.com
|
||
//淘宝店铺:shop389957290.taobao.com
|
||
|
||
/*******************************************************************************/
|
||
|
||
u8 Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq)
|
||
{
|
||
HAL_StatusTypeDef ret=HAL_OK;
|
||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||
RCC_OscInitTypeDef RCC_OscInitStruct;
|
||
|
||
MODIFY_REG(PWR->CR3,PWR_CR3_SCUEN, 0);
|
||
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
|
||
|
||
while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {}
|
||
|
||
RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_HSE;
|
||
RCC_OscInitStruct.HSEState=RCC_HSE_ON;
|
||
RCC_OscInitStruct.HSIState=RCC_HSI_OFF;
|
||
RCC_OscInitStruct.CSIState=RCC_CSI_OFF;
|
||
RCC_OscInitStruct.PLL.PLLState=RCC_PLL_ON;
|
||
RCC_OscInitStruct.PLL.PLLSource=RCC_PLLSOURCE_HSE;
|
||
|
||
RCC_OscInitStruct.PLL.PLLN=plln;
|
||
RCC_OscInitStruct.PLL.PLLM=pllm;
|
||
RCC_OscInitStruct.PLL.PLLP=pllp;
|
||
RCC_OscInitStruct.PLL.PLLQ=pllq;
|
||
|
||
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
|
||
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
|
||
ret=HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
||
if(ret!=HAL_OK) return 1;
|
||
|
||
//QSPI_Enable_Memmapmode(); //QSPI内存映射模式,需要在时钟初始化之前开启,否则会有各种问题
|
||
|
||
RCC_ClkInitStruct.ClockType=(RCC_CLOCKTYPE_SYSCLK|\
|
||
RCC_CLOCKTYPE_HCLK |\
|
||
RCC_CLOCKTYPE_D1PCLK1 |\
|
||
RCC_CLOCKTYPE_PCLK1 |\
|
||
RCC_CLOCKTYPE_PCLK2 |\
|
||
RCC_CLOCKTYPE_D3PCLK1);
|
||
|
||
RCC_ClkInitStruct.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;
|
||
RCC_ClkInitStruct.SYSCLKDivider=RCC_SYSCLK_DIV1;
|
||
RCC_ClkInitStruct.AHBCLKDivider=RCC_HCLK_DIV2;
|
||
RCC_ClkInitStruct.APB1CLKDivider=RCC_APB1_DIV2;
|
||
RCC_ClkInitStruct.APB2CLKDivider=RCC_APB2_DIV2;
|
||
RCC_ClkInitStruct.APB3CLKDivider=RCC_APB3_DIV2;
|
||
RCC_ClkInitStruct.APB4CLKDivider=RCC_APB4_DIV4;
|
||
ret=HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
|
||
if(ret!=HAL_OK) return 1;
|
||
|
||
__HAL_RCC_CSI_ENABLE() ;
|
||
__HAL_RCC_SYSCFG_CLK_ENABLE() ;
|
||
HAL_EnableCompensationCell();
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
#ifdef USE_FULL_ASSERT
|
||
|
||
|
||
//当编译提示出错的时候此函数用来报告错误的文件和所在行
|
||
//file:指向源文件
|
||
//line:指向在文件中的行数
|
||
|
||
|
||
void assert_failed(uint8_t* file, uint32_t line)
|
||
{
|
||
while (1)
|
||
{
|
||
}
|
||
}
|
||
|
||
|
||
#endif
|
||
|
||
|
||
/*******************************************************************************/
|
||
|
||
//判断I_Cache是否打开
|
||
//返回值:0 关闭,1 打开
|
||
|
||
|
||
//STM32H7工程模板-HAL库函数版本
|
||
//DevEBox 大越创新
|
||
//淘宝店铺:mcudev.taobao.com
|
||
//淘宝店铺:shop389957290.taobao.com
|
||
|
||
/*******************************************************************************/
|
||
u8 Get_ICahceSta(void)
|
||
{
|
||
u8 sta;
|
||
sta=((SCB->CCR)>>17)&0X01;
|
||
return sta;
|
||
}
|
||
|
||
|
||
/*******************************************************************************/
|
||
|
||
|
||
//判断I_Dache是否打开
|
||
//返回值:0 关闭,1 打开
|
||
|
||
//STM32H7工程模板-HAL库函数版本
|
||
//DevEBox 大越创新
|
||
//淘宝店铺:mcudev.taobao.com
|
||
//淘宝店铺:shop389957290.taobao.com
|
||
|
||
/*******************************************************************************/
|
||
|
||
u8 Get_DCahceSta(void)
|
||
{
|
||
u8 sta;
|
||
sta=((SCB->CCR)>>16)&0X01;
|
||
return sta;
|
||
}
|
||
|
||
|
||
/*******************************************************************************/
|
||
|
||
|
||
//QSPI进入内存映射模式(执行QSPI代码必备前提,为了减少引入的文件,
|
||
//除了GPIO驱动外,其他的外设驱动均采用寄存器形式)
|
||
|
||
//STM32H7工程模板-HAL库函数版本
|
||
//DevEBox 大越创新
|
||
//淘宝店铺:mcudev.taobao.com
|
||
//淘宝店铺:shop389957290.taobao.com
|
||
|
||
/*******************************************************************************/
|
||
|
||
void QSPI_Enable_Memmapmode(void)
|
||
{
|
||
u32 tempreg=0;
|
||
vu32 *data_reg=&QUADSPI->DR;
|
||
GPIO_InitTypeDef qspi_gpio;
|
||
|
||
RCC->AHB4ENR|=1<<1; //使能PORTB时钟
|
||
RCC->AHB4ENR|=1<<5; //使能PORTF时钟
|
||
RCC->AHB3ENR|=1<<14; //QSPI时钟使能
|
||
|
||
qspi_gpio.Pin=GPIO_PIN_6; //PB6 AF10
|
||
qspi_gpio.Mode=GPIO_MODE_AF_PP;
|
||
qspi_gpio.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
|
||
qspi_gpio.Pull=GPIO_NOPULL;
|
||
qspi_gpio.Alternate=GPIO_AF10_QUADSPI;
|
||
HAL_GPIO_Init(GPIOB,&qspi_gpio);
|
||
|
||
qspi_gpio.Pin=GPIO_PIN_2; //PB2 AF9
|
||
qspi_gpio.Alternate=GPIO_AF9_QUADSPI;
|
||
HAL_GPIO_Init(GPIOB,&qspi_gpio);
|
||
|
||
qspi_gpio.Pin=GPIO_PIN_6|GPIO_PIN_7; //PF6,7 AF9
|
||
qspi_gpio.Alternate=GPIO_AF9_QUADSPI;
|
||
HAL_GPIO_Init(GPIOF,&qspi_gpio);
|
||
|
||
qspi_gpio.Pin=GPIO_PIN_8|GPIO_PIN_9; //PF8,9 AF10
|
||
qspi_gpio.Alternate=GPIO_AF10_QUADSPI;
|
||
HAL_GPIO_Init(GPIOF,&qspi_gpio);
|
||
|
||
//QSPI设置,参考QSPI实验的QSPI_Init函数
|
||
RCC->AHB3RSTR|=1<<14; //复位QSPI
|
||
RCC->AHB3RSTR&=~(1<<14); //停止复位QSPI
|
||
while(QUADSPI->SR&(1<<5)); //等待BUSY位清零
|
||
QUADSPI->CR=0X01000310; //设置CR寄存器,这些值怎么来的,请参考QSPI实验/看H750参考手册寄存器描述分析
|
||
QUADSPI->DCR=0X00160401; //设置DCR寄存器
|
||
QUADSPI->CR|=1<<0; //使能QSPI
|
||
|
||
//注意:QSPI QE位的使能,在QSPI烧写算法里面,就已经设置了
|
||
//所以,这里可以不用设置QE位,否则需要加入对QE位置1的代码
|
||
//不过,代码必须通过仿真器下载,直接烧录到外部QSPI FLASH,是不可用的
|
||
//如果想直接烧录到外部QSPI FLASH也可以用,则需要在这里添加QE位置1的代码
|
||
|
||
//W25QXX进入QPI模式(0X38指令)
|
||
while(QUADSPI->SR&(1<<5)); //等待BUSY位清零
|
||
QUADSPI->CCR=0X00000138; //发送0X38指令,W25QXX进入QPI模式
|
||
while((QUADSPI->SR&(1<<1))==0); //等待指令发送完成
|
||
QUADSPI->FCR|=1<<1; //清除发送完成标志位
|
||
|
||
//W25QXX写使能(0X06指令)
|
||
while(QUADSPI->SR&(1<<5)); //等待BUSY位清零
|
||
QUADSPI->CCR=0X00000106; //发送0X06指令,W25QXX写使能
|
||
while((QUADSPI->SR&(1<<1))==0); //等待指令发送完成
|
||
QUADSPI->FCR|=1<<1; //清除发送完成标志位
|
||
|
||
//W25QXX设置QPI相关读参数(0XC0)
|
||
while(QUADSPI->SR&(1<<5)); //等待BUSY位清零
|
||
QUADSPI->CCR=0X030003C0; //发送0XC0指令,W25QXX读参数设置
|
||
QUADSPI->DLR=0;
|
||
while((QUADSPI->SR&(1<<2))==0); //等待FTF
|
||
*(vu8 *)data_reg=3<<4; //设置P4&P5=11,8个dummy clocks,104M
|
||
QUADSPI->CR|=1<<2; //终止传输
|
||
while((QUADSPI->SR&(1<<1))==0); //等待数据发送完成
|
||
QUADSPI->FCR|=1<<1; //清除发送完成标志位
|
||
while(QUADSPI->SR&(1<<5)); //等待BUSY位清零
|
||
|
||
//MemroyMap 模式设置
|
||
while(QUADSPI->SR&(1<<5)); //等待BUSY位清零
|
||
QUADSPI->ABR=0; //交替字节设置为0,实际上就是W25Q 0XEB指令的,M0~M7=0
|
||
tempreg=0XEB; //INSTRUCTION[7:0]=0XEB,发送0XEB指令(Fast Read QUAD I/O)
|
||
tempreg|=3<<8; //IMODE[1:0]=3,四线传输指令
|
||
tempreg|=3<<10; //ADDRESS[1:0]=3,四线传输地址
|
||
tempreg|=2<<12; //ADSIZE[1:0]=2,24位地址长度
|
||
tempreg|=3<<14; //ABMODE[1:0]=3,四线传输交替字节
|
||
tempreg|=0<<16; //ABSIZE[1:0]=0,8位交替字节(M0~M7)
|
||
tempreg|=6<<18; //DCYC[4:0]=6,6个dummy周期
|
||
tempreg|=3<<24; //DMODE[1:0]=3,四线传输数据
|
||
tempreg|=3<<26; //FMODE[1:0]=3,内存映射模式
|
||
QUADSPI->CCR=tempreg; //设置CCR寄存器
|
||
|
||
//设置QSPI FLASH空间的MPU保护
|
||
SCB->SHCSR&=~(1<<16); //禁止MemManage
|
||
MPU->CTRL&=~(1<<0); //禁止MPU
|
||
MPU->RNR=0; //设置保护区域编号为0(1~7可以给其他内存用)
|
||
MPU->RBAR=0X90000000; //基地址为0X9000 000,即QSPI的起始地址
|
||
MPU->RASR=0X0303002D; //设置相关保护参数(禁止共用,允许cache,允许缓冲),详见MPU实验的解析
|
||
MPU->CTRL=(1<<2)|(1<<0); //使能PRIVDEFENA,使能MPU
|
||
SCB->SHCSR|=1<<16; //使能MemManage
|
||
}
|
||
|
||
|
||
|
||
|
||
/*******************************************************************************/
|
||
|
||
//STM32H7工程模板-HAL库函数版本
|
||
//DevEBox 大越创新
|
||
//淘宝店铺:mcudev.taobao.com
|
||
//淘宝店铺:shop389957290.taobao.com
|
||
|
||
/*******************************************************************************/
|
||
|
||
#if defined(__clang__) //使用V6编译器(clang)
|
||
//THUMB指令不支持汇编内联
|
||
//采用如下方法实现执行汇编指令WFI
|
||
void __attribute__((noinline)) WFI_SET(void)
|
||
{
|
||
__asm__("wfi");
|
||
}
|
||
|
||
//关闭所有中断(但是不包括fault和NMI中断)
|
||
void __attribute__((noinline)) INTX_DISABLE(void)
|
||
{
|
||
__asm__("cpsid i \t\n"
|
||
"bx lr");
|
||
}
|
||
|
||
//开启所有中断
|
||
void __attribute__((noinline)) INTX_ENABLE(void)
|
||
{
|
||
__asm__("cpsie i \t\n"
|
||
"bx lr");
|
||
}
|
||
|
||
//设置栈顶地址
|
||
//addr:栈顶地址
|
||
void __attribute__((noinline)) MSR_MSP(u32 addr)
|
||
{
|
||
__asm__("msr msp, r0 \t\n"
|
||
"bx r14");
|
||
}
|
||
#elif defined (__CC_ARM) //使用V5编译器(ARMCC)
|
||
|
||
//THUMB指令不支持汇编内联
|
||
//采用如下方法实现执行汇编指令WFI
|
||
__asm void WFI_SET(void)
|
||
{
|
||
WFI;
|
||
}
|
||
//关闭所有中断(但是不包括fault和NMI中断)
|
||
__asm void INTX_DISABLE(void)
|
||
{
|
||
CPSID I
|
||
BX LR
|
||
}
|
||
//开启所有中断
|
||
__asm void INTX_ENABLE(void)
|
||
{
|
||
CPSIE I
|
||
BX LR
|
||
}
|
||
//设置栈顶地址
|
||
//addr:栈顶地址
|
||
__asm void MSR_MSP(u32 addr)
|
||
{
|
||
MSR MSP, r0 //set Main Stack value
|
||
BX r14
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*******************************************************************************/
|
||
|
||
//STM32H7工程模板-HAL库函数版本
|
||
//DevEBox 大越创新
|
||
//淘宝店铺:mcudev.taobao.com
|
||
//淘宝店铺:shop389957290.taobao.com
|
||
|
||
/*******************************************************************************/
|
||
|
||
|
||
|
||
|
||
|
||
|