在自己小板子上移植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. C++字符串处理函数总结

    1.基础函数输入输出:cin,cout,getchar,gets,putchar,puts,printf,scanf格式化:sprintf,sprintf_s,wsprintf,wsprintf_s, ...

  2. 网络配置:IP+NETMASK+GATEWAY+DNS

    1.  IP IP地址(英语:Internet Protocol Address)是一种在Internet上的给主机编址的方式,也称为网际协议地址.常见的IP地址,分为IPv4与IPv6两大类. IP ...

  3. linux下Mongodb集群搭建:分片+副本集

    三台服务器 192.168.1.40/41/42 安装包 mongodb-linux-x86_64-amazon2-4.0.1.tgz 服务规划  服务器40  服务器41  服务器42  mongo ...

  4. docker插件

    import docker c = docker.Client(base_url='unix://var/run/docker.sock',version='1.15',timeout=10) pri ...

  5. 我安装android studio的过程与经历

    虽然android studio已经出来两年多了,但是我一直都没真正用过.之前用Eclipse还算用得挺好.我并不是一个专职的android开发者,我是个游戏开发者,打包的时候要用到android.不 ...

  6. java json数据转List对象的集合-----阿里巴巴插件---及原生json---JSON 与 对象 、集合 之间的转换 JSON字符串和java对象的互转【json-lib】

    List<RunfastFullLess> list=(List<RunfastFullLess>)JSONArray.parseObject(activity.getFull ...

  7. hdu 1533KM算法

    #include<stdio.h> #include<string.h> #include<math.h> #define inf 0x3fffffff #defi ...

  8. [bzoj2440]完全平方数[中山市选2011][莫比乌斯函数][线性筛][二分答案]

    题意:求第k个分解质因子后质因子次数均为一的数,即求第k个无平方因子数. 题解: 首先二分答案mid,那么现在就是要求出mid以内的无平方因子数的个数. 其次枚举$\sqrt{mid}$内的所有质数, ...

  9. 分块试水--CODEVS4927 线段树练习5

    模板 #include<stdio.h> #include<algorithm> #include<string.h> #include<stdlib.h&g ...

  10. kendo grid dropdownlist 联动 cascading

    之前是无法联动的 后来将html页面中的 //$('<input required data-text-field="CompanyName" data-value-fiel ...