STM32单片机的系统定时器初始化设置

合集下载

STM32定时器配置(TIM1、TIM2、TIM3、TIM4、TIM5、TIM8)高级定时。。。

STM32定时器配置(TIM1、TIM2、TIM3、TIM4、TIM5、TIM8)高级定时。。。

STM32定时器配置(TIM1、TIM2、TIM3、TIM4、TIM5、TIM8)⾼级定时。

⽂章结构:——> ⼀、定时器基本介绍——> ⼆、普通定时器详细介绍TIM2-TIM5——> 三、定时器代码实例⼀、定时器基本介绍之前有⽤过野⽕的学习板上⾯讲解很详细,所以直接上野⽕官⽅的资料吧,作为学习参考笔记发出来⼆、普通定时器详细介绍TIM2-TIM52.1 时钟来源计数器时钟可以由下列时钟源提供:·内部时钟(CK_INT)·外部时钟模式1:外部输⼊脚(TIx)·外部时钟模式2:外部触发输⼊(ETR)·内部触发输⼊(ITRx):使⽤⼀个定时器作为另⼀个定时器的预分频器,如可以配置⼀个定时器Timer1⽽作为另⼀个定时器Timer2的预分频器。

由于今天的学习是最基本的定时功能,所以采⽤内部时钟。

TIM2-TIM5的时钟不是直接来⾃于APB1,⽽是来⾃于输⼊为APB1的⼀个倍频器。

这个倍频器的作⽤是:当APB1的预分频系数为1时,这个倍频器不起作⽤,定时器的时钟频率等于APB1的频率(36MHZ);当APB1的预分频系数为其他数值时(即预分频系数为2、4、8或16),这个倍频器起作⽤,定时器的时钟频率等于APB1的频率的2倍。

{假如APB1预分频为2(变成36MHZ),则定时器TIM2-5的时钟倍频器起作⽤,将变成2倍的APB1(2x36MHZ)将为72MHZ给定时器提供时钟脉冲。

⼀般APB1和APB2的RCC时钟配置放在初始化函数中例如下⾯的void RCC_Configuration(void)配置函数所⽰,将APB1进⾏2分频,导致TIM2时钟变为72MHZ输⼊。

如果是1分频则会是36MHZ输⼊,如果4分频:CKINT=72MHZ/4x2=36MHZ; 8分频:CKINT=72MHZ/8x2=18MHZ;16分频:CKINT=72MHZ/16x2=9MHZ}1//系统时钟初始化配置2void RCC_Configuration(void)3 {4//定义错误状态变量5 ErrorStatus HSEStartUpStatus;6//将RCC寄存器重新设置为默认值7 RCC_DeInit();8//打开外部⾼速时钟晶振9 RCC_HSEConfig(RCC_HSE_ON);10//等待外部⾼速时钟晶振⼯作11 HSEStartUpStatus = RCC_WaitForHSEStartUp();12if(HSEStartUpStatus == SUCCESS)13 {14//设置AHB时钟(HCLK)为系统时钟15 RCC_HCLKConfig(RCC_SYSCLK_Div1);16//设置⾼速AHB时钟(APB2)为HCLK时钟17 RCC_PCLK2Config(RCC_HCLK_Div1);18 //设置低速AHB时钟(APB1)为HCLK的2分频(TIM2-TIM5输⼊TIMxCLK频率将为72MHZ/2x2=72MHZ输⼊)19 RCC_PCLK1Config(RCC_HCLK_Div2);20//设置FLASH代码延时21 FLASH_SetLatency(FLASH_Latency_2);22//使能预取指缓存23 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);24//设置PLL时钟,为HSE的9倍频 8MHz * 9 = 72MHz25 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);26//使能PLL27 RCC_PLLCmd(ENABLE);28//等待PLL准备就绪29while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);30//设置PLL为系统时钟源31 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);32//判断PLL是否是系统时钟33while(RCC_GetSYSCLKSource() != 0x08);34 }35//允许TIM2的时钟36 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);37//允许GPIO的时钟38 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);39 }APB1的分频在STM32_SYSTICK的学习笔记中有详细描述。

stm32高级定时器使用教程

stm32高级定时器使用教程

STM32 高级定时器-PWM简单使用2010-04-14 14:49:29| 分类:STM32 | 标签:|举报|字号大中小订阅高级定时器与通用定时器比较类似,下面是一个TIM1 的PWM 程序,TIM1是STM32唯一的高级定时器。

共有4个通道有死区有互补。

