STM32学习记录 您所在的位置:网站首页 stm32单片机flash频率 STM32学习记录

STM32学习记录

2024-07-10 12:33| 来源: 网络整理| 查看: 265

前言

😎😎最近学习PWM波形输出,记录一下学习心得,对于我们输出的波形,主要依赖三个数据算出来,芯片的自带的主频(即CPU的时钟频率),arr 是计数值,psc 是预分频值,我们输出的波形根据这个三个数据算出周期,还有一个变量数值来调控PWM波输出的占空比😎

进入正题➡️

一、STM32F407 1.介绍

ART技术使得程序零等待执行,提升了程序执行的效率,将Cortext-M4的性能发挥到了极致,

使得STM32 F4系列可达到210DMIPS@168MHz。

自适应实时加速器能够完全释放Cortex-M4 内核的性能;当CPU 工作于所有允许的频率(≤168MHz)时,在闪存中运行的程序,可以达到相当于零等待周期的性能

2.芯片的主频

Stm32F407主频(即CPU的时钟频率):168MHZ

3.示波器图片以及解释 3.1计算公式、封装PWM /* STM32f407的主频=168MHZ arr=100 psc=1000 168,000,000/168/1000=1000HZ 1÷1000=0.001秒×1000=1ms 1/20000=0.00005(秒) */ static u32 HZ=1000; //单位HZ 1000HZ=1ms(毫秒)=1000=1000us(微妙) static u32 arr=168,psc; //计算分频率 static void psc_num(u32 arr,u32 HZ){ psc=168000000/arr/HZ; }

解释:因为上面知道了stm32f407的时钟频率为168,那么我们要得到PWM的周期为1ms的波形,只需要把HZ函数输入1000,如上图所示,1000HZ=1ms,这样我们就可以得到1ms的波形图

一个完整的周期就是2ms,占空比为50%,其他的周期计算方法相识,只要改一下HZ函数

 说了周期如何设置,现在开始占空比,因为我们计数值设置的168,所以计数值不能大于这个数值

我写了一个自定义占空比的函数,只需高在主函数调用者函数,把我们的计数值和想要的得到的占空比输入进去,即可得到我们想要的波形

