RT1052的介绍及MDK

news2024/10/7 6:45:30

文章目录

  • RT1052 核心板的资源
    • 型号为:RT1052CVL5B。
    • GPIO端口原理
    • LDO
    • EEPROM
  • 复位电路
  • 启动模式设置电路
    • BootLoader地址
  • 开发环境搭建
    • 新建 基于 FSL 库的 MDK5 工程
      • 软件
      • 下载SDK包
      • SDK包内容
        • boards 文件夹
        • CMSIS 文件夹
        • devices 文件夹
        • middleware 文件夹:
    • 新建工程注意
      • 型号
  • 初始化配置
    • MPU_Memory_Protection
    • RT1052_Clock_Init
      • CLOCK_SetXtalFreq() 和 CLOCK_SetRtcXtalFreq() 函数
    • CLOCK_SetMux()
    • CLOCK_SetDiv()
    • CLOCK_InitXXXPll() 函数
    • CLOCK_InitSysPfd()和 和 CLOCK_InitUsb1Pfd 函数
    • CLOCK_EnableClock() 和 CLOCK_DisableClock()
    • SystemCoreClockUpdate 函数

RT1052 核心板的资源

型号为:RT1052CVL5B。

  • 该芯片采用六级流水线
  • 自带指令和数据 Cache
  • 集成双精度硬件浮点计算单元(DPFPU)和 DSP 指令
  • 具有 512KB SRAM
  • 2个通用定时器(GPT)
  • 4 个周期定时器(PIT)
  • 4 个四定时器(QTIMER)
  • 4 个 FlexPWM
  • 1个 eDMA 控制器(32 个通道)
  • 2 个 FlexSPI
  • 4 个 SPI
  • 2 个看门狗
  • 3 个 SAI
  • 4 个 IIC
  • 8 个串口
  • 2 个 USB(高速,带 PHY)
  • 2 个 FlexCAN
  • 2 个 12 位 ADC
  • 1 个 SPDIF 接口
  • 2 个RTC
  • 2 个 USDHC 接口
  • 1 个 SEMC 接口
  • 1 个 TFTLCD 控制器(ELCDIF)
  • 1 个 10/100M以太网 MAC 控制器
  • 1 个摄像头接口
  • 1 个硬件随机数生成器
  • 127 个通用 IO 口。

芯片主频高达 528Mhz(可超频到 600Mhz)

GPIO端口原理

RT1052 的 IO 口总共分成 5 组:GPIO1~GPIO5

  • 其中:GPIO1、GPIO2 和 GPIO4 每组 32个 IO,GPIO3 只有 28 个 IO,GPIO5 最少,只有 3 个 IO,这样总共是 127 个 IO 口

LDO

自带的 LDO 稳压芯片(U5),型号为:RT9013-33GB,支持 500mA 大电流输出,小体积,低噪声,保证了 RT1052 电源的纯净,有利于核心板稳定运行。

EEPROM

板载的 EEPROM 芯片(U3),型号为:24C02,容量为 2Kb,也就是 256 字节。
用于存储一些掉电不能丢失的重要数据

复位电路

在这里插入图片描述
RT1052 是低电平复位的,上拉电阻和上电复位电容,在转接板上面带了
在这里插入图片描述
R1 和 C3,就是上拉电阻和上电复位电容

启动模式设置电路

在这里插入图片描述启动模式是通过 BOOT_MODE0(即 GPIO1_IO04)和 BOOT_MODE1(即 GPIO1_IO05)来设置。启动模式选择如下:
在这里插入图片描述

  • 注 1,eFUSE 是指 RT1052 内部的熔丝,从 0X400 开始~到 0X6F0 结束,熔丝是一次性设置的(设置完以后,无法再改回来),所以不要乱写,否则可能写死芯片。
  • 注 2,RT1052 内部有 96KB 的 BOOT ROM,出厂时已经有固化的启动代码在里面了,这部分 ROM 没有对用户开放,所以我们是无法使用的。
  • RT1052 如果需要正常运行代码,必须设置 BOOT_MODE[1:0]=00/10,而 00 和 10 这两种方式,非常相似,通过对熔丝的设置(BT_FUSE_SEL=1),10 完全可以替代00 的功能。
  • BOOT_MODE[1:0]=01,是 USB 下载模式,此模式仅用于 USB(USB1)下载代码,下载完成后,必须设置成 00/10,否则代码是没办法正常运行的。
    • 当 BOOT_MODE[1:0]=10,且仿真器下载代码出错时,则可以通过设置BOOT_MODE[1:0]=01 进入 USB 下载模式,从而重新下载代码,达到恢复下载的目的。