先是配置IO脚:GPIO_InitTypeDef GPIO_InitStructure;/* PA8设置为功能脚(PWM) */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/*PB13 设置为PWM的反极性输出*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);/*开时钟PWM的与GPIO的*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);/*配置TIM1*/TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;void Tim1_Configuration(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;TIM_DeInit(TIM1); //重设为缺省值/*TIM1时钟配置*/TIM_TimeBaseStructure.TIM_Prescaler = 4000; //预分频(时钟分频)72M/4000=18KTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数TIM_TimeBaseStructure.TIM_Period = 144; //装载值18k/144=125hz 就是说向上加的144便满了 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置了时钟分割不懂得不管 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0; //周期计数器值不懂得不管TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); //初始化TIMx的时间基数单位/* Channel 1 Configuration in PWM mode 通道一的PWM */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //正向通道有效PA8 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //反向通道也有效 PB13TIM_OCInitStructure.TIM_Pulse = 40; //占空时间144 中有40的时间为高,互补的输出正好相反 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; //互补端的极性TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //空闲状态下的非工作状态不管 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //先不管TIM_OC1Init(TIM1,&TIM_OCInitStructure); //数初始化外设TIMx通道1这里2.0库为TIM_OCInit/* TIM1 counter enable开定时器*/TIM_Cmd(TIM1,ENABLE);/* TIM1 Main Output Enable 使能TIM1外设的主输出*/TIM_CtrlPWMOutputs(TIM1,ENABLE);}//设置捕获寄存器1void SetT1Pwm1(u16 pulse){TIM1->CCR1=pulse;}/*操作寄存器改变占空时间*//*****************************************************************************************************************TIM1的定时器通道时间1到4 分别为PB8 PA9 PA10 PA11 而互补输出分别为PB13 PB14PB15中止PB12 。

stm32f411定时开发实验原理

stm32f411定时开发实验原理

一、STM32F411芯片概述STM32F411是意法半导体公司推出的一款高性能的ARM Cortex-M4核心的微控制器芯片,具有丰富的外设接口和强大的计算能力,广泛应用于工业控制、智能家居、医疗设备等领域。

二、定时开发的意义定时开发是指在嵌入式系统中通过定时器实现定时触发某些任务或事件,例如定时采集传感器数据、定时控制某些执行单元等。

在实际应用中,定时开发可以提高系统的稳定性和实时性,优化系统资源的利用,提高系统的响应速度和性能。

三、定时器的工作原理定时器是嵌入式系统中常用的外设,用于产生精确的定时事件,并触发相应的中断或事件处理。

定时器通常由计数器和控制寄存器组成,计数器用于计数时钟脉冲,控制寄存器用于配置定时器的工作模式和触发条件。

四、STM32F411定时器的特点1. 多种定时器:STM32F411芯片内置了多个定时器,包括基本定时器(TIM6/TIM7)、通用定时器(TIM2/TIM3/TIM4/TIM5)、高级定时器(TIM1)。

不同的定时器具有不同的工作模式和功能,可以满足不同的应用需求。

2. 强大的时钟控制:STM32F411芯片具有丰富的时钟控制功能,可以为定时器提供精确的时钟源,并支持多种时钟分频和倍频配置,满足不同的定时精度要求。

3. 灵活的中断处理:定时器可以产生定时中断,并触发相应的中断处理程序,实现定时任务的实时响应和处理。

五、STM32F411定时开发实验原理在STM32F411芯片上实现定时开发,一般需要以下步骤:1. 初始化定时器:首先需要对所选择的定时器进行初始化配置,包括时钟源、工作模式、定时器周期等参数的设置。

2. 配置中断:根据实际需求,配置定时器的中断触发条件和相关中断优先级。

3. 编写中断处理程序:编写定时器中断的处理程序,用于响应定时触发的事件,并执行相应的任务或操作。

4. 启动定时器:将定时器启动,开始计时,等待定时中断的触发。

5. 完善其他相关功能:根据具体应用需求,可以进一步完善其他相关功能,如定时器的互联、定时器同步、定时器的PWM输出等。

stm32定时器初始化后自动进入一次中断问题

stm32定时器初始化后自动进入一次中断问题

stm32定时器初始化后⾃动进⼊⼀次中断问题今天在调试定时器时,定时器3出现了⾃动停⽌⼯作的问题,中断设置是每过⼀秒,进⼀次中断,相应标志位+1,然后每次都是在标志位=4时停⽌⼯作,但是有时候⼜能正常⼯作,暂时未解决。

在调试时,发现⼀个有趣的现象,本次项⽬我同时配置了定时器4,初始化后是DISABLE未使能状态,但是开始运⾏,定时器还是会进⼀次中断,相应的标志位+1,后⾯不能继续增加。

motor_run_time这个标志位在程序启动后会进⼀次中断导致+1,⽽我的定时器并未使能。

我的相关代码是初始化部分代码:TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //允许定时器4更新中断TIM_Cmd(TIM4, DISABLE); //关闭定时器4//定时器4中断服务函数void TIM4_IRQHandler(void){if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //溢出中断{motor_run_time++;}TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清除中断标志位}增加部分: TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清除中断标志位TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //允许定时器4更新中断TIM_Cmd(TIM4, DISABLE); //关闭定时器4//定时器4中断服务函数void TIM4_IRQHandler(void){if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //溢出中断{motor_run_time++;}TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清除中断标志位}。

stm32芯片初始控制码

stm32芯片初始控制码

stm32芯片初始控制码STM32芯片的初始控制码是用于初始化和配置芯片的一组指令。

这些指令在芯片上电后被执行,以确保芯片能够正常工作。

在开始编写初始控制码之前,我们需要了解芯片的基本信息,例如时钟频率、外设的配置等。

这些信息可以在芯片的数据手册中找到。

以下是一个示例的初始控制码,用于初始化STM32芯片:1. 设置系统时钟:- 配置时钟源,例如使用外部晶体振荡器或内部RC振荡器。

- 配置时钟分频器,例如设置主时钟频率为72MHz。

- 配置时钟系统,例如使能PLL锁相环。

2. 配置外设:- 配置GPIO引脚,例如设置某个引脚为输入或输出模式。

- 配置中断,例如使能某个引脚的中断功能。

- 配置定时器,例如设置定时器的时钟源和计数模式。

3. 初始化外设:- 初始化串口,例如配置波特率和数据位数。

- 初始化ADC,例如配置采样率和转换通道。

- 初始化DMA,例如配置传输方向和缓冲区地址。

4. 启动外设:- 启动定时器,例如使能定时器的计数功能。

- 启动ADC,例如使能ADC的转换功能。

- 启动DMA,例如使能DMA的传输功能。

5. 设置中断优先级:- 设置中断优先级,例如设置某个中断的优先级为高级或低级。

以上仅是一个示例,实际的初始控制码可能会根据具体的应用需求有所不同。

编写初始控制码时,需要根据芯片的数据手册和应用需求进行具体的配置和初始化。

需要注意的是,编写初始控制码需要一定的硬件和软件知识,并且需要仔细阅读芯片的数据手册以确保正确配置。

此外,初始控制码也需要根据具体的开发环境和开发工具进行调整和修改。

STM32设置定时器TIM2

STM32设置定时器TIM2

STM32如何设置定时器STM32如何设置定时器下面以stm32的TIM2作为实例一步步配置成为定时器:第一种对定时器的基本配置TIM_TimeBaseStructure.TIM_Period = 1000;//设置自动装载寄存器TIM_TimeBaseStructure.TIM_Prescaler = 35999; //分频计数TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择向上计数TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);TIM_Cmd(TIM2, ENABLE); //是能定时器始能定时器的中断:TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);在开启时钟里一定要打开TIM2的时钟,函数表达式如下:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);4:中断向量函数的编写:void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;#ifdef VECT_TAB_RAM //如果程序在ram中调试那么定义中断向量表在Ram 中否则在Flash中NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);#else /* VECT_TAB_FLASH *//* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);#endif/* Enable the TIM2 global Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}5:中断函数的编写:当有TIM2的无论哪个中断触发中断发生那么就会进入这个函数TIM2_IRQHandler(void)所以这个更新事件的中断判断要依靠以下语句:if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)按照以上步骤配置可以顺利进行定时器的基本定时应用第二种方法:/* Enable TIM2 Update interrupt [TIM2溢出中断允许]*/ TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);中断中的设置为:if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)。

stm32单片机设计定时器中断实现1s的led灯闪烁知识应用

stm32单片机设计定时器中断实现1s的led灯闪烁知识应用

stm32单片机设计定时器中断实现1s的led灯闪烁知识应用要实现1s的LED灯闪烁,可以使用STM32单片机的定时器中断来控制LED的开关。

以下是实现的步骤:1. 配置定时器:选择一个定时器(如TIM2)并设置适当的预分频和计数值,以实现1s的定时周期。

2. 配置中断:使能定时器中断,并将中断优先级设置为适当的值(较高优先级)。

3. 初始化LED引脚:将LED引脚设置为输出,并初始化为高电平(LED关闭)。

4. 编写中断处理程序:在中断处理程序(如TIM2_IRQHandler)中,切换LED引脚的状态。

例如,如果LED引脚当前为高电平,则将其设置为低电平,反之亦然。

5. 启动定时器:启动定时器以开始定时。

整个步骤如下所示的代码示例:```c#include "stm32fxx.h"void TIM2_IRQHandler(void){if(TIM2->SR & TIM_SR_UIF){TIM2->SR &= ~TIM_SR_UIF; // 清除中断标志位// 切换LED引脚状态if(GPIOC->ODR & GPIO_ODR_ODR0)GPIOC->ODR &= ~GPIO_ODR_ODR0; // 关闭LEDelseGPIOC->ODR |= GPIO_ODR_ODR0; // 打开LED}}int main(){// 初始化LED引脚RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // 使能GPIOC时钟GPIOC->MODER |= GPIO_MODER_MODER0_0; // 将PC0设置为输出模式GPIOC->OSPEEDR |= GPIO_OSPEEDR_OSPEED0; // 设置PC0输出速度// 配置定时器RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // 使能TIM2时钟TIM2->PSC = 8399; // 将预分频设置为8400-1,得到10kHz 的计数频率TIM2->ARR = 9999; // 将计数值设置为10000-1,得到1s的定时周期// 配置中断TIM2->DIER |= TIM_DIER_UIE; // 使能更新中断NVIC_EnableIRQ(TIM2_IRQn); // 使能TIM2中断NVIC_SetPriority(TIM2_IRQn, 0); // 设置TIM2中断优先级为最高// 启动定时器TIM2->CR1 |= TIM_CR1_CEN; // 启动TIM2定时器while(1){// 程序主循环}return 0;}```以上代码使用了TIM2定时器和PC0引脚作为LED灯的控制。

stm32pwm初始化函数

stm32pwm初始化函数

stm32pwm初始化函数一、概述PWM(Pulse Width Modulation,脉宽调制)是一种常用的控制技术,用于控制电机、LED等电子设备的亮度或速度。

在STM32中,PWM也是一种常用的控制技术。

本文将介绍如何在STM32中初始化PWM。

二、硬件配置在使用PWM之前,需要先配置好STM32的硬件。

具体步骤如下:1. 选择一个可用的定时器(TIM)。

2. 配置该定时器的时钟源和分频系数。

3. 配置该定时器的计数模式和自动重载寄存器ARR(Auto-Reload Register)的值。

4. 配置输出比较通道(OC)。

5. 配置GPIO引脚作为OC输出口。

三、软件实现1. 初始化定时器首先需要初始化定时器。

具体步骤如下:1. 开启TIMx时钟(x为所选定时器编号)。

2. 设置TIMx分频系数和计数模式。

常见的计数模式有向上计数模式和向下计数模式,可以根据具体需求选择。

3. 设置自动重载寄存器ARR的值。

ARR决定了PWM波形周期长度,可以根据具体需求设置不同的值。

4. 使能更新事件中断,并开启TIMx中断。

5. 启动定时器。

2. 配置输出比较通道接下来需要配置输出比较通道。

具体步骤如下:1. 选择一个可用的输出比较通道(OC)。

2. 配置该OC的工作模式。

常见的工作模式有PWM1模式和PWM2模式,可以根据具体需求选择。

3. 配置该OC的输出极性。

常见的输出极性有正极性和负极性,可以根据具体需求选择。

4. 配置该OC的占空比。

占空比决定了PWM波形高电平时间与周期时间之比,可以根据具体需求设置不同的值。

3. 配置GPIO引脚最后需要配置GPIO引脚作为OC输出口。

具体步骤如下:1. 开启GPIOx时钟(x为所选GPIO端口编号)。

2. 配置该GPIO引脚为AF(Alternate Function)模式,并设置AF 编号为TIMx_CHy(y为所选OC通道编号)。

3. 配置该GPIO引脚的输出类型、驱动能力、上拉/下拉等属性。

STM32F103常用的初始化步骤(第一部分2020年2月)

STM32F103常用的初始化步骤(第一部分2020年2月)
NVIC_Init();
USART_ITConfig();
6、使能串口
USART_Cmd();
编写中断处理函数
USART1_IRQHandler()
{
}
外部中断初始化过程
1、初始化IO口为输入(使能IO、初始化IO)
2、开启AFIO时钟
3、设置IO口与中断线的映射关系
GPIO_EXTILineConfig();
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line3);
//清除 LINE 上的中断标志位
}
}
IWDG过程
WWDG过程
1、取消寄存器写保护(向IWDG_KR写入0X5555)
IWDG_WriteAccessCmd();
2、设置独立看门狗的预分频系数和重装载值
IWDG_SetPrescaler();
//CC1P=1设置为下降沿捕获
……
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update);
//清除中断标志位
}
电容触摸按键:
见原子代码。
FSMC初始化
1、GPIO,FSMC,AFIO时钟使能;
2、GPIO初始化:GPIO_Init()函数;
3、FSMC初始化:FSMC_NORSRAMInit()函数;
串口初始化代码方式一
串口初始化代码方式二
串口初始化代码方式三(推荐使用)
1、使能IO和USART
2、初始化IO
3、NVIC初始化
4、USART初始化
5、开启中断
USART_ITConfig();
6、使能串口

