STM32外部时钟更改后程序设置方法
stm32的RTC时钟程序
rtcfirstconfigure程序是第一次配置rtc如果配置后以后上电不需要重新
stm32的RTC时钟程序
sபைடு நூலகம்m32 的RTC 时钟程序
前些日子做了stm32 RTC 时钟的程序,现在把它记录下来。首先配置RTC,,使用外部时钟32.768KHz。其中配置了秒中断。
RTCFirstConfigure()程序是第一次配置RTC,如果配置后以后上电不需要重新
配置,如果RTC 时钟快了,可内部校准。
void RTCFirstConfigure() //first ini { RCC_BackupResetCmd(ENABLE); RCC_BackupResetCmd(DISABLE); RCC_LSEConfig(RCC_LSE_ON); //enable LSE clock 32.768K while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {} // Select LSE as RTC Clock Source RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //Enable RTC Clock / RCC_RTCCLKCmd(ENABLE); // Wait for RTC registers synchronization / RTC_WaitForSynchro(); // Wait until last write operation on RTC registers has finished / RTC_WaitForLastTask(); // Enable the RTC Second Interrupt/ RTC_ITConfig(RTC_IT_SEC, ENABLE); RTC_WaitForLastTask(); RTC_SetPrescaler(32767); // RTC period = RTCCLK/RTC_PR = (32.768KHz)/(32767+1)/ RTC_WaitForLastTask(); // BKP_SetRTCCalibrationValue(120); //RTC Calibration RCC_ClearFlag(); } RTCNorConfigure()程序配置完后每次上电都运行的程序
STM32F051使用自带时钟48M设置
}
}
去掉外部晶振后,单片机时钟源会默认的使用内部高速RC振荡器HSI,HSI频率大约为8M,所以要想使系统获得48M的频率需要用PLL倍频后做为系统的时钟,PLL是一个锁相环,专门用来倍频或者分频的。(倍频后所得的频率一般叫PLL时钟)
RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_12);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08) //µÈ´ýϵͳʱÖÓ³õʼ»¯³É¹¦
whilerccgetsysclksource去掉外部晶振后单片机时钟源会默认的使用内部高速rc振荡器hsihsi频率大约为8m所以要想使系统获得48m的频率需要用pll倍频后做为系统的时钟pll是一个锁相环专门用来倍频或者分频的
正确设置:
void RCC_Configuration(void);
void RCC_Configuration(void)
{
//ÉèÖÃPLLʱÖÓÔ´¼°±¶ÆµÏµÊý
RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_12);///*!< PLL input clock*12*/
//ʹÄÜPõʼ»¯³É¹¦
这句话的意思是将HSI时钟12倍频,为什么是12倍频而不是6倍频呢?如下图STM32F051系列的时钟树所示:
根据时钟树可以看出用PLL对HSI进行倍频时,硬件将首先对HSI二分频,也就是为4M,所以必须再对其进行12倍频才能变成48M,最后通过RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);语句将PLL时钟作为系统时钟,至此系统的时钟变为48M
STM32外部时钟更改后程序设置方法
FLASH_SetLatency(FLASH_Latency_2);//设置 FLASH 存储器延时时钟周期数 FLASH_Latency_2 2 延时周期 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//选择 FLASH 预取指缓存的模,预取指缓存使能
RCC_DeInit();//将外设 RCC 寄存器重设为缺省 RCC_HSICmd(ENABLE);//设置外部高速晶振(HSE) HSE 晶振打开(ON) while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY_HCLKConfig(RCC_SYSCLK_Div1);//设置 AHB 时钟(HCLK) RCC_SYSCLK_Div1 ----- AHB 时钟 = 系统时钟 RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速 AHB 时钟(PCLK2) RCC_HCLK_Div1 ----- APB2 时钟 = HCLK RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速 AHB 时钟(PCLK1) RCC_HCLK_Div2 ----- APB1 时钟 = HCLK/2
RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速 AHB 时钟(PCLK2) RCC_HCLK_Div1 ----- APB2 时钟 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速 AHB 时钟(PCLK1) RCC_HCLK_Div2 ----- APB1 时钟 = HCLK/2
#endif /* HSE_VALUE */
注意:以上是以外部晶振为 16MHz 为例
方法(2): 使用 STM32F10x 内部时钟来配置 STM32F10x 各个模块的系统时钟。(不推荐使用,内部 8MHz RC 振荡器不稳定)
STM32F0xx 微控制器的时钟配置介绍
2 年 05 月
文档 ID 022837 第 1 版
1/16
目录
目录
AN4055
1
术语表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.2 专家模式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4
已知限制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
文档 ID 022837 第 1 版
3/16
3
图片索引
图片索引
AN4055
图 1. 图 2. 图 3. 图 4. 图 5. 图 6. 图 7.
时钟结构图 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 I2S 时钟结构图 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 向导模式用户界面 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 选择时钟源 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 文件生成错误 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 专家模式用户界面 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 超出系统时钟频率 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
STM32单片机RTC时钟的使用方法及步骤
STM32单片机RTC时钟的使用方法及步骤以下是使用STM32单片机的RTC时钟的步骤:1.初始化RTC模块:首先,需要在RCC寄存器中使能RTC和LSE(Low-Speed External)晶振模块。
然后,配置RTC的时钟源和预分频器,选择合适的时钟频率。
2.配置RTC时间和日期:通过设置RTC的寄存器来配置当前时间和日期。
需要设置秒、分钟、小时、星期、日期、月份和年份,确保其具有正确的值。
3.启动RTC时钟:设置RTC的控制寄存器,使其开始工作。
可以选择启用或禁用闹钟功能,设置闹钟的时间和日期。
4.读取RTC数据:可以随时读取RTC的时间和日期数据。
读取数据后,可以进行各种计算和处理,如计算两个时间之间的差异、比较时间等。
5.处理RTC中断:可以设置RTC中断来触发一些操作,如闹钟触发时执行一些任务。
需要配置NVIC(Nested Vector Interrupt Controller)中断向量表,使能相应的中断。
6.备份和恢复RTC数据:RTC模块提供了备份寄存器,可以用来存储额外的信息。
可以使用一些特殊的寄存器,如BKP (Backup)寄存器或CPU的系统寄存器来备份和恢复数据。
7.断电维持能力:RTC模块的一个关键特性是其断电维持能力。
即使在断电情况下,RTC模块中的数据仍然能够保持。
可以通过电池供电电路来提供必要的电力。
8.节能模式:可以利用RTC模块的节能模式来降低功耗。
可以选择性地关闭RTC模块的不需要的功能,以减少功耗。
需要注意的是,具体的步骤可能会因芯片型号和开发工具的不同而有所差异。
因此,在使用STM32单片机的RTC时钟之前,需查阅相关的技术文档和参考手册,以了解具体操作步骤和寄存器配置。
以上是使用STM32单片机的RTC时钟的基本步骤。
在实际应用中,可以根据具体需求对RTC进行更多的配置和使用。
STM32F072从零配置工程-自定义时钟配置详解
STM32F072从零配置⼯程-⾃定义时钟配置详解从⾃⼰的板⼦STM32F407⼊⼿,参考官⽅的SystemInit()函数:核⼼在SetSysClock()这个函数,官⽅默认是采⽤HSE(设定为8MHz)作为PLL锁相环的输⼊输出168MHz的SYSCLK;/*** @brief Setup the microcontroller system* Initialize the Embedded Flash Interface, the PLL and update the* SystemFrequency variable.* @param None* @retval None*/void SystemInit(void){/* Reset the RCC clock configuration to the default reset state ------------*//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;/* Reset CFGR register */RCC->CFGR = 0x00000000;/* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset PLLCFGR register */RCC->PLLCFGR = 0x24003010;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Disable all interrupts */RCC->CIR = 0x00000000;/* Configure the System clock source, PLL Multiplier and Divider factors,AHB/APBx prescalers and Flash settings ----------------------------------*/SetSysClock();}这⾥⼤致分析⼀下官⽅默认的SetSysClock()配置:由于我个⼈采⽤的是STM32F407型号的芯⽚,因此精简⼀下函数;总体思路的话:使能HSE;等待HSE初始化完毕,进⾏下⼀步设置;设置HCLK、PCLK1、PCLK2的分频系数;配置PLL,使能PLL,等待PLL初始化完毕;选择PLL作为SYSCLK,等待SYSCLK时钟设置完毕;/*** @brief Configures the System clock source, PLL Multiplier and Divider factors,* AHB/APBx prescalers and Flash settings* @Note This function should be called only once the RCC clock configuration* is reset to the default reset state (done in SystemInit() function).* @param None* @retval None*/static void SetSysClock(void){/******************************************************************************//* PLL (clocked by HSE) used as System clock source *//******************************************************************************/__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* Enable HSE */RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* Wait till HSE is ready and if Time out is reached exit */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){else{HSEStatus = (uint32_t)0x00;}if (HSEStatus == (uint32_t)0x01){/* Select regulator voltage output Scale 1 mode */RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;/* HCLK = SYSCLK / 1*/RCC->CFGR |= RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK / 2*/RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;/* PCLK1 = HCLK / 4*/RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;/* PCLK2 = HCLK / 1*/RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK / 2*/RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;/* Configure the main PLL */RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);/* Enable the main PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till the main PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Configure Flash prefetch, Instruction cache, Data cache and wait state */FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; /* Configure Flash prefetch, Instruction cache, Data cache and wait state */FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; /* Select the main PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= RCC_CFGR_SW_PLL;/* Wait till the main PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);{}}else{ /* If HSE fails to start-up, the application will have wrong clockconfiguration. User can add here some code to deal with this error */}}在官⽅的基础上,直接设定HSE作为SYSCLK时钟:初始化HSE;等待HSE初始化成功后再继续;设置调压器电压输出级别为1以便使器件在最⼤频率⼯作;设置HCLK、PCLK1、PCLK2分频系数;设置HSE作为系统时钟;void HSE_SetSysClock(void){__IO uint32_t HSEStartUpStatus = 0; /* 开启HSE时钟 */ /* 此函数从stm32f0xx_rcc.c获取,⽤于配置外部时钟HSE: * 有三个配置:RCC_HSE_OFF关闭外部HSE时钟 * RCC_HSE_ON开始外部HSE晶振 * RCC_HSE_Bypass开始HSE旁路设置 */ RCC_HSEConfig(RCC_HSE_ON); /* 若时钟配置成功 */if(HSEStartUpStatus == SUCCESS){RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK2Config(RCC_HCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div1); /* 将SYSCLK系统时钟设置为HSE */RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); /* 等待SYSCLK系统时钟设置成功 */while(RCC_GetSYSCLKSource() != 0x04){}}else{while(1);}}使⽤HSI经过PLL配置系统时钟:使能HSI时钟;获取HSI状态并等待HSI稳定;设置调节器电压输出级别配置为1;设置HCLK、PCLK1/2分频系数;设置PLL时钟分频系数;使能PLL并等待PLL稳定后配置PLL状态;设置PLL作为SYSCLK时钟并等待设置完成;void HSI_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q) {__IO uint32_t HSIStartUpStatus = 0;/* 去初始化RCC */RCC_DeInit();/* 使能HSI时钟 */RCC_HSICmd(ENABLE);/* 从RCC的CR寄存器中获取HSI配置状态 */HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;/* 若HSI配置成功 */if(HSIStartUpStatus == RCC_CR_HSIRDY){/* 配置调节器电压输出级别为1 */RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;/* 配置SYSCLK到HCLK的分频系数为1 */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* 配置HCLK到PCLK1/2的分频系数为2/4 */RCC_PCLK2Config(RCC_HCLK_Div2);RCC_PCLK1Config(RCC_HCLK_Div4);/* 配置PLL参数,选⽤HSI作为PLL参数,同时使能PLL */RCC_PLLConfig(RCC_PLLSource_HSI, m, n, p, q);RCC_PLLCmd(ENABLE);/* 等待PLL设置完成 */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); FLASH->ACR = FLASH_ACR_PRFTEN| FLASH_ACR_ICEN| FLASH_ACR_DCEN| FLASH_ACR_LATENCY_5WS;RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while(RCC_GetSYSCLKSource() != 0x08);}else{while(1);}}HAL时钟配置分析:与STM32标准外设库不同,HAL库来实现时钟配置需要重新适应配置⽅式,但是本质的寄存器调动是类似不变的,且配置的过程也和STM32标准外设库相似;参考使⽤STMCube⽣成的代码,时钟树如图所⽰:在STM32Cube中设置:HSE设置为Crystal/Ceramic Resonator,Input Frequency设置为16MHz;在⼯程中要配置的参数:第⼀个HSE_VALUE参数位于stm32f0xx_hal_conf.h中,此参数与在STMCube时钟树上定义的⼀致,需要⼿动设置为实际的参数值;第⼆个HSE_VALUE参数位于system_stm32f0xx.c中,此参数默认为8MHz,可以通过⽤户程序来提供和调整;第三个SystemCoreClock参数位于system_stm32f0xx.c中,其默认值也是8MHz,可以根据以下三种⽅式来更新: 调⽤CMSIS函数SystemCoreClockUpdate()、 调⽤HAL API函数HAL_RCC_GetHCLKFreq()、 调⽤HAL_RCC_ClockConfig();/*** @brief Adjust the value of External High Speed oscillator (HSE) used in your application.* This value is used by the RCC HAL module to compute the system frequency* (when HSE is used as system clock source, directly or through the PLL).*/#if !defined (HSE_VALUE)#define HSE_VALUE ((uint32_t)16000000) /*!< Value of the External oscillator in Hz */#endif /* HSE_VALUE */#if !defined (HSE_VALUE)#define HSE_VALUE ((uint32_t)8000000)/*!< Default value of the External oscillator in Hz.This value can be provided and adapted by the user application. */#endif /* HSE_VALUE *//** @addtogroup STM32F0xx_System_Private_Variables* @{*//* This variable is updated in three ways:1) by calling CMSIS function SystemCoreClockUpdate()2) by calling HAL API function HAL_RCC_GetHCLKFreq()3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequencyNote: If you use this function to configure the system clock there is no need to call the 2 first functions listed above, since SystemCoreClock variable is updated automatically.uint32_t SystemCoreClock = 8000000;实际的时钟配置函数如下图:使⽤了三个参数来配置:RCC_OscInitStruct⽤来配置外部时钟参数,这⾥设置晶振类型为HSE、设置HSE的状态为开启状态、不使⽤PLL;RCC_ClkInitStruct⽤来配置系统时钟内的参数(如Sys CLK、HCLK、PCLK1),这⾥设置要配置的时钟类型为HCLK、SYSCLK、PCLK1,选择HSE时钟作为SYSCLK的时钟源,并设置系统时钟SYSCLK分频系数为0、HCLK的分频系数为4;PeriphClkInit⽤来配置外设时钟的时钟源,这⾥设置USART1/2的时钟源为PCLK1;/*** @brief System Clock Configuration* @retval None*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};/** Initializes the CPU, AHB and APB busses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB busses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){Error_Handler();}PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2;art1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;art2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){Error_Handler();}HAL_SYSTICK_Config(SystemCoreClock / 1000);HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);}这⾥加⼊了对SysTick的时钟配置,参考HAL库本⾝的设置:HAL_SYSTICK_Config()⽤来配置使能和配置SysTick寄存器;HAL_SYSTICK_CLKSourceConfig()选择AHB时钟(或AHB时钟除以8)作为SysTick时钟源;HAL_NVIC_SetPriority()配置SysTick_IRQn的中断优先级为0,默认为最⾼;。
stm32f105更换晶振及时钟配置
最近使用MDK515,调试stm32f105rbt6,使用MDK 的Manage Run-Time Environment建立好工程后,使用Systick时间老是不准,而定义的串口却能正常收发数据,奇了怪了。
记得是已经把<stm32f10x.h>里的#define HSE_VALUE ((uint32_t)8000000)改为实际使用的8MHz了啊。
再检查串口的波特率设置,原来串口使用的是RCC_GetClocksFreq(&RCC_ClocksStatus);获取时钟RCC_ClocksStatus.PCLK2_Frequency (USART1),而Systick设置时使用SysTick_Config(SystemCoreClock/1000);这两者肯定不一样。
那么,配置时钟有问题。
在SystemInit(); 中找到时钟配置函数static void SetSysClockTo72(void);发现其配置/* Configure PLLs ------------------------------------------------------*//* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |RCC_CFGR2_PREDIV1SRC_PLL2|RCC_CFGR2_PREDIV1_DIV5);主要是这里:PLL2CLK = (HSE / 5) * 8 = 40 MHz,也就是说SetSysClockTo72函数里的配置是以外部晶振(HSE)25M来配置的,因为单单修改HSE_VALUE并不能改变这里的配置,所以Systick定时不准确。
STM32单片机RTC时钟的使用方法及步骤
STM32单片机RTC时钟的使用方法及步骤
STM32RTC使用步骤:
打开PWR时钟和Backup区数据访问
若使用外部低速时钟(LSE),打开LSE并等待起振
选择和打开RTC时钟,等待时钟同步
配置时间格式,分频系数等
根据需要配置时钟,日期,闹钟,唤醒,输出,时间戳,备份寄存器等模块
根据需要配置和打开中断,其中
RTC Alarm ——EXTI line 17
RTC tamper and TImestamps——EXTI line 19
RTC wakeup——EXTI line 20
下面的代码配置日期,时间,当前时间设置为15年05月31日,星期日(7),15:50:40,打开闹钟A和唤醒中断,每一秒钟来一次中断,15:50:45秒产生闹钟中断,用串口打印相应的信息。
代码:
void RTC_Config(void)
{
RTC_TImeTypeDef RTC_TimeStructure;
RTC_DateTypeDef RTC_DateStructure;
RTC_InitTypeDef RTC_InitStructure;
RTC_AlarmTypeDef RTC_AlarmStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
PWR_BackupAccessCmd(ENABLE);
RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);
RCC_LSEConfig(RCC_LSE_ON);。
STM32单片机RTC时钟的使用方法及步骤
STM32单片机RTC时钟的使用方法及步骤一、配置RTC模块时钟源RTC模块的时钟源可以选择外部低速晶振(LSE)或者低速内部时钟(LSI)。
通过以下步骤配置RTC时钟源:1.使能外部低速晶振(LSE)或者低速内部时钟(LSI)。
例如,如果使用外部低速晶振,则需要使能相应的GPIO端口,并配置为晶振模式。
2.配置RCC时钟控制寄存器(RCC_CR)和时钟配置寄存器(RCC_CSR)。
二、使能RTC模块时钟1.使能PWR模块时钟和备份寄存器访问。
RCC_APB1ENR,=(1<<28);RCC_APB1ENR,=(1<<27);2.校验并关闭RTC模块。
RCC->BDCR,=RCC_BDCR_RTCEN;PWR->CR,=PWR_CR_DBP;if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0)RCC->BDCR,=RCC_BDCR_RTCEN;3.配置RTC时钟预分频器和提供给RTC的时钟源。
RTC->PRER ,= rtc_prescaler_value << RTC_PRER_PREDIV_S_Pos;RTC->PRER ,= 127 << RTC_PRER_PREDIV_A_Pos;RTC->CR&=~RTC_CR_FMT;三、配置RTC模块时间和日期1.关闭RTC时钟写保护功能。
RTC->WPR=0xCA;RTC->WPR=0x53;RTC->ISR,=RTC_ISR_INIT;while((RTC->ISR & RTC_ISR_INITF) == 0);2.配置RTC的时间和日期寄存器。
RTC->TR ,= (uint32_t)((hours / 10) << RTC_TR_Hours10_Pos);RTC->TR ,= (uint32_t)((hours % 10) << RTC_TR_Hours1_Pos);RTC->TR ,= (uint32_t)((minutes / 10) <<RTC_TR_Minutes10_Pos);RTC->TR ,= (uint32_t)((minutes % 10) <<RTC_TR_Minutes1_Pos);RTC->TR ,= (uint32_t)((seconds / 10) <<RTC_TR_Seconds10_Pos);RTC->TR ,= (uint32_t)((seconds % 10) <<RTC_TR_Seconds1_Pos);RTC->DR ,= (uint32_t)((year / 10) << RTC_DR_YT_Pos);RTC->DR ,= (uint32_t)((year % 10) << RTC_DR_YU_Pos);RTC->DR ,= (uint32_t)((month / 10) << RTC_DR_MT_Pos);RTC->DR ,= (uint32_t)((month % 10) << RTC_DR_MU_Pos);RTC->DR ,= (uint32_t)((day / 10) << RTC_DR_DT_Pos);RTC->DR ,= (uint32_t)((day % 10) << RTC_DR_DU_Pos);3.开启RTC时钟写保护功能。
STM32实时时钟RTC按键修改时间
User 文件夹下main.c #include "sys.h" #include "usart.h"#include "delay.h" #include "led.h" #include "key.h" #include "exti.h" #include "wdg.h" #include "timerx.h" #include "adc.h" #include "rtc.h" #include "12864.h" #include "ov7670.h"#include "usmart.h" #include "enc28j60.h"#include "uip.h" #include "uip_arp.h" #include "tapdev.h"#include "timer.h" #include "math.h" #include "string.h"#include "syn.h"//Mini STM32 开发板扩展实验21//ENC28J60 网络模块实验//正点原子@ALIENTEK//技术论坛: //广州市星翼电子科技有限公司void uip_polling(void);void Display_Time(void);void received_date(u8 *str);u16 Process_date(u8 q,u8 b,u8 s,u8 g);#define BUF ((struct uip_eth_hdr *)&uip_buf[0])u8 t,Addres_1=10,Addres_2=1,Addres_3=168,Addres_4=192; int main(void){Stm32_Clock_Init(9); //usart_init(72,9600); USART3_Init(36,9600); USART2_Init(36,9600); delay_init(72);LED_Init();LCD12864_InitPort(); LCD12864_Init();//系统时钟设置// 串口初始化为9600//延时初始化// 初始化与LED 连接的硬件接口//初始化LCD//KEY_Init();RTC_Init();// usmart_dev.init(72);EXTIX_Init();while(tapdev_init()){//初始化按键// 初始化RTC//初始化USMART//初始化ENC28J60 错误}; LCD_ShowString(3,0,"28J60 InitError!"); delay_ms(200);LCD12864_Clr();// 清除之前显示uip_init(); //uIP 初始化uip_ipaddr(ipaddr, 192,168,1,10); //设置本地设置IP 地址uip_sethostaddr(ipaddr);uip_ipaddr(ipaddr, 192,168,1,1); 〃设置网关IP地址(其实就是你路由器的IP地址) uip_setdraddr(ipaddr);uip_ipaddr(ipaddr, 255,255,254,0); //设置网络掩码uip_setnetmask(ipaddr);uip_listen(HTONS(1200));uip_listen(HTONS(80)); tcp_client_reconnect();while (1){ Display_Time(); //监听1200 端口,用于TCP Server//监听80 端口,用于Web ServerII尝试连接到TCP Server端,用于TCP Clientuip_polling(); //处理uip 事件,必须插入到用户程序的循环体中II key=KEY_Scan();if(tcp_client_tsta!=tcp_client_sta)IITCP Client 状态改变{ if(tcp_client_sta&(1<<7)){LCD_ShowString(3,0," 接收数据:");disp_IP();} else{ LCD_ShowString(3,0," 已断开! ");disp_IP();}if(tcp_clie nt_sta&(1<<6)) 〃收到新数据{IILCD12864_Clr(); II 清除之前显示received_date(tcp_client_databuf);tcp_client_sta&=~(1<<6);}tcp_client_tsta=tcp_client_sta;}delay_ms(1);usart3_Receive_Process();} } //uip 事件处理函数//必须将该函数插入用户主循环,循环调用.void uip_polling(void){u8 i;static struct timer periodic_timer, arp_timer;static u8 timer_ok=0;if(timer_ok==0)// 仅初始化一次{timer_ok = 1;timer_set(&periodic_timer,CLOCK_SECOND/2); //创建1 个0.5 秒的定时器timer_set(&arp_timer,CLOCK_SECOND*10); // 创建1 个10 秒的定时器}uip_len=tapdev_read(); //从网络设备读取一个IP 包,得到数据长度.uip_len 在uip.c 中定义if(uip_len>0) //有数据{//处理IP 数据包(只有校验通过的IP 包才会被接收) if(BUF->type ==htons(UIP_ETHTYPE_IP))// 是否是IP 包? {uip_arp_ipin(); // 去除以太网头结构,更新ARP 表uip_input(); //IP 包处理//当上面的函数执行后,如果需要发送数据,则全局变量uip_len > 0 //需要发送的数据在uip_buf, 长度是uip_len (这是 2 个全局变量) if(uip_len>0)// 需要回应数据{uip_arp_out();// 加以太网头结构,在主动连接时可能要构造ARP 请求tapdev_se nd();〃发送数据到以太网}}else if (BUF->type==htons(UIP_ETHTYPE_ARP))〃处理arp 报文,是否是ARP 请求包?{uip_arp_arpin();//当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf, 长度是uip_len( 这是 2 个全局变量) if(uip_len>O)tapdev_send();〃需要发送数据,则通过tapdev_send 发送}}else if(timer_expired(&periodic_timer)) //0.5 秒定时器超时{timer_reset(&periodic_timer); //复位0.5 秒定时器//轮流处理每个TCP连接,UIP_CONNS缺省是40个for(i=0;i<UIP_CONNS;i++){uip_periodic(i); //处理TCP 通信事件//当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf, 长度是uip_len (这是 2 个全局变量) if(uip_len>0){uip_arp_out();// 加以太网头结构,在主动连接时可能要构造ARP 请求tapdev_se nd();〃发送数据到以太网}}#if UIP_UDP //UIP_UDP//轮流处理每个UDP 连接, UIP_UDP_CONNS 缺省是10 个for(i=0;i<UIP_UDP_CONNS;i++){uip_udp_periodic(i); //处理UDP 通信事件//当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf, 长度是uip_len ( 这是 2 个全局变量) if(uip_len > 0){uip_arp_out();〃加以太网头结构,在主动连接时可能要构造ARP请求tapdev_se nd();〃发送数据到以太网}}#endif//每隔10 秒调用1次ARP 定时器函数用于定期ARP 处理,ARP 表10秒更新一次,旧的条目会被抛弃if(timer_expired(&arp_timer)){timer_reset(&arp_timer); uip_arp_timer();}}}void Display_Time(void){ if(t!=timer.sec){ t=timer.sec;LCD_ShowString(1,5," 星期");LCD_ShowString(0,3,"20");LCD_Shownum(0,4,(timer.w_year%100));LCD12684_Wdat(0x2d);LCD_Shownum1(timer.w_month);LCD12684_Wdat(0x2d);LCD_Shownum1(timer.w_date);switch(timer.week){case 0:LCD_ShowString(1,7," 日");break;case 1:LCD_ShowString(1,7," 一");break;case 2:LCD_ShowString(1,7," 二");break;case 3:LCD_ShowString(1,7," 三");break;case 4:LCD_ShowString(1,7," 四");break; case 5:LCD_ShowString(1,7," 五");break; case 6:LCD_ShowString(1,7," 六");break;}LCD_Shownum(1,0,timer.hour);LCD12684_Wdat(0x3a);LCD_Shownum1(timer.min);LCD12684_Wdat(0x3a);LCD_Shownum1(timer.sec);}}void received_date(u8 *str){ u8 len;len=(u8)strlen(str);switch(len){case 13: Addres_4= (u8)Process_date(0,(str[0]-0x30),str[1],str[2]); Addres_3=(u8)Process_date(0,(str[4]-0x30),str[5],str[6]); Addres_2=(u8)Process_date(0,0,str[8],str[9]);Addres_1=(u8)Process_date(0,0,str[11],str[12]); uip_ipaddr(ipaddr,Addres_4,Addres_3,Addres_2,Addres_1); 设置IP 地址uip_sethostaddr(ipaddr); tcp_client_reconnect();// 设置本地disp_IP(); break;case 19:RTC->CRH&=~(0X01);while(!(RTC->CRL&(1<<5))); //等待RTC 寄存器操作完成timer.w_year=(s16)Process_date(str[0]-0x30,str[1]-0x30,str[2],str[3]);timer.w_month=(s8)Process_date(0,0,str[5],str[6]);timer.w_date=(s8)Process_date(0,0,str[8],str[9]);timer.hour=(s8)Process_date(0,0,str[11],str[12]);timer.min=(s8)Process_date(0,0,str[14],str[15]);timer.sec=(s8)Process_date(0,0,str[17],str[18]);RTC_Set(timer.w_year,timer.w_month,timer.w_date,timer.hour,timer.min,timer.sec); // 设置时间RTC->CRH|=0X01;while(!(RTC->CRL&(1<<5))); // 等待RTC 寄存器操作完成break;case 6:case 7:case 8:case 9:case 10 :case 11 : LCD_ShowString(3,5,str);Speech(str);break;default : break;}}u16 Process_date(u8 q,u8 b,u8 s,u8 g){u16 temp; temp=q*1000+b*100+(s-0x30)*10+(g-0x30); return temp ;}HARDW ARE 文件夹下rtc。
STM32f407系统定时器时钟配置计算
STM32f407系统定时器时钟配置计算首先,我们需要配置系统定时器的时钟源。
STM32F407的系统定时器可以使用内部时钟源(HCLK/8)或外部时钟源。
通过软件配置,我们可以选择其中一种时钟源。
1.配置内部时钟源:要使用内部时钟源,可以通过RCC寄存器来配置。
具体需要做以下几步:a. 使能系统定时器时钟:在 RCC_APBxENR 寄存器中设置位SysTickEN=1,其中 x 为适当的 APBx 总线索引。
b.配置系统定时器时钟源:在STK_CTRL寄存器中设置位CLKSOURCE=12.配置外部时钟源:如果要使用外部时钟源作为系统定时器的时钟源,我们需要将外部时钟源与系统的时钟树相连。
具体的配置方法因时钟源的不同而不同,可参考具体芯片的参考手册。
配置了系统定时器的时钟源后,我们可以计算定时器中断的时间间隔。
系统定时器中断的时间间隔=(计数器周期)*(重载值+1)/(时钟频率)其中,计数器周期为24位,取值范围为0~2^24-1、时钟频率为系统定时器的时钟源频率。
重载值是计数器的初始值,当计数器减到0时,会触发定时中断。
举个例子,假设系统定时器的时钟源频率为8MHz,我们希望计算系统定时器中断每100ms触发一次的重载值。
中断触发周期 = 100ms = 0.1s时钟频率=8MHz=8*10^6Hz由于重载值需要为整数,我们可以将计算结果四舍五入为最接近的整数,即重载值为477以上就是STM32F407系统定时器时钟配置和计算方法的简要介绍。
配置完系统定时器的时钟源,并计算出需要的重载值后,我们可以通过编程设置相关寄存器,来开始使用系统定时器进行定时中断的任务。
STM32时钟配置方法详解
STM32时钟配置方法详解STM32是意法半导体(STMicroelectronics)公司推出的一系列32位Flash微控制器,被广泛应用于各种嵌入式系统中。
时钟是STM32微控制器的核心部分,正确配置时钟可以确保系统正常工作并达到预期的性能。
本文将详细介绍STM32时钟配置的方法。
1.时钟源:STM32微控制器提供了多个时钟源,包括内部时钟(HSI、LSI)和外部时钟(HSE、LSE)。
其中,HSI(高速内部时钟)是一个高频率(通常为8MHz)的内部RC振荡器,适用于低功耗应用;LSI(低速内部时钟)是一个低频率(通常为40kHz)的内部RC振荡器,用于RTC(实时时钟)模块;HSE(高速外部时钟)是一个外接的高频晶振,用于提供更精确的时钟信号;LSE(低速外部时钟)是一个外接的低频晶振,适用于RTC模块。
2.主频和系统时钟:主频是指CPU的时钟频率,系统时钟是指STM32微控制器的总线时钟,包括AHB(高性能总线)、APB1(低速外设总线)和APB2(高速外设总线)。
在进行STM32时钟配置之前,需要按照以下几个步骤来完成。
1.启用对应的时钟源:根据具体需求,选择合适的时钟源并启用相应的时钟。
可以通过设置RCC_CR寄存器和RCC_APB1ENR/RCC_APB2ENR寄存器来实现。
例如,要使用HSE作为时钟源,需要首先启用HSE时钟。
2.配置时钟分频器:为了使系统时钟不超过芯片规格要求的最大频率,需要对时钟进行分频。
分频器有两个,即AHB分频器和APB分频器。
可以通过设置RCC_CFGR寄存器来实现。
例如,将AHB分频器设置为8,将APB1和APB2分频器分别设置为4,可以将主频分别分频为8MHz、32MHz和64MHz。
3.等待时钟稳定:当启用外部时钟源时,需要等待时钟稳定。
可以通过读取RCC_CR寄存器的特定标志位来判断时钟是否稳定。
4. 配置Flash存储器的延时:根据主频的不同,需要设置Flash存储器的访问延时,以确保正常读写数据。
stm32外部时钟模式1
stm32外部时钟模式1基础了解时钟选择计数器时钟可由下列时钟源提供:●内部时钟(CK_INT)●外部时钟模式1:外部输⼊脚(TIx)●外部时钟模式2:外部触发输⼊(ETR)●内部触发输⼊(ITRx):使⽤⼀个定时器作为另⼀个定时器的预分频器在平常使⽤中我们系统复位 000 默认使⽤内部时钟源外部时钟源1来⾃定时器⾃⾝输⼊通道1或通道2的输⼊信号,经过极性选择和滤波以后⽣成的触发信号,连接到从模式控制器,进⽽控制计数器的⼯作;来⾃通道1的输⼊信号经过上升沿、下降沿双沿检测⽽⽣成的脉冲信号进⾏逻辑相或以后的信号就是TI1F_ED信号,即TI1F_ED双沿脉冲信号。
//SIGNAL_COUNT(GPIO)#define SIGNAL_COUNT_ENA_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() //PB0#define SIGNAL_COUNT_ENA_GPIO_Port (GPIOB)#define SIGNAL_COUNT_ENA_Pin (GPIO_PIN_0)#define SIGNAL_COUNT_DIR_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() //PA7#define SIGNAL_COUNT_DIR_GPIO_Port (GPIOA)#define SIGNAL_COUNT_DIR_Pin (GPIO_PIN_7)#define SIGNAL_COUNT_DIR_Get_IRQn (EXTI9_5_IRQn) //EXTI7中断//SIGNAL_COUNT(AFIO & TIM)#define SIGNAL_COUNT_PUL_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() //PA6#define SIGNAL_COUNT_PUL_GPIO_Port (GPIOA)#define SIGNAL_COUNT_PUL_Pin (GPIO_PIN_6)#define SIGNAL_COUNT_TIM_CLK_ENABLE() __HAL_RCC_TIM3_CLK_ENABLE() //TIM3#define SIGNAL_COUNT_Get_TIM (TIM3)#define SIGNAL_COUNT_Get_HTIM (htim3)//GPIO输⼊#define SIGNAL_COUNT_READ_DIR_IO() (SIGNAL_DIR_GPIO_Port -> IDR & SIGNAL_DIR_Pin)#define SIGNAL_COUNT_READ_ENA_IO() (SIGNAL_ENA_GPIO_Port -> IDR & SIGNAL_ENA_Pin)//TIM输⼊#define SIGNAL_COUNT_READ_COUNT() (SIGNAL_COUNT_Get_TIM -> CNT)//TIM输出#define SIGNAL_COUNT_UP() (SIGNAL_COUNT_Get_TIM -> CR1 &= ~(TIM_CR1_DIR))#define SIGNAL_COUNT_DOWN() (SIGNAL_COUNT_Get_TIM -> CR1 |= (TIM_CR1_DIR))/*** @brief TIM_SIGNAL_PUL初始化* @param NULL* @retval NULL**/void REIN_TIM_SIGNAL_COUNT_Init(void){/* GPIO初始化 */GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable*/SIGNAL_COUNT_PUL_CLK_ENABLE(); //启⽤SIGNAL_COUNT_PUL端⼝时钟/*Configure GPIO pin*/GPIO_InitStruct.Pin = SIGNAL_COUNT_PUL_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //输⼊模式GPIO_InitStruct.Pull = GPIO_NOPULL; //禁⽤上下拉HAL_GPIO_Init(SIGNAL_COUNT_PUL_GPIO_Port, &GPIO_InitStruct);/* TIM初始化 */TIM_SlaveConfigTypeDef sSlaveConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};SIGNAL_COUNT_TIM_CLK_ENABLE(); //启⽤TIM时钟SIGNAL_COUNT_Get_HTIM.Instance = SIGNAL_COUNT_Get_TIM;SIGNAL_COUNT_Get_HTIM.Init.Prescaler = 0; //预分频:0SIGNAL_COUNT_Get_HTIM.Init.CounterMode = TIM_COUNTERMODE_UP; //向上计数SIGNAL_COUNT_Get_HTIM.Init.Period = 65535; //16位周期SIGNAL_COUNT_Get_HTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //不分频SIGNAL_COUNT_Get_HTIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //禁⽤⾃动重新加载if (HAL_TIM_Base_Init(&SIGNAL_COUNT_Get_HTIM) != HAL_OK){Error_Handler();}sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; //外部时钟模式sSlaveConfig.InputTrigger = TIM_TS_TI1FP1; //TI1FP1sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; //上升沿触发sSlaveConfig.TriggerFilter = 4; //滤波参数(FDIV2_N6)if (HAL_TIM_SlaveConfigSynchro(&SIGNAL_COUNT_Get_HTIM, &sSlaveConfig) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; //主机模式触发复位sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; //禁⽤主机模式if (HAL_TIMEx_MasterConfigSynchronization(&SIGNAL_COUNT_Get_HTIM, &sMasterConfig) != HAL_OK){Error_Handler();}/*begin work*/HAL_TIM_Base_Start(&SIGNAL_COUNT_Get_HTIM);}static void Signal_Count_Capture_Goal(void){//SignalPort获取⽬标//读取En_Pinif(SIGNAL_COUNT_READ_ENA_IO()){if(sg_cut.en_inve)sg_cut.en_valid = true;elsesg_cut.en_valid = false;}else{if(sg_cut.en_inve)sg_cut.en_valid = false;elsesg_cut.en_valid = true;}//采样(对⽐上次的计数值)sg_cut.sampling_count_last = sg_cut.sampling_count;sg_cut.sampling_count = SIGNAL_COUNT_READ_COUNT();sg_cut.sampling_count_sub = sg_cut.sampling_count - sg_cut.sampling_count_last;//采样(缓冲输出)//(采样数/细分数)*Move_Divide_NUM = 电机输出步数sg_cut.interp_out = sg_cut.sampling_count_sub * sg_cut.subdivide_form;//输出if(sg_cut.en_valid){signal_moreio.goal_location = sg_cut.interp_out; //Count模式借⽤⽬标位置存放⽬标位置增量 signal_moreio.goal_disable = false;signal_moreio.goal_brake = false;}else{signal_moreio.goal_location = 0; //Count模式借⽤⽬标位置存放⽬标位置增量signal_moreio.goal_disable = true;signal_moreio.goal_brake = false;}}。
STM32时钟初始化流程
STM32时钟初始化流程
加载main函数之前(启动代码中LDRR0,=__main之前),HCLK 总线时钟默认上电是上一次断电前配置的频率。
加载到main时,被设定为system_stm32f1xx。
c中定义的SystemCoreClock的初始值;
加载到SystemClock_Config()函数时,调用了
HAL_RCC_ClockConfig()函数,该函数的最后根据前面配置好的时钟源、分频等更新了SystemCoreClock的值,即更新了总线时钟(因为32要求的时钟是固定的,比如外部时钟8M,所以直接可以根据时钟源和分频确定时钟频率)
正常运行,HCLK总线时钟保持这个时钟。
方法总结:
不明白STM 32的一些功能,那就从头去捋一遍,从启动文件开始,用上调试功能,事半功倍。
使用STM32的TIMER进行外部计数
使⽤STM32的TIMER进⾏外部计数使⽤ETR引脚的输⼊信号作为计数时钟,本例程使⽤Timer 2,其ETR输⼊引脚为PA1,该引脚⼯作模式为输⼊模式,Timer的⼯作模式为从模式;另外使⽤PC6输出⼀模拟⽅波时钟信号。
测试时将PC6与PA1短接。
(⽤户也可另外连接⼀个时钟信号到PA1引脚上。
)代码见下:int main(void){unsigned char i_Loop;unsigned char n_Counter;#ifdef DEBUGdebug();#endifRCC_Configuration(); // System Clocks ConfigurationNVIC_Configuration(); // NVIC configurationGPIO_Configuration(); // Configure the GPIO portsTIM_TimeBaseStructure.TIM_Period = 0xFFFF;TIM_TimeBaseStructure.TIM_Prescaler = 0x00;TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // Time base configurationTIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);TIM_SetCounter(TIM2, 0);TIM_Cmd(TIM2, ENABLE);for(i_Loop = 0; i_Loop < 100; i_Loop ++) {GPIO_SetBits(GPIOC, GPIO_Pin_6);Delay(10);GPIO_ResetBits(GPIOC, GPIO_Pin_6);Delay(10);}n_Counter = TIM_GetCounter(TIM2);while (1) {}}前三⾏进⾏了时钟、中断、和I/O⼝的配置。
STM32时钟源的介绍及使用方法——STM32时钟树
STM32时钟源的介绍及使⽤⽅法——STM32时钟树【温馨提⽰:以下内容均来⾃⽹友的⽆私奉献或书本的摘抄,在此表⽰感谢!】上图是STM32的时钟树,从树上我们可以看到,STM32的时钟有两个来源——内部时钟和外部时钟。
按时钟频率来分,⼜可分为⾼速时钟和低速时钟。
因此STM32的时钟有四个来源:⾼速外部时钟信号(HSE)、低速外部时钟信号(LSE)、⾼速内部时钟信号(HSI)和低速内部时钟信号(LSI)(图中分别⽤蓝⾊的①~④标注)。
①HSE⾼速外部时钟:由外部4~16MHz的晶体或有源晶振提供,通常采⽤8MHz。
②LSI低速外部时钟:外部晶体提供,主要是给实时时钟(RTC),⼀般为32.768kHz。
③HSI⾼速内部时钟:由内部RC振荡器产⽣的8MHz时钟,但不够稳定。
④LSI低速内部时钟:内部RC振荡器产⽣的供给RTC的时钟,频率在30kHz~60kHz之间,通常约40kHz。
时钟在STM32内部最终是供给四⼤块(图中⽤红⾊椭圆圈出):USB的48MHz时钟、系统时钟SYSCLK、实时时钟模块RTC、独⽴看门狗的时钟IWDGCLK。
其中最主要的,也是最⼤头是系统时钟SYSCLK,它可以是内部或外部⾼速时钟直接接过来,也可以内、外部⾼速时钟是PLL倍频后提供的,系统时钟再分别供给Cortex内核、SDIO、AHB总线、DMA、APB1、APB2等。
我们通常是采⽤外部8MHz⾼速时钟(HSE),所以着重说HSE。
我们以前⾯的GPIO上的时钟为例,由ST的Datasheet可知,GPIO是在APB2⾼速外设总线上的,图中绿⾊的线就是时钟的流程,我们⼀步步地来看。
8MHz外部晶体(或晶振)输⼊后,先经过⼀个开关PLLXTPRE(HSE divider for PLL entry),此开关决定对HSE进⾏2分频再输⼊到PLL或直接到PLL。
我们选择不分频。
这样时钟⼜到了第⼆个开关PLLSRC(PLL entry clock source),此开关决定PLL的时钟来源,是内部⾼速时钟⼆分频的时钟还是PLLXTPRE的输出。
STM32时钟配置方法详解
STM32时钟配置方法详解时钟树是STM32微控制器中一系列时钟源和时钟分频器的组成部分。
时钟树包括系统时钟、外设时钟和内核时钟。
系统时钟用于驱动整个微控制器系统的核心,外设时钟用于驱动各种外设,内核时钟用于驱动CPU的运算。
在进行时钟配置之前,首先需要了解系统所需的时钟频率。
在STM32中,系统时钟可以通过多种方式进行配置,例如使用外部晶体、外部时钟、内部RC振荡器或者PLL(锁相环)等方式。
外部晶体是一种常用的时钟源,可以提供高精度的时钟频率。
在使用外部晶体时,首先需要设置PLL的时钟源为外部晶体,并设置PLL输入除频器的分频系数。
然后,再根据系统所需的时钟频率,设置PLL的倍频系数,以得到最终的系统时钟频率。
外部时钟是从外部提供的时钟信号,一般用于测试和调试。
使用外部时钟时,需要设置PLL的时钟源为外部时钟,并设置PLL的倍频系数,以得到所需的系统时钟频率。
内部RC振荡器是一种低成本的时钟源,但是其频率不如外部晶体稳定和精确。
在使用内部RC振荡器时,需要设置PLL的时钟源为内部RC振荡器,并设置PLL的倍频系数,以得到所需的系统时钟频率。
PLL是一种用于产生稳定高频时钟的电路,可以从一个低频时钟源产生一个高频时钟源。
使用PLL时,需要设置其输入时钟源和倍频系数。
系统时钟的分频系数可以通过RCC_CFGR寄存器进行设置。
RCC_CFGR寄存器的各个位域用于配置系统时钟的分频系数,包括分频因子、APB1的分频系数、APB2的分频系数等。
外设时钟是用于驱动外设的时钟,可以由系统时钟分频得到。
外设时钟的分频系数可以通过RCC_CFGR寄存器及各个外设的控制寄存器进行设置。
内核时钟是用于驱动CPU的运算的时钟。
在STM32微控制器中,CPU 时钟可以由系统时钟分频得到,分频系数可以通过RCC_CFGR寄存器和FLASH_ACR寄存器进行设置。
除了上述方法之外,STM32还可以使用时钟配置工具进行时钟配置。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
方法(1):
第一步:在 main 函数中执行下面的函数(红色字体的 C 语句,根据自己的硬件的外部晶振大小而确定的)
//RCC_HSE_Configuration 函数设置 HSE 作为 PLL 的时钟源,不设置的话在 main 函数执行前执行了 SystemInit 函数
/*************************************
* 执行 SystemInit 函数后芯片内部时钟为:
* SYSCLK
72MHz
* AHB
72MHz
* PCLK1
36MHz
* PCLK2
72MHz
* PLL
72MHz
**************************************/
void RCC_HSE_Configuration(void)
FLASH_SetLatency(FLASH_Latency_2);//设置 FLASH 存储器延时时钟周期数 FLASH_Latency_2 2 延时周期 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//选择 FLASH 预取指缓存的模,预取指缓存使能
RCC_DeInit();//将外设 RCC 寄存器重设为缺省 RCC_HSICmd(ENABLE);//设置外部高速晶振(HSE) HSE 晶振打开(ON) while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);//等待 HSI 就绪
RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置 AHB 时钟(HCLK) RCC_SYSCLK_Div1 ----- AHB 时钟 = 系统时钟 RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速 AHB 时钟(PCLK2) RCC_HCLK_Div1 ----- APB2 时钟 = HCLK RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速 AHB 时钟(PCLK1) RCC_HCLK_Div2 ----- APB1 时钟 = HCLK/2
RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_9);//设置 PLL 时钟源及倍频系 RCC_PLLConfig(外部时钟分频因子,PLL 倍频系数) RCC_PLLCmd(ENABLE);//使能 PLL while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//检查指定的 RCC 标志位(PLL 准备好标志)设置与否
#if !defined HSE_VALUE #ifdef STM32F10X_CL #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ #else #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ #endif /* STM32F10X_CL */
STM32F10x 时钟系统框图:
STM32F10x 时钟系统设置 | 这个夏天 199271
STM32F10x 时钟系统设置 | 这个夏天 199271
由于 STM32F10x 库官方采用的是默认的外接 8MHz 晶振,因此造成很多用户也采用了 8MHz 的晶振,但是,8MHz 的晶振不是必须的,其他 频点的晶振也是可行的,只需/将外设 RCC 寄存器重设为缺省值
RCC_HSEConfig(RCC_HSE_ON);//设置外部高速晶振(HSE) HSE 晶振打开(ON)
if(RCC_WaitForHSEStartUp() == SUCCESS)//等待 HSE 起振,SUCCESS;HSE 晶振稳定且就绪
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//设置系统时钟(SYSCLK) while(RCC_GetSYSCLKSource() != 0x00);//0x00:HSI 作为系统时钟 }
#endif /* HSE_VALUE */
注意:以上是以外部晶振为 16MHz 为例
方法(2): 使用 STM32F10x 内部时钟来配置 STM32F10x 各个模块的系统时钟。(不推荐使用,内部 8MHz RC 振荡器不稳定)
//RCC_HSI_Configuration 设置 HSI 8MHz 作为 PLL 的时钟源 void RCC_HSI_Configuration(void) {
#endif /* HSE_VALUE */
改成:
#if !defined HSE_VALUE #ifdef STM32F10X_CL #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ #else #define HSE_VALUE ((uint32_t)16000000) /*!< Value of the External oscillator in Hz */ #endif /* STM32F10X_CL */
RCC_PCLK1Config(RCC_HCLK_Div2);//设置低速 AHB 时钟(PCLK1) RCC_HCLK_Div2 ----- APB1 时钟 = HCLK/2
FLASH_SetLatency(FLASH_Latency_2);//设置 FLASH 存储器延时时钟周期数 FLASH_Latency_2 2 延时周期 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//选择 FLASH 预取指缓存的模,预取指缓存使能
{
RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置 AHB 时钟(HCLK) RCC_SYSCLK_Div1 ----- AHB 时钟 = 系统时钟
RCC_PCLK2Config(RCC_HCLK_Div1);//设置高速 AHB 时钟(PCLK2) RCC_HCLK_Div1 ----- APB2 时钟 = HCLK
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//设置系统时钟(SYSCLK) while(RCC_GetSYSCLKSource() != 0x08);//0x08:PLL 作为系统时钟 } }
第二部:打开 stm32f10x.h,将
STM32F10x 时钟系统设置 | 这个夏天 199271