一般只要用到BOOT_MODE1:0]=01/10 这两个设置即可,刚好两个位是相反的,在开发板上设计有一个反相电路,只需要控制 BOOT_MODE[0],就可以达到同时设置BOOT_MODE[1]的目的。
在这里插入图片描述 BOOT_MODE[1:0]设置好了,RT1052 的启动过程,还要通过 BOOT_CFG1[0~7] 和 BOOT_CFG2[0~3]来决定具体从哪个器件启动以及相关参数。
在这里插入图片描述BOOT_CFG1[0~7]和 BOOT_CFG2[0~3]的设置是可以通过 eFUSE 和 GPIO 两种方式来决定的,我们一般通过 GPIO 设置(也可以通过 eFUSE 设置,不过 eFUSE 设置以后,无法再修改,请谨慎选择!) GPIO 配置的这部分电路在转接板上
在这里插入图片描述BOOT_CFG1[0~7]和 BOOT_CFG2[0~3]全部接了下拉电阻,也就是全部设置为 0。
这样,当我们设置 BOOT_MODE[1:0]=10 的时候,BOOT_CFG1[7:4]=0000,即:选择从 SPI FLASH 启动代码(SPI FLASH 地址:0X6000 0000)。

BootLoader地址

__disable_irq();
SCB->VTOR = flash_app_state_address;//将中断向量指向app地址
__enable_irq(); 

复制中断向量到新的地址。
BOOTLoader笔记

开发环境搭建

在 MDK5 安装完成后,要安装 RT1052 的器件支持包:

  • NXP.MIMXRT1052_DFP.10.0.1.pack (RT1052 系列的器件包)。
  • 还需要将 RT1052 的 FLASH下载 算法(MIMXRT105x_QuadSPI_4KB_SEC.FLM ),拷贝到 MDK 安装路径 →ARM →Flash文件夹里面。
  • MDK5.23、RT1052 器件包和 RT1052 Flash 下载算法(见:光盘资料→6,软件资料→1,软件→MDK5 文件夹)

新建 基于 FSL 库的 MDK5 工程

软件

MCUXpresso_Config_Tools_V2_64.exe

下载SDK包

SDK 可以在 NXP 的官网下载到,下载地址。

  • NXP 官方的 SDK 是针对 NXP 自己的 RT1050-EVK 开发板写的,所以在选择 Boards 的时候选择 NXP 官方的 RT1052 开发板,如果需要下载 NXP 其他
    型号的 MCU SDK 的时候就选择相应的 Boards
    在这里插入图片描述跳转到
    在这里插入图片描述进一步配置 SDK,比如开发主机系统:是 windows 还是 linux?所使用的 IDE 环境:是 KEIL、IAR 还是 GCC?是否需要第三方组件?都需要些啥组件等等,配置好以后点击下面的“Request Build”
    在这里插入图片描述SDK包下载
    在这里插入图片描述

  • 也可光盘资料→8,RT1052 参考资料→2,RT1052 官方 SDK→SDK_2.3.1_EVKB-IMXRT1050

  • 用过SDK_2_10_0 MIMXRT1060_EVKB

SDK包内容

在这里插入图片描述NXP 官方的 SDK 包一共有 7 个文件夹和 3 个其他文件
在这里插入图片描述

boards 文件夹

NXP 针对 RT1050 系列 MCU 写的一些例程
在这里插入图片描述NXP 提供的例程共有 8 种,有 USB 的、emiwn 的、基础例程的和RTOS 操作系统的等等。学习 RT1052 重点就是参考官方 SDK 包里面提供的这些例程。

CMSIS 文件夹

CMSIS 全称: Cortex Microcontroller Software
Interface Standard,叫做 Cortex 微控制器软件接口标准。
在这里插入图片描述此文件夹里面有一些重要的跟 Cortex-M 架构有关的头文件,在 include 文件夹里面,创建工程需要用到!此文件夹还有重要的 DSP 库,在 Lib 文件夹里面。

devices 文件夹

此文件夹是 RT1052 相关的东西,包括 FSL 库。
在这里插入图片描述FSL 库就在 drivers 文件夹里面,我们创建库函数工程模板的时候就需要 FSL 库,还有一些其他的跟 RT1052 有关的.c 和.h 文件。

middleware 文件夹:

此文件夹包含了一些常用的第三方组件,比如 fatfs、lijpeg 库、usb、emwi 等。
在这里插入图片描述

新建工程注意