STM32笔记(五)RTC的初始化

STM32笔记(五)RTC的初始化

STM32笔记(五)RTC的初始化这次是RTC的笔记:)RTC这东西晕晕的,因为一个模块涉及到了RTC,BKP,RCC多个模块,之间的关系让人有点模糊入门的知识请大家看手册,我来总结:总之,RTC只是个能靠电池维持运行的32位定时器over!所以,使用时要注意以下问题:1. 上电后要检查备份电池有没有断过电。

如何检查?恩,RTC的示例代码中已经明示:往备份域寄存器中写一个特殊的字符,备份域寄存器是和RTC一起在断电下能保存数据的。

上电后检查下这个特殊字符是否还存在,如果存在,ok,RTC的数据应该也没丢,不需要重新配置它如果那个特殊字符丢了,那RTC的定时器数据一定也丢了,那我们要重新来配置RTC了这个过程包括时钟使能、RTC时钟源切换、设置分频系数等等,这个可以参考FWLib\example\RTC\Calendar的代码在我的这个实例里,检查备份域掉电在Init.c的RTC_Conig()中,函数内若检测到BKP掉电,则会调用RTC_Configuration()2. 因为RTC的一些设置是保存在后备域中的,so,操作RTC的设置寄存器前,要打开后备域模块中的写保护功能。

