系列文章目录
1.连续打卡第一天:提前对CPK_RA2E1是瑞萨RA系列开发板的初体验,了解一下
2.开发环境的选择和调试(从零开始,加油)
3.欲速则不达,今天是对RA2E1 基础知识的补充学习。
4.e2 studio 使用教程
5.Keil配置使用(使用 RASC 生成 Keil 工程)
6.Keil配置使用(使用 RASC 生成 Keil 工程)
7.(电脑重装系统)学习RA产品家族选型手册
8.问题解决、学习RA寄存器、用寄存器的方式点亮第一个LED灯。
9.继续学习RA寄存器
10.FSP固件库开发及FSP配置详解。
11.FSP固件库开发点亮第一个灯。
12.FSP固件库开发按键输入检测控制LED灯闪烁
13.FSP固件库开发启动文件详解
文章目录
前言
一、RA2E1的时钟是什么?
二、时钟详解
1.时钟产生的一些来源
2.RA2E1内部时钟源
3.内部时钟源相关引脚
4.FSP固件库时钟树
5.时钟配置函数
6.实操:配置时钟,编写延时函数(粗略延时)
7.FSP配置
8.代码
总结
人各有志,自己的路自己走。
前言
随着学习的深入,于是开始探讨了一个单片机的灵魂,时钟,并且用时钟编写一些延时函数,了解RA2E1 FSP内部的时钟配置。学习时钟的使用。
RA2E1 产品群是 RA 系列的入门级单芯片微控制器,基于48 MHz Arm® Cortex®-M23 内核,具有高达 128 kB 的代码闪存以及 16 kB 的 SRAM 。 这款产品采用优化的制程和瑞萨电子的低功耗工艺技术,是业界一流水平的超低功耗微控制器。 RA2E1 产品支持 1.6V 至 5.5V 的宽工作电压范围和多种封装,如 LQFP、QFN、LGA、BGA 和 WLCSP。 RA2E1 可与 RA2L1 产品群引脚和外围设备兼容,特别适用于电池供电应用以及空间受限应用,以及其他需要高性能和低功耗的系统。
一、RA2E1的时钟是什么?
系统中的每一个外围设备都需要不同的工作频率。因此需要配置不同的时钟频率,来满足不同模块的需求。
RA2E1是一款由瑞萨电子(Renesas Electronics)推出的微控制器(MCU)系列产品,其时钟的产生来源主要依赖于内部的晶体振荡器和外部的时钟源。以下是关于RA2E1时钟产生来源的详细解释:
内部晶体振荡器:RA2E1芯片内置了一个高精度的晶体振荡器,其频率通常为4~20 MHz。使用内部晶体振荡器可以获得非常精确的时钟信号,但是由于晶体振荡器的稳定性会受到温度和供电电压等因素的影响,因此需要在设计时进行合适的校准。
外部晶体振荡器:RA2E1芯片还支持外部晶体振荡器,可以通过将外部晶体振荡器连接到芯片的XT1和XT2引脚上来提供时钟源。外部晶体振荡器可以提供更高的稳定性和精度,适用于一些对时钟精度要求较高的应用场景。
外部时钟源:除了晶体振荡器,RA2E1芯片还支持外部时钟源,例如用于网络通信的以太网时钟,或其他MCU、DSP等芯片提供的时钟信号。外部时钟源可以提供更高的频率和更稳定的时钟信号,适用于一些需要高速操作和高精度计时的应用场景。
二、时钟详解
1.时钟产生的一些来源
Main Clock Oscillator (MOSC) :主时钟振荡器,连接外部 8 ~ 24 MHz 高速晶振 (连接引脚 EXTAL、XTAL)
Sub-Clock Oscillator (SOSC) :副时钟振荡器,连接外部 32.768 kHz 低速晶振 (连接引脚 XCIN、XCOUT)
Phase Locked Loop (PLL、PLL2) : PLL电路具有倍增振荡器频率的功能,可选择输入的时钟信号,并对其进行分频和倍频,输入时钟源 MOSC、HOCO,输入频率 8 MHz至 24 MHz,倍频比可在 10 到 30 之间选择(0.5步进)
PLL 输出频率:120 MHz ~ 200 MHz
PLL2 输出频率:120 MHz ~ 240 MHz
High-speed on-chip oscillator (HOCO) :高速片上振荡器,振荡频率: 16/18/20 MHz
Middle-speed on-chip oscillator (MOCO) :中速片上振荡器,振荡频率: 8 MHz
Low-speed on-chip oscillator (LOCO) :低速片上振荡器,振荡频率: 32.768 kHz
IWDT-dedicated clock (IWDTLOCO) :IWDT专用片上振荡器,振荡频率: 15 kHz
External clock input for JTAG (TCK) :JTAG的外部时钟输入,振荡频率: 最大25MHz
External clock input for SWD (SWCLK) :SWD的外部时钟输入,振荡频率: 最大25MHz
2.RA2E1内部时钟源
时钟线
时钟源
最大频率
系统时钟 (ICLK)
CPU, DTC, DMAC, Flash, RAM
最大 200 MHz
外围模块时钟A (PCLKA)
ETHERC, EDMAC, USBHS, QSPI, SCI, CAN-RAM, SPI, CRC, DOC, ADC12, DAC12, SCE9, GPT bus clock
最大 100 MHz
外围模块时钟B (PCLKB)
CAC, ELC, I/O ports, POEG, RTC, WDT, IWDT, AGT, IIC, CAN, USBFS, SSIE, SDHI, CEC, TSN, CTSU, Standby SRAM, Octal-SPI bus clock
最大 50 MHz
外围模块时钟C (PCLKC)
ADC12 conversion clock
最大 50 MHz
外围模块时钟D (PCLKD)
GPT计数时钟
最大 100 MHz
FlashIF时钟 (FCLK)
FlashIF
4 MHz - 50 MHz(P/E) 最大50 MHz(读取)
外部总线时钟 (BCLK)
External bus (外部总线时钟)
3.内部时钟源相关引脚
引脚
方向
说明
XTAL
Output
连接外部 8~24 MHz 晶振
EXTAL
Input
连接外部 8~24 MHz 晶振。时钟信号输入引脚
XCIN
Input
连接外部 32.768 kHz 晶振。时钟信号输入引脚
XCOUT
Output
连接外部 32.768 kHz 晶振
TCK/SWCLK
Input
用作 JTAG/SWD 的时钟输入。用于调试
EBCLK
Output
用于为外部设备提供外部总线时钟(EBCLK)
CLKOUT
Output
输出 CLKOUT/BUZZER 时钟
4.FSP固件库时钟树
5.时钟配置函数
/*******************************************************************************************************************//** * Initializes system clocks. Makes no assumptions about current register settings. **********************************************************************************************************************/ void bsp_clock_init (void) { /* Unlock CGC and LPM protection registers. */ R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_UNLOCK; #if BSP_FEATURE_BSP_FLASH_CACHE #if !BSP_CFG_USE_LOW_VOLTAGE_MODE && BSP_FEATURE_BSP_FLASH_CACHE_DISABLE_OPM /* Disable flash cache before modifying MEMWAIT, SOPCCR, or OPCCR. */ R_BSP_FlashCacheDisable(); #else /* Enable the flash cache and don't disable it while running from flash. On these MCUs, the flash cache does not * need to be disabled when adjusting the operating power mode. */ R_BSP_FlashCacheEnable(); #endif #endif #if BSP_FEATURE_BSP_FLASH_PREFETCH_BUFFER /* Disable the flash prefetch buffer. */ R_FACI_LP->PFBER = 0; #endif bsp_clock_freq_var_init(); #if BSP_CLOCK_CFG_MAIN_OSC_POPULATED #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET /* Update the main oscillator drive, source, and wait states if the main oscillator is stopped. If the main * oscillator is running, the drive, source, and wait states are assumed to be already set appropriately. */ if (R_SYSTEM->MOSCCR) { /* Don't write to MOSCWTCR unless MOSTP is 1 and MOSCSF = 0. */ FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.MOSCSF, 0U); /* Configure main oscillator drive. */ R_SYSTEM->MOMCR = BSP_PRV_MOMCR; /* Set the main oscillator wait time. */ R_SYSTEM->MOSCWTCR = (uint8_t) BSP_CLOCK_CFG_MAIN_OSC_WAIT; } #else /* Configure main oscillator drive. */ R_SYSTEM->MOMCR = BSP_PRV_MOMCR; /* Set the main oscillator wait time. */ R_SYSTEM->MOSCWTCR = (uint8_t) BSP_CLOCK_CFG_MAIN_OSC_WAIT; #endif #endif #if BSP_FEATURE_CGC_HAS_SOSC #if BSP_CLOCK_CFG_SUBCLOCK_POPULATED /* If Sub-Clock Oscillator is started at reset, stop it before configuring the subclock drive. */ if (0U == R_SYSTEM->SOSCCR) { /* Stop the Sub-Clock Oscillator to update the SOMCR register. */ R_SYSTEM->SOSCCR = 1U; /* Allow a stop interval of at least 5 SOSC clock cycles before configuring the drive capacity * and restarting Sub-Clock Oscillator. */ R_BSP_SoftwareDelay(BSP_PRV_SUBCLOCK_STOP_INTERVAL_US, BSP_DELAY_UNITS_MICROSECONDS); } /* Configure the subclock drive as subclock is not running. */ R_SYSTEM->SOMCR = ((BSP_CLOCK_CFG_SUBCLOCK_DRIVE << BSP_FEATURE_CGC_SODRV_SHIFT) & BSP_FEATURE_CGC_SODRV_MASK); /* Restart the Sub-Clock Oscillator. */ R_SYSTEM->SOSCCR = 0U; #if (BSP_CLOCKS_SOURCE_CLOCK_SUBCLOCK == BSP_CFG_CLOCK_SOURCE) || (BSP_PRV_HOCO_USE_FLL) /* If the subclock is the system clock source OR if FLL is used, wait for stabilization. */ R_BSP_SubClockStabilizeWait(BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS); #endif #else R_SYSTEM->SOSCCR = 1U; #endif #endif #if BSP_FEATURE_CGC_HAS_HOCOWTCR #if BSP_FEATURE_CGC_HOCOWTCR_64MHZ_ONLY /* These MCUs only require writes to HOCOWTCR if HOCO is set to 64 MHz. */ #if 64000000 == BSP_HOCO_HZ #if BSP_CFG_USE_LOW_VOLTAGE_MODE /* Wait for HOCO to stabilize before writing to HOCOWTCR. */ FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.HOCOSF, 1U); #else /* HOCO is assumed to be stable because these MCUs also require the HOCO to be stable before changing the operating * power control mode. */ #endif R_SYSTEM->HOCOWTCR = BSP_FEATURE_CGC_HOCOWTCR_VALUE; #endif #else /* These MCUs require HOCOWTCR to be set to the maximum value except in snooze mode. There is no restriction to * writing this register. */ R_SYSTEM->HOCOWTCR = BSP_FEATURE_CGC_HOCOWTCR_VALUE; #endif #endif #if !BSP_CFG_USE_LOW_VOLTAGE_MODE #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET /* Switch to high-speed to prevent any issues with the subsequent clock configurations. */ bsp_prv_operating_mode_set(BSP_PRV_OPERATING_MODE_HIGH_SPEED); #elif BSP_FEATURE_CGC_LOW_VOLTAGE_MAX_FREQ_HZ > 0U /* MCUs that support low voltage mode start up in low voltage mode. */ bsp_prv_operating_mode_opccr_set(BSP_PRV_OPERATING_MODE_HIGH_SPEED); #if !BSP_PRV_HOCO_USED /* HOCO must be running during startup in low voltage mode. If HOCO is not used, turn it off after exiting low * voltage mode. */ R_SYSTEM->HOCOCR = 1U; #endif #elif BSP_FEATURE_CGC_STARTUP_OPCCR_MODE != BSP_PRV_OPERATING_MODE_HIGH_SPEED /* Some MCUs do not start in high speed mode. */ bsp_prv_operating_mode_opccr_set(BSP_PRV_OPERATING_MODE_HIGH_SPEED); #endif #endif /* The FLL function can only be used when the subclock is running. */ #if BSP_PRV_HOCO_USE_FLL /* If FLL is to be used configure FLLCR1 and FLLCR2 before starting HOCO. */ R_SYSTEM->FLLCR2 = BSP_PRV_FLL_FLLCR2; R_SYSTEM->FLLCR1 = 1U; #endif /* Start all clocks used by other clocks first. */ #if BSP_PRV_HOCO_USED R_SYSTEM->HOCOCR = 0U; #if BSP_PRV_HOCO_USE_FLL && (BSP_CLOCKS_SOURCE_CLOCK_HOCO != BSP_CFG_PLL_SOURCE) /* If FLL is enabled, wait for the FLL stabilization delay (1.8 ms) */ R_BSP_SoftwareDelay(BSP_PRV_FLL_STABILIZATION_TIME_US, BSP_DELAY_UNITS_MICROSECONDS); #endif #if BSP_PRV_STABILIZE_HOCO /* Wait for HOCO to stabilize. */ FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.HOCOSF, 1U); #endif #endif #if BSP_PRV_MOCO_USED #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET /* If the MOCO is not running, start it and wait for it to stabilize using a software delay. */ if (0U != R_SYSTEM->MOCOCR) { R_SYSTEM->MOCOCR = 0U; #if BSP_PRV_STABILIZE_MOCO R_BSP_SoftwareDelay(BSP_FEATURE_CGC_MOCO_STABILIZATION_MAX_US, BSP_DELAY_UNITS_MICROSECONDS); #endif } #endif #endif #if BSP_PRV_LOCO_USED #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET /* If the LOCO is not running, start it and wait for it to stabilize using a software delay. */ if (0U != R_SYSTEM->LOCOCR) { R_SYSTEM->LOCOCR = 0U; #if BSP_PRV_STABILIZE_LOCO R_BSP_SoftwareDelay(BSP_FEATURE_CGC_LOCO_STABILIZATION_MAX_US, BSP_DELAY_UNITS_MICROSECONDS); #endif } #else R_SYSTEM->LOCOCR = 0U; #if BSP_PRV_STABILIZE_LOCO R_BSP_SoftwareDelay(BSP_FEATURE_CGC_LOCO_STABILIZATION_MAX_US, BSP_DELAY_UNITS_MICROSECONDS); #endif #endif #endif #if BSP_PRV_MAIN_OSC_USED R_SYSTEM->MOSCCR = 0U; #if BSP_PRV_STABILIZE_MAIN_OSC /* Wait for main oscillator to stabilize. */ FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.MOSCSF, 1U); #endif #endif /* Start clocks that require other clocks. At this point, all dependent clocks are running and stable if needed. */ #if BSP_PRV_STARTUP_OPERATING_MODE != BSP_PRV_OPERATING_MODE_LOW_SPEED #if BSP_FEATURE_CGC_HAS_PLL2 && BSP_CFG_PLL2_SOURCE != BSP_CLOCKS_CLOCK_DISABLED R_SYSTEM->PLL2CCR = BSP_PRV_PLL2CCR; #if (3U == BSP_FEATURE_CGC_PLLCCR_TYPE) R_SYSTEM->PLL2CCR2 = BSP_PRV_PLL2CCR2; #endif /* Start PLL2. */ R_SYSTEM->PLL2CR = 0U; #endif /* BSP_FEATURE_CGC_HAS_PLL2 && BSP_CFG_PLL2_ENABLE */ #endif #if BSP_PRV_PLL_SUPPORTED && BSP_PRV_PLL_USED #if BSP_CLOCKS_SOURCE_CLOCK_PLL == BSP_CFG_CLOCK_SOURCE /* Configure the PLL registers. */ #if 1U == BSP_FEATURE_CGC_PLLCCR_TYPE R_SYSTEM->PLLCCR = (uint16_t) BSP_PRV_PLLCCR; #elif 2U == BSP_FEATURE_CGC_PLLCCR_TYPE R_SYSTEM->PLLCCR2 = (uint8_t) BSP_PRV_PLLCCR; #elif 3U == BSP_FEATURE_CGC_PLLCCR_TYPE R_SYSTEM->PLLCCR = (uint16_t) BSP_PRV_PLLCCR; R_SYSTEM->PLLCCR2 = (uint16_t) BSP_PRV_PLLCCR2; #endif #if BSP_FEATURE_CGC_PLLCCR_WAIT_US > 0 /* This loop is provided to ensure at least 1 us passes between setting PLLMUL and clearing PLLSTP on some * MCUs (see PLLSTP notes in Section 8.2.4 "PLL Control Register (PLLCR)" of the RA4M1 manual R01UH0887EJ0100). * Five loops are needed here to ensure the most efficient path takes at least 1 us from the setting of * PLLMUL to the clearing of PLLSTP. HOCO is the fastest clock we can be using here since PLL cannot be running * while setting PLLCCR. */ bsp_prv_software_delay_loop(BSP_DELAY_LOOPS_CALCULATE(BSP_PRV_MAX_HOCO_CYCLES_PER_US)); #endif #endif R_SYSTEM->PLLCR = 0U; #if BSP_PRV_STABILIZE_PLL /* Wait for PLL to stabilize. */ FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.PLLSF, 1U); #endif #endif /* Set source clock and dividers. */ #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET #if BSP_TZ_SECURE_BUILD /* In case of soft reset, make sure callback pointer is NULL initially. */ g_bsp_clock_update_callback = NULL; #endif #if BSP_FEATURE_CGC_HAS_CPUCLK bsp_prv_clock_set(BSP_CFG_CLOCK_SOURCE, BSP_PRV_STARTUP_SCKDIVCR, BSP_PRV_STARTUP_SCKDIVCR2); #else bsp_prv_clock_set(BSP_CFG_CLOCK_SOURCE, BSP_PRV_STARTUP_SCKDIVCR, 0); #endif #else bsp_prv_clock_set_hard_reset(); #endif /* If the MCU can run in a lower power mode, apply the optimal operating speed mode. */ #if !BSP_CFG_USE_LOW_VOLTAGE_MODE #if BSP_PRV_STARTUP_OPERATING_MODE != BSP_PRV_OPERATING_MODE_HIGH_SPEED #if BSP_PRV_PLL_SUPPORTED #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET if (BSP_PRV_OPERATING_MODE_LOW_SPEED == BSP_PRV_STARTUP_OPERATING_MODE) { /* If the MCU has a PLL, ensure PLL is stopped and stable before entering low speed mode. */ R_SYSTEM->PLLCR = 1U; /* Wait for PLL to stabilize. */ FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.PLLSF, 0U); #if BSP_FEATURE_CGC_HAS_PLL2 /* If the MCU has a PLL2, ensure PLL2 is stopped and stable before entering low speed mode. */ R_SYSTEM->PLL2CR = 1U; /* Wait for PLL to stabilize. */ FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->OSCSF_b.PLL2SF, 0U); #endif } #endif #endif bsp_prv_operating_mode_set(BSP_PRV_STARTUP_OPERATING_MODE); #endif #endif #if defined(BSP_PRV_POWER_USE_DCDC) && (BSP_PRV_POWER_USE_DCDC == BSP_PRV_POWER_DCDC_STARTUP) && \ (BSP_PRV_STARTUP_OPERATING_MODE <= BSP_PRV_OPERATING_MODE_MIDDLE_SPEED) /* Start DCDC as part of BSP startup when configured (BSP_CFG_DCDC_ENABLE == 2). */ R_BSP_PowerModeSet(BSP_CFG_DCDC_VOLTAGE_RANGE); #endif /* Configure BCLK if it exists on the MCU. */ #ifdef BSP_CFG_BCLK_OUTPUT #if BSP_CFG_BCLK_OUTPUT > 0U R_SYSTEM->BCKCR = BSP_CFG_BCLK_OUTPUT - 1U; R_SYSTEM->EBCKOCR = 1U; #else #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET R_SYSTEM->EBCKOCR = 0U; #endif #endif #endif /* Configure SDRAM clock if it exists on the MCU. */ #ifdef BSP_CFG_SDCLK_OUTPUT R_SYSTEM->SDCKOCR = BSP_CFG_SDCLK_OUTPUT; #endif /* Configure CLKOUT. */ #if BSP_CFG_CLKOUT_SOURCE == BSP_CLOCKS_CLOCK_DISABLED #if BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET R_SYSTEM->CKOCR = 0U; #endif #else uint8_t ckocr = BSP_CFG_CLKOUT_SOURCE | (BSP_CFG_CLKOUT_DIV << BSP_PRV_CKOCR_CKODIV_BIT); R_SYSTEM->CKOCR = ckocr; ckocr |= (1U << BSP_PRV_CKOCR_CKOEN_BIT); R_SYSTEM->CKOCR = ckocr; #endif #if BSP_PRV_STARTUP_OPERATING_MODE != BSP_PRV_OPERATING_MODE_LOW_SPEED #if BSP_CFG_UCK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED /* If the USB clock has a divider setting in SCKDIVCR2. */ #if BSP_FEATURE_BSP_HAS_USB_CLOCK_DIV && !BSP_FEATURE_BSP_HAS_USBCKDIVCR R_SYSTEM->SCKDIVCR2 = BSP_PRV_UCK_DIV << BSP_PRV_SCKDIVCR2_UCK_BIT; #endif /* BSP_FEATURE_BSP_HAS_USB_CLOCK_DIV && !BSP_FEATURE_BSP_HAS_USBCKDIVCR */ /* If there is a REQ bit in USBCKCR than follow sequence from section 8.2.29 in RA6M4 hardware manual R01UH0890EJ0050. */ #if BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ /* Request to change the USB Clock. */ R_SYSTEM->USBCKCR_b.USBCKSREQ = 1; /* Wait for the clock to be stopped. */ FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->USBCKCR_b.USBCKSRDY, 1U); /* Write the settings. */ R_SYSTEM->USBCKDIVCR = BSP_PRV_UCK_DIV; /* Select the USB Clock without enabling it. */ R_SYSTEM->USBCKCR = BSP_CFG_UCK_SOURCE | R_SYSTEM_USBCKCR_USBCKSREQ_Msk; #endif /* BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ */ #if BSP_FEATURE_BSP_HAS_USB_CLOCK_SEL /* Some MCUs use an alternate register for selecting the USB clock source. */ #if BSP_FEATURE_BSP_HAS_USB_CLOCK_SEL_ALT #if BSP_CLOCKS_SOURCE_CLOCK_PLL == BSP_CFG_UCK_SOURCE /* Write to USBCKCR to select the PLL. */ R_SYSTEM->USBCKCR_ALT = 0; #elif BSP_CLOCKS_SOURCE_CLOCK_HOCO == BSP_CFG_UCK_SOURCE /* Write to USBCKCR to select the HOCO. */ R_SYSTEM->USBCKCR_ALT = 1; #endif #else /* Select the USB Clock. */ R_SYSTEM->USBCKCR = BSP_CFG_UCK_SOURCE; #endif #endif /* BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ */ #if BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ /* Wait for the USB Clock to be started. */ FSP_HARDWARE_REGISTER_WAIT(R_SYSTEM->USBCKCR_b.USBCKSRDY, 0U); #endif /* BSP_FEATURE_BSP_HAS_USB_CLOCK_REQ */ #endif /* BSP_CFG_USB_ENABLE */ #endif /* BSP_PRV_STARTUP_OPERATING_MODE != BSP_PRV_OPERATING_MODE_LOW_SPEED */ /* Set the OCTASPI clock if it exists on the MCU (See section 8.2.30 of the RA6M4 hardware manual R01UH0890EJ0050). */ #if BSP_FEATURE_BSP_HAS_OCTASPI_CLOCK && BSP_CFG_OCTA_SOURCE != BSP_CLOCKS_CLOCK_DISABLED bsp_octaclk_settings_t octaclk_settings = { .source_clock = (bsp_clocks_source_t) BSP_CFG_OCTA_SOURCE, .divider = (bsp_clocks_octaclk_div_t) BSP_CFG_OCTA_DIV }; R_BSP_OctaclkUpdate(&octaclk_settings); #endif /* BSP_FEATURE_BSP_HAS_OCTASPI_CLOCK && BSP_CFG_OCTASPI_CLOCK_ENABLE */ /* Set the CANFD clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_CANFD_CLOCK && (BSP_CFG_CANFDCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) && \ (BSP_CFG_CANFDCLK_SOURCE != BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) bsp_peripheral_clock_set(&R_SYSTEM->CANFDCKCR, &R_SYSTEM->CANFDCKDIVCR, BSP_CFG_CANFDCLK_DIV, BSP_CFG_CANFDCLK_SOURCE); #endif /* Set the SCISPI clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_SCISPI_CLOCK && (BSP_CFG_SCISPICLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->SCISPICKCR, &R_SYSTEM->SCISPICKDIVCR, BSP_CFG_SCISPICLK_DIV, BSP_CFG_SCISPICLK_SOURCE); #endif /* Set the SCI clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_SCI_CLOCK && (BSP_CFG_SCICLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->SCICKCR, &R_SYSTEM->SCICKDIVCR, BSP_CFG_SCICLK_DIV, BSP_CFG_SCICLK_SOURCE); #endif /* Set the SPI clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_SPI_CLOCK && (BSP_CFG_SPICLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->SPICKCR, &R_SYSTEM->SPICKDIVCR, BSP_CFG_SPICLK_DIV, BSP_CFG_SPICLK_SOURCE); #endif /* Set the GPT clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_GPT_CLOCK && (BSP_CFG_GPTCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->GPTCKCR, &R_SYSTEM->GPTCKDIVCR, BSP_CFG_GPTCLK_DIV, BSP_CFG_GPTCLK_SOURCE); #endif /* Set the IIC clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_IIC_CLOCK && (BSP_CFG_IICCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->IICCKCR, &R_SYSTEM->IICCKDIVCR, BSP_CFG_IICCLK_DIV, BSP_CFG_IICCLK_SOURCE); #endif /* Set the CEC clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_CEC_CLOCK && (BSP_CFG_CECCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->CECCKCR, &R_SYSTEM->CECCKDIVCR, BSP_CFG_CECCLK_DIV, BSP_CFG_CECCLK_SOURCE); #endif /* Set the I3C clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_I3C_CLOCK && (BSP_CFG_I3CCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->I3CCKCR, &R_SYSTEM->I3CCKDIVCR, BSP_CFG_I3CCLK_DIV, BSP_CFG_I3CCLK_SOURCE); #endif /* Set the ADC clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_ADC_CLOCK && (BSP_CFG_ADCCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->ADCCKCR, &R_SYSTEM->ADCCKDIVCR, BSP_CFG_ADCCLK_DIV, BSP_CFG_ADCCLK_SOURCE); #endif /* Set the LCD clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_LCD_CLOCK && (BSP_CFG_LCDCLK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->LCDCKCR, &R_SYSTEM->LCDCKDIVCR, BSP_CFG_LCDCLK_DIV, BSP_CFG_LCDCLK_SOURCE); #endif /* Set the USB-HS clock if it exists on the MCU */ #if BSP_FEATURE_BSP_HAS_USB60_CLOCK_REQ && (BSP_CFG_U60CK_SOURCE != BSP_CLOCKS_CLOCK_DISABLED) bsp_peripheral_clock_set(&R_SYSTEM->USB60CKCR, &R_SYSTEM->USB60CKDIVCR, BSP_CFG_U60CK_DIV, BSP_CFG_U60CK_SOURCE); #endif /* Lock CGC and LPM protection registers. */ R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_LOCK; #if BSP_FEATURE_BSP_FLASH_CACHE && BSP_FEATURE_BSP_FLASH_CACHE_DISABLE_OPM R_BSP_FlashCacheEnable(); #endif #if BSP_FEATURE_BSP_FLASH_PREFETCH_BUFFER R_FACI_LP->PFBER = 1; #endif }
6.实操:配置时钟,编写延时函数(粗略延时)
就用延时函数控制LED灯闪烁,之前的工程都是用的以下这种。
使用 R_BSP_SoftwareDelay 函数可以进行延时,LED 灯维持亮和灭这两种状态的时间由此函数决定。 它的第一个参数表示延时的时间量,第二个参数表示时间单位。
延时函数:
void R_BSP_SoftwareDelay (uint32_t delay, bsp_delay_uni时间单位参数可选:
BSP_DELAY_UNITS_SECONDS,表示秒;
BSP_DELAY_UNITS_MILLISECONDS,表示毫秒;
BSP_DELAY_UNITS_MICROSECONDS,表示微秒。ts_t units);
个人表示以上的函数还是很好用的,但是我们这次为了了解时钟,特此换一种方式。
硬件方面:(还是两个LED灯)
7.FSP配置
打开 FSP 的 Clock 配置页面,如下图所示,不做任何变更,其配置为默认的时钟频率配置,MCU的主频为默认的 48 MHz。
不同的频率修改:
8.代码
#include "hal_data.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
#define LED1_ON R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_01, BSP_IO_LEVEL_LOW)
#define LED2_ON R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_02, BSP_IO_LEVEL_LOW)
#define LED1_OFF R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_01, BSP_IO_LEVEL_HIGH)
#define LED2_OFF R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_02, BSP_IO_LEVEL_HIGH)
/* 简单的软件延时函数
使用不同的系统时钟,延时不一样
*/
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
while(1)
{
LED1_ON; // LED1亮
LED2_ON; // LED2亮
//R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时1秒
Delay(0x0FFFFFF); //不精确延时,延时时间会随系统时钟变化
LED1_OFF; // LED1灭
LED2_OFF; // LED2灭
//R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时1秒
Delay(0x0FFFFFF); //不精确延时,延时时间会随系统时钟变化
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
视频演示:
RA2E1 时钟频率测试
总结
时钟详解到此结束,希望给大家带来帮助!!!