型号

  • 安装 光盘:6,软件资料\1,软件\MDK5\NXP.MIMXRT1052_DFP.10.0.1.pack 这个安装包
  • 号令者 RT1052 开发板所使用的 MCU 型号为 RT1052CVL5B,所以我们选择:NXP→MIMXRT1052→MIMXRT1052xxxxx→MIMXRT1052CVL5B
    在这里插入图片描述MDK 会弹出 Manage Run-Time Environment 对话框
    在这里插入图片描述在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境。我们直接点击 Cancel,即可。

初始化配置

MPU_Memory_Protection();    //初始化MPU
RT1052_Clock_Init();	    //配置系统时钟

MPU_Memory_Protection

MPU_Memory_Protection,用于对 RT1052 内部各个存储区域进行保护设置(RT1052 各存储区的分配和地址,详见《RT1050 参考手册》第 2 章 Memory Maps)
该函数里面总共对 8 个内存区域进行了保护设置,分别是:

  • 区域 0,起始地址:0XC0000000,大小:1GB。存储属性;设备类型(TEX=2),禁止共享(S=0)、禁止 Cache(C=0)、禁止缓存(B=0)。此地址段属于 SEMC3。
  • 区域 1,起始地址:0X80000000,大小:512MB。存储属性;设备类型(TEX=2),禁止共享(S=0)、禁止 Cache(C=0)、禁止缓存(B=0)。此地址段属于 SEMC0~2,包括:SDRAM 和
    DBI 等。
    区域 2,起始地址:0X60000000,大小:512MB。存储属性;普通类型(TEX=0),禁止共享(S=0)、允许 Cache(C=1)、允许缓存(B=1)。此地址段属于 FlexSPI,包括:FlexSPIA 和
    FlexSPIB 等。
  • 区域 3,起始地址:0X00000000,大小:1GB。设备类型(TEX=2),禁止共享(S=0)、禁止 Cache(C=0)、禁止缓存(B=0)。此地址段属于 ITCM/ROMCP/DTCM 和 OCRAM 等。
  • 区域 4,起始地址:0X00000000,大小:128KB。存储属性;普通类型(TEX=0),禁止共享(S=0)、允许 Cache(C=1)、允许缓存(B=1)。此地址段属于 ITCM。MPU 属性规则:区域大的覆盖区域小的,所以 ITCM 的属性以区域 4 的设置为准,区域 3 的设置,对 ITCM 无效。
  • 区域 5,起始地址:0X20000000,大小:128KB。存储属性;普通类型(TEX=0),禁止共享(S=0)、允许 Cache(C=1)、允许缓存(B=1)。此地址段属于 DTCM。同理,DTCM 的属性以区域 5 的设置为准。
  • 区域 6,起始地址:0X20200000,大小:256KB。存储属性;强序类型(TEX=0),禁止共享(S=0)、禁止 Cache(C=0)、禁止缓存(B=0)。此地址段属于 OCRAM。同理,OCRAM 的属性以区域 6 的设置为准。
  • 区域 7,起始地址:0X80000000,大小:2MB。存储属性;普通类型(TEX=0),禁止共享(S=0)、允许 Cache(C=1)、允许缓存(B=1)。此地址段属于 SDRAM(前 2MB 范围)。同理,SDRAM 的前 2MB 地址空间属性以区域 7 的设置为准。

经过这样的设置,我们对 RT1052 用到的地址空间都进行了 MPU 保护设置,在实际
使用时,可以很好的运行。

  • 该函数调用了好多外部函数,其中: SCB_DisableICache、SCB_DisableDCache 、SCB_EnableICache 和 SCB_EnableDCache 这几个函数,用于禁止/使能 I chache 和 D cahche,来自 core_cm7.h(放在 CORE 文件夹下)。

  • 而:ARM_MPU_Disable、ARM_MPU_Enable、ARM_MPU_RBAR 和ARM_MPU_RASR 这几个函数,用于关闭/开启 MPU 保护,以及设置 MPU 的 RBAR 和 RASR 寄存器,来自mpu_armv7.h(放在 CORE 文件夹下)。

注意:这个函数最终是会开启 MPU 保护和 I Cache 和 D Cache 的,所以一旦调用,肯定就开 Cache 和内存保护了。

  • 大家只要记住有这么个函数,作用就是给各个内存段做保护,避免开了 Cache 以后访问出错,而且每个例程都需要调用,就可以了。

RT1052_Clock_Init