3. RTC设定值写入前后都要检查命令有没有完成,调用RTC_WaitForLastTask();具体的RTC初始化代码如下:////////////////////////////////////////////////////////////////////////////////// RTC时钟初始化!/////////////////////////////////////////////////////////////////////////////////****************************************************************************** ** Function Name : RTC_Configuration* Description : 来重新配置RTC和BKP,仅在检测到后备寄存器数据丢失时使用* Input : None* Output : None* Return : None******************************************************************************* /void RTC_Configuration(void){//启用PWR和BKP的时钟(from APB1)RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//后备域解锁PWR_BackupAccessCmd(ENABLE);//备份寄存器模块复位BKP_DeInit();//外部32.768K其哟偶那个RCC_LSEConfig(RCC_LSE_ON);//等待稳定while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);//RTC时钟源配置成LSE(外部32.768K)RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//RTC开启RCC_RTCCLKCmd(ENABLE);//开启后需要等待APB1时钟与RTC时钟同步,才能读写寄存器RTC_WaitForSynchro();//读写寄存器前,要确定上一个操作已经结束RTC_WaitForLastTask();//设置RTC分频器,使RTC时钟为1Hz//RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)RTC_SetPrescaler(32767);//等待寄存器写入完成RTC_WaitForLastTask();//使能秒中断RTC_ITConfig(RTC_IT_SEC, ENABLE);//等待写入完成RTC_WaitForLastTask();return;}/****************************************************************************** ** Function Name : RTC_Config* Description : 上电时调用本函数,自动检查是否需要RTC初始化,* 若需要重新初始化RTC,则调用RTC_Configuration()完成相应操作* Input : None* Output : None* Return : None******************************************************************************* /void RTC_Config(void){//我们在BKP的后备寄存器1中,存了一个特殊字符0xA5A5//第一次上电或后备电源掉电后,该寄存器数据丢失,//表明RTC数据丢失,需要重新配置if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5){//重新配置RTCRTC_Configuration();//配置完成后,向后备寄存器中写特殊字符0xA5A5BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);}else{//若后备寄存器没有掉电,则无需重新配置RTC//这里我们可以利用RCC_GetFlagStatus()函数查看本次复位类型if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET){//这是上电复位}else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET){//这是外部RST管脚复位}//清除RCC中复位标志RCC_ClearFlag();//虽然RTC模块不需要重新配置,且掉电后依靠后备电池依然运行//但是每次上电后,还是要使能RTCCLK???????//RCC_RTCCLKCmd(ENABLE);//等待RTC时钟与APB1时钟同步//RTC_WaitForSynchro();//使能秒中断RTC_ITConfig(RTC_IT_SEC, ENABLE);//等待操作完成RTC_WaitForLastTask();}#ifdef RTCClockOutput_Enable/* Enable PWR and BKP clocks */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE);/* Disable the Tamper Pin */BKP_TamperPinCmd(DISABLE);/* Enable RTC Clock Output on Tamper Pin */BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);#endifreturn;}。

