在自己小板子上移植PWM时候又重新学习了一下,加入两点:1,对各种输出比较模式的学习;2,输出模式时加入中断

先写出函数:

 //TIM4 PWM部分初始化
//PWM输出初始化
//period:输出周期:KHz
//duty:占空比 0-100
//mode: 是否开启Tim4中断溢出中断与CC4中断 void TIM4_CH4_PB9_PWM_Init(unsigned short int period,char duty,char mode)
{ GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器4时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟 //设置该引脚为复用输出功能,输出TIM4 CH4的PWM脉冲波形 GPIOB.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TIM_CH4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO //初始化TIM4
TIM_TimeBaseStructure.TIM_Period = (/period); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值,本身频率为1MHz,又分频器设置的下面一行
TIM_TimeBaseStructure.TIM_Prescaler =(-); //设置用来作为TIMx时钟频率除数的预分频值,72MHz/72=1MHz
TIM_TimeBaseStructure.TIM_ClockDivision = ; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM4 Channel4 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_Pulse=(*duty/period); //(TIM_Period)*(duty/100) --> (1000/period)*(duty/100)
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC4Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC4 TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR4上的预装载寄存器
TIM_Cmd(TIM4, ENABLE); //使能TIM4 if(mode)
{
/* Clear TIM4 update pending flag[清除TIM4溢出中断标志] */
TIM_ClearITPendingBit(TIM4, TIM_IT_CC4 | TIM_IT_Update );
/* TIM IT enable */ //打开溢出中断
TIM_ITConfig(TIM4, TIM_IT_CC4 | TIM_IT_Update, ENABLE); /* Enable the TIM4 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); } }

TIM4_CH4_PB9_PWM_Init

其中:

TIM_OCInitStructure.TIM_Pulse=(10*duty/period);

这句就是set CCR4比较/捕获寄存器的值。

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器输出比较

TIM_OCMode_Timing        输出比较时间模式  (输出引脚冻结无效)
                                               
TIM_OCMode_Active         输出比较主动模式  (匹配时设置输出引脚为有效电平,当计数值为比较/捕获寄存器值相同时,强制输出为高电平

TIM_OCMode_Inactive      输出比较非主动模式 (匹配时设置输出引脚为无效电平,当计数值为比较/捕获寄存器值相同时,强制输出为低电平)      
                                               
TIM_OCMode_Toggle         输出比较翻转触发模式(当计数值与比较/捕获寄存器值相同时,翻转输出引脚的电平)   
                                              
TIM_OCMode_PWM1          向上计数时,当TIMx_CNT < TIMx_CCR*时,输出电平有效,否则为无效                            
                                       向下计数时,当TIMx_CNT > TIMx_CCR*时,输出电平无效,否则为有效
                                               
TIM_OCMode_PWM2          与PWM1模式相反

PWM模式就不说了,通过函数设置频率与占空比。

其余几个所说的“当计数值为比较/捕获寄存器值相同时” 即CCRX=CNT;这时候会触发后面所说的事件,而TIM_OCMode_Active与TIM_OCMode_Inactive     仅触发一次,所以之后就会出现一直为高电平或者低电平。TIM_OCMode_Toggle会每次都翻转,所以也形成一个PWM,而占空比只会是百分之五十,周期为参数period的两倍,频率为1/2,因为一个period只翻转一次!翻转是在CCRX=CNT时翻转,并不是CNT=ARR(ARR=TIM_TimeBaseStructure.TIM_Period)。

输出比较时候可以出发本身的比较/捕获中断与溢出中断,我用的CH4,开启了TIM_IT_CC4 | TIM_IT_Update,中断函数中可以看到何时触发中断,什么时候进行翻转。

 void TIM4_IRQHandler(void)
{ if(TIM_GetITStatus(TIM4,TIM_IT_Update)!=RESET)
{
LED1_Toggle();
// printf("TIM_IT_CC4");
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
if(TIM_GetITStatus(TIM4,TIM_IT_CC4)!=RESET)
{
// printf("TIM_IT_CC4");
LED2_Toggle();
TIM_ClearITPendingBit(TIM4,TIM_IT_CC4);
} }

TIM4_IRQHandler

STM32:TIMER输出比较模式-PWM的更多相关文章

  1. 【转】STM32定时器输出比较模式中的疑惑

    OCx与OCxREF和CCxP之间的关系 初学STM32,我这个地方卡了很久,现在终于有些明白了,现在把我的理解写下与大家共享,如果有不对的地方,还请指出. OCxREF就是一个参考信号,并且约定: ...

  2. STM32: TIMER门控模式控制PWM输出长度

    搞了两天单脉冲没搞定,无意中发现,这个利用主从模式的门控方式来控制一路PWM的输出长度很有效. //TIM2 PWM输出,由TIM4来控制其输出与停止 //frequency_tim2:TIM2 PW ...

  3. stm32定时器输出移相PWM(非主从模式)

    背景:由于项目需要,需要stm32输出任意相角度的PWM 前提知识: 1.stm32定时器的Tim,一般有多个OC.具体差别根据型号来定. 2.定时器的使能,理论上是多个通道同时使能 3.TIM_OC ...

  4. TIMER门控模式控制PWM输出长度

    TIMER门控模式控制PWM输出长度 参照一些网友代码做了些修改,由TIM4来控制TIM2的PWM输出长度, 采用主从的门控模式,即TIM4输出高时候TIM2使能输出 //TIM2 PWM输出,由TI ...

  5. stm32定时器PWM模式和输出比较模式

    pwm模式是输出比较模式的一种特例,包含于输出比较模式中 /** @defgroup TIM_Output_Compare_and_PWM_modes * @{ */ #define TIM_OCMo ...

  6. 基于STM32F429+HAL库编写的定时器主从门控模式级联输出固定个数PWM脉冲的程序

    硬件设备   42步进电机,步进电机驱动器,正点原子F429开发板 开发软件    keil5,Cube 综述   一般要精准的控制电机,就要控制单片机的引脚输出指定个数的PWM波,有多种可实现的方法 ...

  7. STM32—TIMx输出PWM信号驱动MG996R舵机

    文章目录 一.前言 二.MG996R舵机简介 三.TIM定时器简介 四.通用定时器TIMx 1.TIMx主要功能 2.TIMx框图 3.计数单元 4.时钟选择 5.输出比较PWM 五.TIM3输出双路 ...

  8. STM32 精确输出PWM脉冲数控制电机(转)

    STM32 精确输出PWM脉冲数控制电机 发脉冲两种目的1)速度控制2)位置控制 速度控制目的和模拟量一样,没有什么需要关注的地方发送脉冲方式为PWM,速率稳定而且资源占用少 stm32位置控制需要获 ...

  9. 定时器同步+触发三ADC采样+输出6路PWM波

    为了熟悉定时器定时器和ADC 用STM32F407DIS做了一个简单的工程: 通过高级定时器TIM1溢出更新时间作为触发输出信号(TRGO),触发TIM8开始计数: 同时TIM1的通道1.2.3以及分 ...