//设置RT1052的系统时钟
void RT1052_Clock_Init(void)
{
    CLOCK_SetXtalFreq(24000000);			//芯片主晶振24MHz
    CLOCK_SetRtcXtalFreq(32768);			//RTC晶振32.728KHz

	//初始化时钟阶段先设置为低速的24M时钟,
	//后面会重新将PLL1设置为1200MHz,主频设置为600MHz
	CLOCK_SetMux(kCLOCK_PeriphClk2Mux,1);   //设置PERIPH_CLK2的时钟源为OSC时钟,也就是24M晶振 
	CLOCK_SetMux(kCLOCK_PeriphMux,1);       //设置PERIPH_CLK为PERIPH_CLK2=24MHz 

	//设置VDD_SOC电压为1.25V,这样的话AHB就可以到600MHz
    DCDC->REG3=(DCDC->REG3&(~DCDC_REG3_TRG_MASK))|DCDC_REG3_TRG(0x12);

    //等待DCDC的稳定,即DCDC->REG0寄存器的bit31(STS_DC_OK)为1
    while(DCDC_REG0_STS_DC_OK_MASK!=(DCDC_REG0_STS_DC_OK_MASK&DCDC->REG0)){};

	//下面配置中的1200Mhz,528Mhz和480Mhz等频率均按照PLL1为1200Mhz来配置的
	//因为后面会重新配置PLL1的,不要纠结于上面配置的24MHz!!!!
    CLOCK_InitArmPll(&armPllConfig); 		//配置PLL1(ARM PLL)为1200MHz
    CLOCK_InitSysPll(&sysPllConfig);		//配置PLL2(SYS PLL)为528MHz
    CLOCK_InitUsb1Pll(&usb1PllConfig); 		//配置PLL3(USB1 PLL)为480MHz

    CLOCK_SetDiv(kCLOCK_ArmDiv,1); 		    //ARM PODF 2分频,可选择0~7分别对应1~8分频,1200Mhz/2=600MHz
    CLOCK_SetMux(kCLOCK_PrePeriphMux,3); 	//设置PRE_PERIPH_CLK的时钟源为PLL1经过ARM PODF分频后的时钟
											//即:PRE_PERIPH_CLK=PLL1/ARM PODF=1200MHz/2=600MHz
    CLOCK_SetMux(kCLOCK_PeriphMux,0);    	//设置PERIPH_CLK为PRE_PERIPH_CLK=600MHz 
        
    CLOCK_SetDiv(kCLOCK_AhbDiv,0); 		    //AHB_CLK_ROOT=PERIPH_CLK/1=600/1=600Mhz
    CLOCK_SetDiv(kCLOCK_IpgDiv,3); 		    //IPG_CLK_ROOT=AHB_CLK_ROOT/4=600/4=150MHz
	CLOCK_SetDiv(kCLOCK_PerclkDiv,1); 	    //PER_CLK_ROOT=IPG_CLK_ROOT/2=150/2=75MHz

    
    //设置PLL2(SYS PLL)各个PFD
    CLOCK_InitSysPfd(kCLOCK_Pfd0,27);       //PLL2_PFD0=528*18/27=352Mhz
    CLOCK_InitSysPfd(kCLOCK_Pfd1,16);       //PLL2_PFD1=528*18/16=594Mhz
    CLOCK_InitSysPfd(kCLOCK_Pfd2,24);       //PLL2_PFD2=528*18/24=396Mhz
    CLOCK_InitSysPfd(kCLOCK_Pfd3,32);       //PLL2_PFD3=528*18/32=297Mhz
    
    //设置PLL3(USB1 PLL)各个PFD
    CLOCK_InitUsb1Pfd(kCLOCK_Pfd0,15);      //PLL3_PFD0=480*18/12=720Mhz
    CLOCK_InitUsb1Pfd(kCLOCK_Pfd1,13);      //PLL3_PFD1=480*18/13=664.62Mhz
    CLOCK_InitUsb1Pfd(kCLOCK_Pfd2,17);      //PLL3_PFD2=480*18/17=508.24Mhz
    CLOCK_InitUsb1Pfd(kCLOCK_Pfd3,19);      //PLL3_PFD3=480*18/19=454.74Mhz
    
	//一共7个PLL,上面初始化了PLL1(ARM PLL)、PLL2(SYS PLL)和USB1 PLL(USB1 PLL)
	//其它四个PLL后面根据实际使用情况在做初始化。
    CLOCK_DeinitAudioPll();	//关闭AUDIO PLL (PLL4)
    CLOCK_DeinitVideoPll();	//关闭VIDEO PLL (PLL5)
    CLOCK_DeinitEnetPll();	//关闭ENET  PLL (PLL6)
    CLOCK_DeinitUsb2Pll();	//关闭USB2  PLL (PLL7)
    
	//更新内核时钟,此函数计算全局变量SystemCoreClock的值,
	//SystemCoreClock就是内核时钟,按照上面的配置此时钟就是600MHz
    SystemCoreClockUpdate(); 
    	
	//使能SNVS时钟
	CLOCK_EnableClock(kCLOCK_IomuxcSnvs); 	
    
    CLOCK_SetMux(kCLOCK_SemcMux,0); //PERIPH_CLK作为SEMC时钟源,PERIPH_CLK=600M
    CLOCK_SetDiv(kCLOCK_SemcDiv,3); //设置SEMC时钟由PERIPH_CLK四分频得到,即SEMC Clock=600/4=150Mhz
}