stm32基本定时器计数值主动清零的方法

stm32基本定时器计数值主动清零的方法

文章标题:如何实现STM32基本定时器计数值主动清零的方法1. 引言在嵌入式系统开发中,STM32微控制器是一个非常流行的选择。

其中,基本定时器是一个非常重要的模块,用于产生基本的定时脉冲和定时中断。

在使用基本定时器时,我们经常会遇到计数值的清零操作。

本文将重点探讨如何实现STM32基本定时器计数值的主动清零方法,旨在帮助开发者更全面地理解和应用基本定时器。

2. 理解基本定时器基本定时器是STM32微控制器中的一个重要模块,用于生成定时脉冲和定时中断。

它通常包括计数器、自动重装载寄存器和控制寄存器等部分。

在使用基本定时器时,我们需要了解其工作原理和使用方法,以便更好地应用和优化。

3. 计数值自动清零的方法在实际开发中,我们常常需要在特定条件下主动清零基本定时器的计数值。

这种操作可以通过控制寄存器来实现。

具体的方法包括以下几个步骤:3.1 设置计数值在使用基本定时器前,首先需要设置计数值,确定定时周期和分频系数等参数。

这一步在定时器初始化的过程中完成,是基本定时器工作的基础。

3.2 主动清零当需要主动清零计数值时,我们可以通过修改控制寄存器的方式来实现。

在STM32中,通常使用指令对控制寄存器进行设置,从而达到主动清零的目的。

4. 实例分析为了更具体地说明上述方法,我们可以以一个简单的实例来进行分析。

假设我们需要在某个条件满足时,主动清零基本定时器的计数值,以实现定时器控制。

这时,我们可以通过修改控制寄存器的方式,将计数值主动清零,从而实现我们的需求。

5. 个人观点和总结在实际开发中,灵活掌握基本定时器的使用方法对于优化系统性能和实现特定功能至关重要。

计数值的主动清零是基本定时器功能的重要应用之一,通过合理的控制方法,我们可以更好地实现定时器控制和优化系统性能。

在使用基本定时器时,我们应该充分了解其工作原理和各寄存器的作用,灵活运用控制方法,以实现特定的功能要求。

总结:本文围绕STM32基本定时器计数值主动清零的方法进行了探讨,从理论到实际应用都进行了详细的介绍。

STM32HAL库学习系列第4篇定时器TIM-----开始定时器与PWM输出配置

STM32HAL库学习系列第4篇定时器TIM-----开始定时器与PWM输出配置