随机推荐

  1. 16Log4J

    Log4J Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务器.NT的事件记录器.UNIX Syslog守 ...

  2. 视频剪辑生成gif格式(php外挂python程序)完美!

    接到朋友的需求,朋友是做php的,让我帮忙处理php生成gif的需求.他的项目类似抖音短视频那种,就是展示出来的界面是gif动图,然后点进去是完整的视频. 我想了想,我倒是没做过php生成gif的需求 ...

  3. iOS-关于一些手势冲突问题(scrollView 嵌套 tableView)

    简单说下关于开发中容易遇到的父试图添加手势与子试图点击事件冲突,UIScrollView 嵌套 UIScrollView . UIScrollView 嵌套 UITableView的情况手势冲突问题: ...

  4. [Git]Please make sure you have the correct access rights and the repository exists

    这个问题是这样,需要在已有github账号的A机器上,再创建一个github账号,新账号创建完毕,将代码通过机器A push上之后,再另一台机器B,clone 这个项目时报出了如下错误: Permis ...

  5. 「 HDU P3336 」 Count the string

    题目大意 给出一个长度为 $n$ 的字符串 $s$ 要求你求出 $s$ 的每一个前缀在 $s$ 中出现的次数之和.$n\le 200000$. 解题思路 暴力的对每一个前缀进行一次匹配,求出出现次数后 ...

  6. Object类型转换为String类型

    1. Object.toString() 1 obj.toString() 注意:必须保证Object不是null值,否则将抛出NullPointerException异常. 2. (String)O ...

  7. jsp页面应用简记

    1.记录总数据条数 <div class="" > <span class="">共有数据:<strong>${fn:len ...

  8. MyBatis 创建核心配置文件和 SQL 映射文件

    Mybatis 的两个配置文件(mybatis-config.xml  和 xxxMapper.xml)都为 xml 类型,因此在 eclipse 中创建 xml 文件命名为相应的 mybatis-c ...

  9. linux free命令-显示内存的使用情况

    更多Linux 性能监测与优化 关注 Linux命令大全 free命令可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区. 语法 free(选项) 选项 -b:以Byte为单 ...

  10. JUnit 深入

    Fixture 何谓 Fixture ?它是指在执行一个或者多个测试方法时需要的一系列公共资源或者数据,例如测试环境,测试数据等等.在编写单元测试的过程中,您会发现在大部分的测试方法在进行真正的测试之 ...