NXP 的 FSL 库提供了一套用于设置系统时钟,包括各个外设时钟的 API 函数,我们在使用 FSL 库函数开发 RT1052 的时候就可以使用这些 API 函数来设置相应的时钟。

CLOCK_SetXtalFreq() 和 CLOCK_SetRtcXtalFreq() 函数

CLOCK_SetXtalFreq()和 CLOCK_SetRtcXtalFreq()这两个函数用来设置所使用的主晶振和RTC 晶振
这两个函数在 fsl_clock.h 中定义,如下:

static inline void CLOCK_SetXtalFreq(uint32_t freq)
{
		g_xtalFreq = freq;
}
static inline void CLOCK_SetRtcXtalFreq(uint32_t freq)
{
		g_rtcXtalFreq = freq;
}

CLOCK_SetMux()

Mux 是多路复用器的意思,用来在可选的多路输入时钟中选择其中的一路作为使用时钟。
CLOCK_SetMux 函数最终肯定是要操作 CCM→CBCDR 的 PERIPH_CLK_SEL 位。

static inline void CLOCK_SetMux(clock_mux_t mux, uint32_t value)

此函数有两个参数:mux 和 value,mux 用来指定要设置的是哪个时钟,value 肯定就是要设置的值,mux 是个 clock_mux_t 类型的变量,而 clock_mux_t 是个枚举类型,枚举出来 RT1052所有可设置的时钟,clock_mux_t 在文件 fsl_clock.t 中有定义