STM32HAL库学习系列第4篇定时器TIM-----开始定时器与PWM输出配置基本流程:1.配置定时器2.开启定时器3.动态改变pwm输出,改变值HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);函数总结:1 __HAL_TIM_SET_COMPARE()// 是设置CCRx,⼀般是⽤在PWM输出的,控制PWM占空⽐2 __HAL_TIM_GET_COMPARE // 是⽤来读取CCRx的,⼀般⽤于捕获处理PWM输出配置:频率设置:1static void MX_TIM2_Init(void)2 {3 TIM_MasterConfigTypeDef sMasterConfig;4 TIM_IC_InitTypeDef sConfigIC;5 TIM_OC_InitTypeDef sConfigOC;6 htim2.Instance = TIM2;7 htim2.Init.Prescaler = (36-1); //实际时钟频率为 72M/36=2MHz /40000=50H,-----490HZ,改变观察电机输出状态定时器预分频器8 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;9 htim2.Init.Period = (4082-1); //定时器周期配置 PWM频率为 490KHz 定义定时器周期,PWM频率为:168MHz/ (L298N_TIMx_PRESCALER+1)/ (L298N_TIM_PERIOD+1)10//⾼级定时器重复计数寄存器值11 **⾼级才有12// 定义⾼级定时器重复计数寄存器值13//实际PWM频率为:72MHz/(L298N_TIMx_PRESCALER+1)/(L298N_TIM_PERIOD+1)/(L298N_TIM_REPETITIONCOUNTER+1)14#define L298N_TIM_REPETITIONCOUNTER 015 **刹车和死区配置:1/* 刹车和死区时间配置 */2 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;3 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;4 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;5 sBreakDeadTimeConfig.DeadTime = 0;6 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;7 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;8 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;9 HAL_TIMEx_ConfigBreakDeadTime(&htimx_L298N, &sBreakDeadTimeConfig);基于通信的pwm频率和脉宽的更新控制算法:1/*2** pwm是否需要更新,⽐较上⼀次的频率和脉宽值,如果不同,则更新3*/4void pwm_update_loop( void )5 {6/*1,第⼀路判断: 频率或占空⽐发⽣变化 */7if( (HLM_SOKO_I_FREQ != HLM_SOKO_I_FREQ_LAST ) ||8 HLM_SOKO_I_DUTY != HLM_SOKO_I_DUTY_LAST )9 {10/* 更新频率和占空⽐的记录值 */11 HLM_SOKO_I_FREQ_LAST = HLM_SOKO_I_FREQ;12 HLM_SOKO_I_DUTY_LAST = HLM_SOKO_I_DUTY;13/* 更新当前通道的PWM波形 */14 pwm_update( PWM_I,HLM_SOKO_I_FREQ, HLM_SOKO_I_DUTY );15 }1617/*2,第⼆路判断 */18if( (HLM_SOKO_II_FREQ != HLM_SOKO_II_FREQ_LAST ) ||19 HLM_SOKO_II_DUTY != HLM_SOKO_II_DUTY_LAST )20 {21/* 更新频率和占空⽐的记录值 */22 HLM_SOKO_II_FREQ_LAST = HLM_SOKO_II_FREQ;23 HLM_SOKO_II_DUTY_LAST = HLM_SOKO_II_DUTY;24/* 更新当前通道的PWM波形 */25 pwm_update( PWM_II,HLM_SOKO_II_FREQ, HLM_SOKO_II_DUTY );26 }2728/*3,第三路判断 */29if( (HLM_SOKO_III_FREQ != HLM_SOKO_III_FREQ_LAST ) ||30 HLM_SOKO_III_DUTY != HLM_SOKO_III_DUTY_LAST )31 {32/* 更新频率和占空⽐的记录值 */33 HLM_SOKO_III_FREQ_LAST = HLM_SOKO_III_FREQ;34 HLM_SOKO_III_DUTY_LAST = HLM_SOKO_III_DUTY;35/* 更新当前通道的PWM波形 */36 pwm_update( PWM_III,HLM_SOKO_III_FREQ, HLM_SOKO_III_DUTY );37 }38 }补充:开起定时器功能只要在相应的定时器下开始内部时钟源即可使⽤定时器功能定时器内部动能:定时器时钟配置:M是10的6次⽅微秒是10的-6次⽅内部时钟设置为不分频(CKD),则CK_PSC的时钟频率等于APB1的时钟频率108MHz,即108000 000Hz。

一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现

一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现

一文带你看懂Stm32定时器+ADC+DMA进行AD采样的实现此STM32单片机为STM32F103系列的STM32的ADC有DMA功能这都毋庸置疑,也是我们用的最多的!然而,如果我们要对一个信号(比如脉搏信号)进行定时采样(也就是隔一段时间,比如说2ms),有三种方法:1、使用定时器中断每隔一定时间进行ADC转换,这样每次都必须读ADC的数据寄存器,非常浪费时间!2、把ADC设置成连续转换模式,同时对应的DMA通道开启循环模式,这样ADC就一直在进行数据采集然后通过DMA把数据搬运至内存。

但是这样做的话还得加一个定时中断,用来定时读取内存中的数据!3、使用ADC的定时器触发ADC转换的功能,然后使用DMA进行数据的搬运!这样只要设置好定时器的触发间隔,就能实现ADC定时采样转换的功能,然后可以在程序的死循环中一直检测DMA转换完成标志,然后进行数据的读取,或者使能DMA转换完成中断,这样每次转换完成就会产生中断,我是采用第二种方法。

下面上代码:我这里使用的单通道//定时器初始化voidTIM2_ConfiguraTIon(void){TIM_TImeBaseInitTypeDefTIM_TimeBaseStructure;TIM_OCInitTypeDefTIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);TIM_TimeBaseStructure.TIM_Period=1999;//设置2ms一次TIM2比较的周期TIM_TimeBaseStructure.TIM_Prescaler=71;//系统主频72M,这里分频71,相当于1000K 的定时器2时钟TIM_TimeBaseStructure.TIM_ClockDivision=0x0;。

STM32单片机RTC时钟的使用方法及步骤

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时钟写保护功能。

STM32Cubemx配置定时器定时1mS

STM32Cubemx配置定时器定时1mS

STM32Cubemx配置定时器定时1mS 最近才发现原来我把定时器⾥的配置参数代表的意义给搞混了,这⾥记录⼀下,防⽌以后⾃⼰忘记。