/** * @brief Specific_Value(u32 led0pwmval,double Cycle) * @param led0pwmval 参数修改比值达到占空比的调解 * @param Value 占空比比值 * @retval 用户可以直接规定PWM占空比 */ void Specific_Value(u32 led0pwmval,float Value){ u32 num=0; num = led0pwmval*Value/100; TIM_SetCompare1(GENERAL_TIM,num); //修改比较值,修改占空比 }

Specific_Value(arr,20.25),//主函数使用函数,以及输出的波形

 Specific_Value(arr,20.25),//主函数使用函数,以及输出的波形

4.实现代码 PWM.h #ifndef _TIMER_H #define _TIMER_H #include "sys.h" #define GENERAL_OCPWM_PIN GPIO_Pin_5 #define GENERAL_OCPWM_GPIO_PORT GPIOA #define GENERAL_OCPWM_GPIO_CLK RCC_AHB1Periph_GPIOA #define GENERAL_OCPWM_PINSOURCE GPIO_PinSource5 #define GENERAL_OCPWM_AF GPIO_AF_TIM2 #define GENERAL_TIM TIM2 #define GENERAL_TIM_CLK RCC_APB1Periph_TIM2 void TIM2_PWM_Init(u32 arr,u32 psc); void Duty_Cycle(u32 led0pwmval,u8 Cycle); void Specific_Value(u32 led0pwmval,float Cycle); #endif  PWM.c #include "pwm.h" #include "usart.h" /* * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有 * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可, * 另外三个成员是通用定时器和高级定时器才有. *----------------------------------------------------------------------------- * TIM_Prescaler 都有 * TIM_CounterMode TIMx,x[6,7]没有,其他都有(基本定时器) * TIM_Period 都有 * TIM_ClockDivision TIMx,x[6,7]没有,其他都有(基本定时器) * TIM_RepetitionCounter TIMx,x[1,8]才有(高级定时器) *----------------------------------------------------------------------------- 如果目标PWM的频率为F=1MHz,占空比D=0.5。 (ARR+1)*(PSC+1) = 72MHz/1MHz =72000000/1000000 =72 (ARR+1)*(PSC+1) = 72 = 8*9 → 则:可以令ARR = 7 , PSC = 8, 由于占空比D=0.5, 则:计算得到CRR=D*(ARR+1)=0.5*(7+1)=4 则:TIM_Pulse=CCR = (7+1)/2 = 4 */ //TIM14 PWM部分初始化 //PWM输出初始化 //arr:自动重装值 //psc:时钟预分频数 void TIM2_PWM_Init(u32 arr,u32 psc) { //此部分需手动修改IO口设置 GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(GENERAL_TIM_CLK,ENABLE); // 开启TIMx_CLK,x[2,3,4,5,12,13,14] RCC_AHB1PeriphClockCmd(GENERAL_OCPWM_GPIO_CLK, ENABLE); //使能PORTF时钟 GPIO_PinAFConfig(GENERAL_OCPWM_GPIO_PORT,GENERAL_OCPWM_PINSOURCE,GENERAL_OCPWM_AF); //GPIOF9复用为定时器14 GPIO_InitStructure.GPIO_Pin = GENERAL_OCPWM_PIN; //GPIOF9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GENERAL_OCPWM_GPIO_PORT,&GPIO_InitStructure); //初始化PF9 TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(GENERAL_TIM,&TIM_TimeBaseStructure);//初始化定时器14 //初始化TIM14 Channel1 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低 TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 4OC1 TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); //使能TIM14在CCR1上的预装载寄存器 TIM_ARRPreloadConfig(GENERAL_TIM,ENABLE);//ARPE使能 TIM_Cmd(GENERAL_TIM, ENABLE); //使能TIM14 } /** * @brief Duty_Cycle(u32 led0pwmval,u8 Cycle) * @param led0pwmval 参数修改比值达到占空比的调解 * @param Cycle 数值为1-10.每一个数据代表一个占空比 |---------------------------------------| | Cycle = 1 = 0% | | Cycle = 1 = 99.48% | | Cycle = 2 = 49.94% | | Cycle = 3 = 33.32% | | Cycle = 4 = 24.96% | | Cycle = 5 = 19.96% | | Cycle = 6 = 16.60% | | Cycle = 7 = 14.21% | | Cycle = 8 = 12.50% | | Cycle = 9 = 11.00% | |---------------------------------------| * @retval 占空比修改 */ void Duty_Cycle(u32 led0pwmval,u8 Cycle){ u32 num=0; switch(Cycle){ case 1: num = led0pwmval; break; case 2: num = led0pwmval/2; break; //33% case 3: num = led0pwmval/3; break; case 4: //25% num = led0pwmval/4; break; //50% case 5: num = led0pwmval/5; break; case 6: num = led0pwmval/6; break; case 7: num = led0pwmval/7; break; case 8: num = led0pwmval/8;; break; case 9: num = led0pwmval/9; break; case 0: num = 0; break; default: printf("不存在该占空比\n"); break; } TIM_SetCompare1(GENERAL_TIM,num); //修改比较值,修改占空比 } /** * @brief Specific_Value(u32 led0pwmval,double Cycle) * @param led0pwmval 参数修改比值达到占空比的调解 * @param Value 占空比比值 * @retval 用户可以直接规定PWM占空比 */ void Specific_Value(u32 led0pwmval,float Value){ u32 num=0; num = led0pwmval*Value/100; TIM_SetCompare1(GENERAL_TIM,num); //修改比较值,修改占空比 }

主函数直接引用 

二、STM32F103 1.介绍

STM32F系列属于中低端的32位ARM微控制器,该系列芯片是意法半导体(ST)公司出品,其内核是Cortex-M3 [1]  。

该系列芯片按片内Flash的大小可分为三大类:小容量(16K和32K)、中容量(64K和128K)、大容量(256K、384K和512K)。

芯片集成定时器Timer,CAN,ADC,SPI,I2C,USB,UART等多种外设功能。

2.芯片的主频

Stm32Ff103主频(即CPU的时钟频率):72MHZ

3.实现代码

F407与F107除了PWM的配置不同以外,其他的函数可以直接复用F407的代码,如计算公式等

PWM.c #include "timer.h" #include "led.h" #include "usart.h" //通用定时器3中断初始化 //这里时钟选择为APB1的2倍,而APB1为36M //arr:自动重装值。 //psc:时钟预分频数 //这里使用的是定时器3! void TIM3_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIMx外设 } //定时器3中断服务程序 void TIM3_IRQHandler(void) //TIM3中断 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源 LED1=!LED1; } } //TIM3 PWM部分初始化 //PWM输出初始化 //arr:自动重装值 //psc:时钟预分频数 void TIM3_PWM_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟 GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2->PB5 //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形 GPIOB.5 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO //初始化TIM3 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM3 Channel2 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIM3 } PWM.h #ifndef __TIMER_H #define __TIMER_H #include "sys.h" void TIM3_Int_Init(u16 arr,u16 psc); void TIM3_PWM_Init(u16 arr,u16 psc); #endif l


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有