typedef enum _clock_mux
{
    kCLOCK_Pll3SwMux = CCM_TUPLE(CCSR,
                                 CCM_CCSR_PLL3_SW_CLK_SEL_SHIFT,
                                 CCM_CCSR_PLL3_SW_CLK_SEL_MASK,
                                 CCM_NO_BUSY_WAIT), /*!< pll3_sw_clk mux name */

    kCLOCK_PeriphMux = CCM_TUPLE(CBCDR,
                                 CCM_CBCDR_PERIPH_CLK_SEL_SHIFT,
                                 CCM_CBCDR_PERIPH_CLK_SEL_MASK,
                                 CCM_CDHIPR_PERIPH_CLK_SEL_BUSY_SHIFT), /*!< periph mux name */
    kCLOCK_SemcAltMux = CCM_TUPLE(CBCDR,
                                  CCM_CBCDR_SEMC_ALT_CLK_SEL_SHIFT,
                                  CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK,
                                  CCM_NO_BUSY_WAIT), /*!< semc mux name */
    kCLOCK_SemcMux = CCM_TUPLE(
        CBCDR, CCM_CBCDR_SEMC_CLK_SEL_SHIFT, CCM_CBCDR_SEMC_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< semc mux name */

    kCLOCK_PrePeriphMux = CCM_TUPLE(CBCMR,
                                    CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT,
                                    CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK,
                                    CCM_NO_BUSY_WAIT), /*!< pre-periph mux name */
    kCLOCK_TraceMux = CCM_TUPLE(
        CBCMR, CCM_CBCMR_TRACE_CLK_SEL_SHIFT, CCM_CBCMR_TRACE_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< trace mux name */
    kCLOCK_PeriphClk2Mux = CCM_TUPLE(CBCMR,
                                     CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT,
                                     CCM_CBCMR_PERIPH_CLK2_SEL_MASK,
                                     CCM_NO_BUSY_WAIT), /*!< periph clock2 mux name */
 }

以上通过名字就可以设置,可以通过如下设置将 PERIPH CLK 的时钟选择为 PERIPH_CLK2__CLK。

//设置 PERIPH_CLK 为 PERIPH_CLK2=24MHz
CLOCK_SetMux(kCLOCK_PeriphMux, 1);

CLOCK_SetDiv()

Div 是单词 Division 的缩写,意思是分频,所以这个函数是用来设置时钟分频的。

  • 这里是设置 AHB_CLK_ROOT 时钟频率的,此时钟是对 PERIPH CLK 进行分频得来的,由 CCM→CBCDR 的 AHB_PODF 位控制

在这里插入图片描述可以看出 AHB_PODF 可设置的值为:0~7,分别对应 1~8 分频,假设 PERIPH CLK此时为600M,那么设置AHB_PODF位为0,也就是一分频,AHB_CLK_ROOT就为600M。

static inline void CLOCK_SetDiv(clock_div_t divider, uint32_t value)

此函数有两个参数:divider 和 value,divider 用来指定要设置的是哪个时钟的分频值,value明显的就是要设置的分频值。

  • divider 是 clock_div_t 类型的,clock_div_t 同样是个枚举类型,枚
    举出了所有可以分频的时钟,在文件 fsl_clock.h 中有如下定义
typedef enum _clock_div
{
    kCLOCK_ArmDiv = CCM_TUPLE(
        CACRR, CCM_CACRR_ARM_PODF_SHIFT, CCM_CACRR_ARM_PODF_MASK, CCM_CDHIPR_ARM_PODF_BUSY_SHIFT), /*!< core div name */

    kCLOCK_PeriphClk2Div = CCM_TUPLE(CBCDR,
                                     CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT,
                                     CCM_CBCDR_PERIPH_CLK2_PODF_MASK,
                                     CCM_NO_BUSY_WAIT), /*!< periph clock2 div name */
    kCLOCK_SemcDiv = CCM_TUPLE(CBCDR,
                               CCM_CBCDR_SEMC_PODF_SHIFT,
                               CCM_CBCDR_SEMC_PODF_MASK,
                               CCM_CDHIPR_SEMC_PODF_BUSY_SHIFT), /*!< semc div name */
    kCLOCK_AhbDiv = CCM_TUPLE(
        CBCDR, CCM_CBCDR_AHB_PODF_SHIFT, CCM_CBCDR_AHB_PODF_MASK, CCM_CDHIPR_AHB_PODF_BUSY_SHIFT), /*!< ahb div name */
    kCLOCK_IpgDiv =
        CCM_TUPLE(CBCDR, CCM_CBCDR_IPG_PODF_SHIFT, CCM_CBCDR_IPG_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< ipg div name */
}

如果要设置 AHB_CLK_ROOT 的时钟分频的话就可以使用如下代码:

//AHB PODF 1 分频,可选择 0~7 分别对应 1~8 分频,
CLOCK_SetDiv(kCLOCK_AhbDiv,0);

CLOCK_InitXXXPll() 函数

CLOCK_InitXXXPll 里面的 XXX 表示其他字母,看名字里面有个 Pll,那么基本可以猜出这一系列函数是用来设置 PLL 的,前面说了,RT1052 一共 7 个 PLL,所以有七个这样的函数。
在这里插入图片描述以表中设置 PLL1 的函数 CLOCK_InitArmPll 为例,主时钟图③处就是设置 ARM PLL(PLL1),通过这个 PLL 可以将输入时钟(一般为 24M)倍频到一个比较高的频率。

  • 具体是通过 CCM_ANALOG→PLL_ARM 寄存器的 DIV_SELECT 位设置,取值范围:54~108。
  • PLL 输出频 率 = 输 入 频 率 *div_select/2 。 因 此 函 数 CLOCK_InitArmPll 最 终 肯 定 是 会 操 作CCM_ANALOG→PLL_ARM 寄存器的,自行查看函数 CLOCK_InitArmPll 源码,里面就是操作的 CCM_ANALOG→PLL_ARM 寄存器。

CLOCK_InitSysPfd()和 和 CLOCK_InitUsb1Pfd 函数

这两个函数是分别来设置 PLL2 和 PLL3 的 PFD 时钟频率的, PLL2和 PLL3 各有 4 个 PFD,总共 8 个。这 8 个 PFD 就通过函数 CLOCK_InitSysPfd 和CLOCK_InitUsb1Pfd 来设置。

CLOCK_EnableClock() 和 CLOCK_DisableClock()

为了降低系统功耗,RT1052 是可以单独开关指定外设时钟的。通过设置 CCM→CCGR0~CCGR6 这 7 个寄存器中指定的位来开关指定外设 的 时 钟 , FSL 库 提 供 了 两 个 函 数 来 实 现 这 个 功 能 : CLOCK_EnableClock 和
CLOCK_DisableClock,前者打开指定外设的时钟,后者关闭指定外设的时钟

static inline void CLOCK_EnableClock(clock_ip_name_t name)
static inline void CLOCK_DisableClock(clock_ip_name_t name)

这两个函数都只有一个参数 name,这个参数就是用来指定要开关哪个外设的时钟。

  • 参数name 是个枚举类型,类型为 clock_ip_name_t,此类型枚举出了所有可以设置外设时钟的外设,在文件 fsl_clock.h 中有如下定义

比如我们要开关串口 LPUART1 的时钟,那么就可以使用如下代码:

CLOCK_EnableClock(kCLOCK_Lpuart1); //打开 LPUART1 时钟
CLOCK_DisableClock (kCLOCK_Lpuart1); //关闭 LPUART1 时钟

SystemCoreClockUpdate 函数

FSL库里面提供了一个全局变量来记录系统内核时钟频率,这个变量就是SystemCoreClock,在文件 system_MIMXRT1052.c 中有如下定义:

#define DEFAULT_SYSTEM_CLOCK 528000000UL //默认值
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;

SystemCoreClock 默认为 DEFAULT_SYSTEM_CLOCK,DEFAULT_SYSTEM_CLOCK 是个宏,在 system_MIMXRT1052.h 中定义为 528000000UL,也就是说默认为 528M。

  • 但是我们要把内核时钟设置为其他值,比如 600M,因此变量 SystemCoreClock 要根据我们的设置同步的更新。
  • 这个更新变量 SystemCoreClock 的功能就是函数 SystemCoreClockUpdate()来完成的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/782743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决Git拉取代码仓库时显示文件名太长无法创建的问题解决

问题描述 拉取鸿蒙仓库应用示例代码时&#xff0c;鸿蒙应用示例代码&#xff0c;发现能下载成功&#xff0c;但是会报一个错误&#xff0c;错误截图和信息如下所示&#xff1a; 报错信息&#xff1a; try/src/main/ets/pages/pagelevelstagemanagement/multicompomentssync/ …

Redis的9种数据类型与数据持久化

系列文章传送门&#xff1a; 【七天入门数据库】第一天 MySQL的安装部署 【七天入门数据库】第二天 数据库理论基础 【七天入门数据库】第三天 MySQL的库表操作 【七天入门数据库】第四天 数据操作语言DML 一、Redis的9种数据类型的基本操作 &#xff08;一&#xff09;k…

服务器中了360后缀勒索病毒,360后缀勒索病毒介绍解密数据恢复

360后缀勒索病毒&#xff0c;是BeijingCrypt勒索家族中的一种勒索软件病毒&#xff0c;这种恶意软件一旦攻击了企业的服务器就会利用自身独特的加密技术来全盘扫描系统文件&#xff0c;并对用户的全部文件进行加密&#xff0c;并要求用户支付赎金以解锁文件。近期&#xff0c;我…

16matlab数据分析 多项式的求导(matlab程序)

1.简述 多项式的求导 polyder( ):多项式求导函数。调用格式: ( 1 ) ppolyder( P):求多项式P的导函数。 ( 2 ) ppolyder(P,Q):求PQ的导函数。 ( 3 ) [p,q]polyder(P,Q):求P/Q的导函数&#xff0c;导函数的分子存入p&#xff0c;分母存入q。 多项式的表示 多项式的四则运算 四…

i.MX6ULL(十七) linux LED驱动

1 设备树 LED 驱动原理 对于MX6ULL 点灯方式较多&#xff0c;直接通过寄存器操作更适合低成本设备&#xff0c;与裸机实验不同的是&#xff0c;在 Linux 下编写驱动要符合 Linux 的驱动框架。 但Linux 下的任何外设驱动&#xff0c;最终都是要配置相应的硬件寄存器&#xff0…

Spring中的Bean对象

经过上一篇博客&#xff0c;我们已经可以实现基本的 Spring 读取和存储对象的操作了&#xff0c;但在操作的过程中我们发 现读取和存储对象并没有想象中的那么“ 简单 ” &#xff0c;所以接下来我们要学习更加简单的操作 Bean 对象的方法。 在 Spring 中想要 更简单的存储…

mac怎么转换音频格式?

mac怎么转换音频格式&#xff1f;相信很多小伙伴都知道&#xff0c;平时我们接触到的音频格式大多是mp3格式的&#xff0c;因为mp3是电脑上最为流行的音频格式&#xff0c;不过除了mp3格式外&#xff0c;还有很多不同的音频格式&#xff0c;有时候不同网上或者不同软件上下载到…

Python爬虫学习笔记(十)————Scrapy

目录 1.scrapy是什么&#xff1f; 2.安装scrapy 3. scrapy项目的创建以及运行 &#xff08;1&#xff09;创建scrapy项目&#xff1a; &#xff08;2&#xff09;项目组成&#xff1a; &#xff08;3&#xff09;创建爬虫文件&#xff1a; ①跳转到spiders文件夹中去创建…

ext4 - delay allocation数据结构

概述 延迟分配delay allocation是ext4非常重要的特性&#xff0c;启用该特性write系统将用户空间buffer写入内存page cache中即返回&#xff0c;此时也不会真正进行磁盘block分配&#xff0c;而是延迟到磁盘回写时&#xff08;比如dirty ratio达到一定值&#xff0c;定时刷新&…

高校大数据教材推荐-《Python中文自然语言处理基础与实战》

《Python中文自然语言处理基础与实战》是“十四五”职业教育国家规划教材&#xff0c;是大数据应用开发&#xff08;Python&#xff09;“1X”职业技能等级证书配套系列教材。本书以项目为载体&#xff0c;突出职业技能。坚持理实一体化的理念。理实一体化&#xff0c;就是理论…

H5基础教程

w3school官网 请点击下面工程名称&#xff0c;跳转到代码的仓库页面&#xff0c;将工程 下载下来 Demo Code 里有详细的注释 TestH5

Vue3+Vite前端知识汇总1篇

目录 1、设置package.json&#xff0c;让编译完成后自动打开浏览器。 2、设置vite.config.ts,设置src别名&#xff0c;后面就不用 ../../../ 了。 3、安装types/node 解决vscode显示红波浪线问题。 4、安装 sass和reset.css 5、创建并引入全局组件&#xff0c;HospitalTop…

2816. 判断子序列

题目链接&#xff1a; 自己的做法&#xff1a; #include <bits/stdc.h>using namespace std;const int N 1e5 10; int a[N], b[N]; int main() {int n, m;bool flag true;scanf("%d%d", &n, &m);for (int i 0; i < n; i) scanf("%d"…

【C++】AVL树的实现及测试

文章目录 AVL树节点的定义AVL树的定义AVL树的插入插入后更新平衡因子AVL树的右单旋AVL树的左单旋先左单旋再右单旋先右单旋再左单旋检查是否满足AVL树总代码 AVL树 AVL树也叫平衡二叉搜索树&#xff0c;通过旋转解决了搜索二叉树的不确定性&#xff0c;让整颗树趋近于一颗满二叉…

一本通OJ 1810 登山 题解

题目链接 题目大意 从 ( 0 , 0 ) (0,0) (0,0) 走到 ( n , n ) (n,n) (n,n) &#xff0c;不能超过直线 y x yx yx&#xff0c;并且图上有 m m m 个点不能走&#xff0c;问你有几种方案 解题思路 很明显这题与卡特兰数有关&#xff0c;但是不同点在于这题中存在点不能走…

解决阿里云服务器不能访问端口

服务器已经下载了redis&#xff0c;kafka&#xff0c;但就是访问不了端口号&#xff0c; 开通云服务器以后&#xff0c;请一定在安全组设置规则&#xff0c;放行端口 防火墙要关闭

服务器内存满了解决之路

背景&#xff1a;大清早&#xff0c;突然一通电话吵醒&#xff0c;说项目跑不了&#xff0c;还没洗漱赶紧跑过来&#xff0c;毕竟属于实时在用的系统。排查发现系统盘满了&#xff0c;数据写不进去了&#xff0c;导致报错。接手的项目&#xff0c;从来没考虑服务器问题&#xf…

SR501人体红外模块

文章目录 前言一、SR501模块介绍二、设备树添加节点三、驱动程序四、测试程序五、上机测试及效果总结 前言 人体红外模块 是一种能够检测人或动物发射的红外线而输出电信号的传感器。广泛应用于各种自动化控制装置中。比如常见的楼道自动开关、防盗报警等。 一、SR501模块介绍…

深度学习-第R1周心脏病预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 我的环境&#xff1a; 语言环境&#xff1a;Python3.10.7编译器&#xff1a;VScode深度学习环境&#xff1a;TensorFlow 2.13.0 一、前期工作&#xff1a; …

语义通信中基于深度双Q网络的多维资源联合分配算法

目录 论文简介系统模型多维资源联合分配模型多维资源联合分配算法 论文简介 作者 林润韬 郭彩丽 陈九九 王彦君发表期刊or会议 《移动通信》发表时间 2023.4 系统模型 场景中的边缘服务器部署在路边单元上&#xff0c;每个路边单元具有一定的无线覆盖区域&#xff0c;服务器将…