以建⽴⼀个定时1mS定时器为例: 1、先打开定时器 2、配置好时钟 3、配置定时器设置 重点来了,以前在这⾥我⼀直以为这⾥配置的就是时间,然后在调频率的时候,⼀直不对劲,知道查阅了硬⽯的资料才发现,这⾥配置的是进⼊定时器中断的频率,然后要定的时间要跟据这个频率来定时的。

由这个图可见,这⾥配置的是定时器产⽣中断的频率,然后再跟据频率与时间的关系推出定时的时间。

所以定时器频率为 f = 72M / Prescaler / Period = 72000 000 / 72 /1000 = 1000Hz; 定时时间T = 1 / f 则: 1s / 1000Hz = 1000 000us / 1000Hz = 1000us =1ms。

这样就可以定时1ms了啦,如果要做PWM频率调频,就直接改 pre 与 per 算出 f 就可以了。

具体公式如下图(上⾯的计算我是为了⽅便理解把公式逆运算了⼀次): 最后使⽤定时器中断跟关闭定时器中断以及回调函数即可, 使⽤中断的时候注意要先开启中断HAL_TIM_Base_Start_IT(&htim1); //使⽤定时器的时候调⽤这个函数启动HAL_TIM_Base_Stop_IT(&htim1); //停⽌定时器的时候调⽤这个函数关闭void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if(htim->Instance == TIM1) { //编写回调逻辑,即定时器1定时1MS后的逻辑 }}补充:最后记得⽣成STM32Cubemx⽂件时打开定时器中断,不然进不了回调函数,⼀般的话习惯⽤TIM3做定时器。

STM32时钟初始化流程

STM32时钟初始化流程

STM32时钟初始化流程
加载main函数之前(启动代码中LDRR0,=__main之前),HCLK 总线时钟默认上电是上一次断电前配置的频率。

加载到main时,被设定为system_stm32f1xx。

c中定义的SystemCoreClock的初始值;
加载到SystemClock_Config()函数时,调用了
HAL_RCC_ClockConfig()函数,该函数的最后根据前面配置好的时钟源、分频等更新了SystemCoreClock的值,即更新了总线时钟(因为32要求的时钟是固定的,比如外部时钟8M,所以直接可以根据时钟源和分频确定时钟频率)
正常运行,HCLK总线时钟保持这个时钟。

方法总结:
不明白STM 32的一些功能,那就从头去捋一遍,从启动文件开始,用上调试功能,事半功倍。

STM32时钟初始化函数SystemInit()详解

STM32时钟初始化函数SystemInit()详解

STM32时钟初始化函数SystemInit()详解花了⼀天的时间,总算是了解了SystemInit()函数实现了哪些功能,初学STM32,,现记录如下(有理解错误的地⽅还请⼤侠指出):使⽤的是3.5的库,⽤的是STM32F107VC,开发环境RVMDK4.23我已经定义了STM32F10X_CL,SYSCLK_FREQ_72MHz函数调⽤顺序:startup_stm32f10x_cl.s(启动⽂件)→ SystemInit() → SetSysClock () → SetSysClockTo72()初始化时钟⽤到的RCC寄存器复位值:RCC_CR = 0x0000 xx83; RCC_CFGR = 0x0000 0000;RCC_CIR = 0x0000 0000; RCC_CF GR2 = 0x0000 0000;SystemInit()在调⽤ SetSysClock()之前RCC寄存器的值如下(都是⼀些与运算,或运算,在此就不赘述了):RCC->CR = 0x0000 0083;内、外部⾼速时钟的选择使能、就绪标志RCC->CIR = 0x00FF0000; LSI、LSE、HIS、HSE、PLL就绪中断标志RCC->CFGR2 = 0x00000000;系统时钟源切换及状态⾄于这些寄存器都代表着什么意思,详见芯⽚资料RCC寄存器,该⽂重点不在此处;SetSysClock()函数如下:static void SetSysClock(void){#ifdef SYSCLK_FREQ_HSESetSysClockToHSE();#elif defined SYSCLK_FREQ_24MHzSetSysClockTo24();#elif defined SYSCLK_FREQ_36MHzSetSysClockTo36();#elif defined SYSCLK_FREQ_48MHzSetSysClockTo48();#elif defined SYSCLK_FREQ_56MHzSetSysClockTo56();#elif defined SYSCLK_FREQ_72MHz//我的定义的是SYSCLK_FREQ_72MHz,所以调⽤SetSysClockTo72()SetSysClockTo72();#endif}SetSysClockTo72()函数如下:static void SetSysClockTo72(void){__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*//* Enable HSE */RCC->CR |= ((uint32_t)RCC_CR_HSEON);1、使能外部晶振/* 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){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}if (HSEStatus == (uint32_t)0x01){/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;⼀、先设AHB APB1 AHB2分频寄存器RCC->CFGR/* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;2、系统时钟不分频作为AHB频率所以AHB等于SYSCLK频率0xxx: system clock not divided Bits 7:4 HPRE: AHB prescaler:Set and cleared by software t o control AHB clock division factor./* PCLK2 = HCLK/2 */RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;3、AHB时钟2分频作为⾼速APB2时钟故APB2 =(AHB=SYSCLK)/2PPRE2: APB high-speed prescaler (APB2)Set and cleared by software to control APB high-speed clock division factor.0xx: AHB clock not divided/* PCLK1 = HCLK */RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;4、AHB时钟4分频作为低速APB1时钟故APB1 =(APB2=AHB=SYSCLK)/4,所以定时器2~7时钟为2倍APB1,为60M--参加⽂章:STM32中定时器的时钟源PPRE1: APB Low speed prescaler (APB1)Set and cleared by software to control APB low-speed clock division factor.100: AHB clock divided by 2#ifdef STM32F10X_CL⼆、配置PLL2时钟频率/* Configure PLLs ------------------------------------------------------*//* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz *//* Configure the main PLL */RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);5、所以PLL时钟=8M/8*240/2=1 20M SYSCLK=AHB=120M,PLL时钟=8M/8*240/2=120M,APB2=60M,APB1=30M(upt项⽬时钟)RCC_PLLCFGR_PLLSRC_HSE:Bit 22 PLLSRC: Main PLL(PLL) and audio PLL (PLLI2S) entry clock source1: HSE oscillator clock selected as PLL and PLLI2S clock entryBits 17:16 PLLP: Main PLL (PLL) division factor for main system clockPLL output clock frequency = VCO frequency / PLLP with PLLP = 2, 4, 6, or 800: PLLP = 2f(PLL general clock output) = f(VCO clock) / PLLP,///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define PLL_M 8#define PLL_N 240#define PLL_P 2/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */#define PLL_Q 5///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* Enable the main PLL */RCC->CR |= RCC_CR_PLLON; 6、使能PLL时钟Bit 24 PLLON: Main PLL (PLL) enableSet and cleared by software to enable PLL./* 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_3WS;/* Select the main PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= RCC_CFGR_SW_PLL;7、将PLL作为系统时钟Bits 1:0 SW: System clock switchSet and cleared by software to select the system clock source.Set by hardware to force the HSI selection when leaving the Stop or Standby mode or incase of failure of the HSE oscillator used directly or indirectly as the system clock.00: HSI oscillator selected as system clock01: HSE oscillator selected as system clock10: PLL selected as system clock11: not allowed/* Wait till the main PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);{}1:AHB, APB1,APB2时钟确定//HCLK = SYSCLK ,从下⾯的分析可以得出SYSCLK是使⽤PLLCLK时钟的,也就是72MHZ(⾄于72MHZ如何得来,请看下⾯分析)//那么就是HCLK(AHB总线时钟)=PLLCLK = 72MHZ//AHB总线时钟等于系统时钟SYSCLK,也就是 AHB时钟 = HCLK = SYSCLK = 72MHZ/* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;//PLCK2等于HCLK⼀分频,所以PCLK2 = HCLK,HCLK = 72MHZ, 那么PLCK2(APB2总线时钟) = 72MHZ//APB2总线时钟等于HCLK的⼀分频,也就是不分频;APB2 时钟 = HCLK = SYSCLK = 72M HZ/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;//PCLK1 = HCLK / 2;PCLK1 等于HCLK时钟的⼆分频,那么PCLK1(APB1) = 72MHZ / 2 = 36MHZ//APB1总线时钟等于HCLK的⼆分频,也就是APB1时钟= HCLK / 2 = 36MHZ/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;2:如何得出SYSCLK(系统时钟)为72MHZ(外部晶振25MHZ)//记得参考英⽂芯⽚资料的时钟树P115页和RCC时钟寄存器进⾏理解RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);RCC_CFGR2_PREDIV2_DIV5: PREDIV2 = 5; 5分频也就是PREDIV2对输⼊的外部时钟 5分频,那么PLL2和PLL3没有倍频前是25 /5 = 5MHZ RCC_CFGR2_PLL2MUL8 : PLL2MUL = 8; 8倍频8倍频后,PLL2时钟 = 5 * 8 = 40MHZ; 因此 PLL2CLK = 40MHZRCC_CFGR2_PREDIV1SRC_PLL2 : RCC_CFGR2的第16位为1,选择PLL2CLK 作为PRED IV1的时钟源RCC_CFGR2_PREDIV1_DIV5:PREDIV1 = 5;PREDIV1对输⼊时钟5分频PREDIV1CLK = PLL2CLK / 5 = 8MHZ以上是对RCC_CFGR2进⾏的配置--------------------------------------------------------------------------------------RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PR EDIV1 |RCC_CFGR_PLLMULL9);RCC_CFGR_PLLXTPRE_PREDIV1 :操作的是RCC_CFGR的第17位PLLXTPRE,操作这⼀位和操作RCC_CFGR2寄存器的位[3:0]中的最低位是相同的效果RCC_CFGR_PLLSRC_PREDIV1 :选择PREDIV1输出作为PLL输⼊时钟;PREDIV1CLK = 8MHZ,所以输⼊给PLL倍频的时钟源是8MHZRCC_CFGR_PLLMULL9 :PLLMUL = 9;PLL倍频系数为9,也就是对 PLLCLK = PREDIV1C LK * 8 = 72MHZ以上是对RCC_CFGR进⾏的配置---------------------------------------------------------------------------------------------------RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; //选择PLLCLK作为系统时钟源--------------------------------------------------------------------------------------------------⾄此基本配置已经完成,配置的时钟如下所述:SYSCLK(系统时钟) = 72MHZAHB总线时钟 = 72MHZAPB1总线时钟 = 36MHZAPB2总线时钟 = 72MHZPLL时钟 = 72MHZPLL2时钟 = 40MHZ。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档