stm32f103_高级定时器——输入捕获/输出比较中断+pwm=spwm生成
****************************首选我们了解一下它们的功能吧**************************************************************
TIM1和TIM8定时器的功能包括:
● 16位向上、向下、向上/下自动装载计数器
● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意
数值
● 多达4个独立通道:
─ 输入捕获
─ 输出比较
─ PWM生成(边缘或中间对齐模式)
─ 单脉冲模式输出
● 死区时间可编程的互补输出
● 使用外部信号控制定时器和定时器互联的同步电路
● 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器
● 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态
● 如下事件发生时产生中断/DMA:
─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
─ 输入捕获
─ 输出比较
─ 刹车信号输入
● 支持针对定位的增量(正交)编码器和霍尔传感器电路
● 触发输入作为外部时钟或者按周期的电流管理
****************************************************************************************************************
以定时器8讲解。。。。。。好多代码都是复制粘贴 代码可能有的没有必要,或则思路累赘,但是实测能达到目的
void TIM8_PWM_Init(u16 arr,u16 psc)
{
/*******************************************************************************
这一段是各种结构体声明了,就不用多说了
********************************************************************************/
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/*******************************************************************************
第一步:时钟使能
********************************************************************************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);// 使能定时器时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE); //使能GPIO外设时钟使能
/*******************************************************************************
第二步:spwm波形输出管脚的初始化
********************************************************************************/
//设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_7; //TIM_CH2, 3 4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*******************************************************************************
第三步:定时器的初始化参数
这里我就通过初始化函数 TIM_TimeBaseInit 实现的
1-设置自动重载计数周期值
2-设置时钟分频系数
3-设置时钟分频因子
4-设置计数方式 (我设置的向上计数模式)
********************************************************************************/
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
/*******************************************************************************
第四步:设置 TIM8_CH2&CH3&CH4 的 PWM 模式
1.PWM模式1- 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为
无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否
则为有效电平(OC1REF=1)。
2.PWM模式2- 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为
有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电
平。
3.输出比较极性指的是有效电平
从上面的截图我们可以看出,我们要打开定时8或则关闭定时器八通道pwm输出时,只需要操作寄存器CCER,也就是用TIM8->CCER指令操作寄存器。
还有捕获/比较寄存器(TIMx_CCR2~4),对应 3个输通道 CH2~4。因为这 3个寄存器都差不多,我们仅以 TIMx_CCR2 为例介绍:该寄存器是通道2捕获/比较的值。
其实下面的TIM_Pulse参数就是给CCR2寄存器赋值的,也就是设置待装入捕获比较寄存器的脉冲值。通过改变此能改变占空比,TIM8->CCR2代码实现。
CCR2[15:0]: 捕获/比较通道2的值 (Capture/Compare 2 value) 若CC2通道配置为输出: CCR2包含了装入当前捕获/比较2寄存器的值(预装载值)。 如果在TIMx_CCMR2寄存器(OC2PE位)中未选择预装载特性,写入的数值会立即传输至当前寄 存器中。否则只有当更新事件发生时,此预装载值才传输至当前捕获/比较2寄存器中。 当前捕获/比较寄存器参与同计数器TIMx_CNT的比较,并在OC2端口上产生输出信号。 若CC2通道配置为输入: CCR2包含了由上一次输入捕获2事件(IC2)传输的计数器值。 |
********************************************************************************/
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH1预装载使能
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH1预装载使能
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH1预装载使能
/*******************************************************************************
第五步:中断打开,优先级配置
TIM_IT_Update:更新中断,计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
TIM_IT_CC1~4:都是捕获/比较中断,貌似都是平等的,即输入捕获,输出比较
TIM_IT_Trigger:触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
使用的时候都是调用函数TIM_ITConfig()来使能指定的中断类型,调用TIM_GetITStatus()函数来查看是否有中断发生,入口参数都是平等的。
可能就是不同的事件导致中断的发生略有不同
输入捕获中断:发生输入捕获,立即在硬件上产生一个中断标志,产生中断请求,要是当前没有比捕获中断更高级别的中断在执行或等待执行,那么就会立即跳转到你中断函数里面去执行代码。
13.4.4 TIM1 和TIM8 DMA/中断使能寄存器(TIMx_DIER)
位15 | 保留,始终读为0。 |
位14 | TDE:允许触发DMA请求 (Trigger DMA request enable) 0:禁止触发DMA请求; 1:允许触发DMA请求。 |
位13 | COMDE:允许COM的DMA请求 (COM DMA request enable) 0:禁止COM的DMA请求; 1:允许COM的DMA请求。 |
位12 | CC4DE:允许捕获/比较4的DMA请求 (Capture/Compare 4 DMA request enable) 0:禁止捕获/比较4的DMA请求; 1:允许捕获/比较4的DMA请求。 |
位11 | CC3DE:允许捕获/比较3的DMA请求 (Capture/Compare 3 DMA request enable) 0:禁止捕获/比较3的DMA请求; 1:允许捕获/比较3的DMA请求。 |
位10 | CC2DE:允许捕获/比较2的DMA请求 (Capture/Compare 2 DMA request enable) 0:禁止捕获/比较2的DMA请求; 1:允许捕获/比较2的DMA请求。 |
位9 | CC1DE:允许捕获/比较1的DMA请求 (Capture/Compare 1 DMA request enable) 0:禁止捕获/比较1的DMA请求; 1:允许捕获/比较1的DMA请求。 |
位8 | UDE:允许更新的DMA请求 (Update DMA request enable) 0:禁止更新的DMA请求; 1:允许更新的DMA请求。 |
位7 | BIE:允许刹车中断 (Break interrupt enable) 0:禁止刹车中断; 1:允许刹车中断。 |
位6 | TIE:触发中断使能 (Trigger interrupt enable) 0:禁止触发中断; 1:使能触发中断。 |
位5 | COMIE:允许COM中断 (COM interrupt enable) 0:禁止COM中断; 1:允许COM中断。 |
位4 | CC4IE:允许捕获/比较4中断 (Capture/Compare 4 interrupt enable) 0:禁止捕获/比较4中断; 1:允许捕获/比较4中断。 |
位3 | CC3IE:允许捕获/比较3中断 (Capture/Compare 3 interrupt enable) 0:禁止捕获/比较3中断; 1:允许捕获/比较3中断。 |
位2 | CC2IE:允许捕获/比较2中断 (Capture/Compare 2 interrupt enable) 0:禁止捕获/比较2中断; 1:允许捕获/比较2中断。 |
位1 | CC1IE:允许捕获/比较1中断 (Capture/Compare 1 interrupt enable) 0:禁止捕获/比较1中断; 1:允许捕获/比较1中断。 |
位0 | UIE:允许更新中断 (Update interrupt enable) 0:禁止更新中断; 1:允许更新中断。 |
********************************************************************************/
TIM_ClearFlag(TIM8, TIM_FLAG_Update);//清除中断标志,如果没有添加这条语句,会先进一次中断
TIM_ITConfig(TIM8, TIM_IT_CC2/*TIM 输入捕获中断源*/, ENABLE); //使能或者失能指定的TIM中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;//TIM8捕捉比较中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能 高级定时器需要这句 我们还需要
//使能刹车和死区寄存器(TIM1_BDTR)的 MOE 位,以使能整个 OCx(即 PWM)输出
TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
/*******************************************************************************
如果在TIMx_CCMR1寄存器(OC1PE位)中未选择预装载功能,写入的数值会立即传输至当前寄 存器中。否则只有当更新事件发生时,此预装载值才传输至当前捕获/比较1寄存器中。 |
所以我用的通道而输入捕获中断,在中断函数里给三个通道占空比赋值,虽然通道二发生输入捕获后,通道3或则通道4有可能还没有发生输入捕获,但是由于我已经选择了预装在功能,所以数值还是要等定时器8发生更新事件时在传输到输入捕获寄存器(CCR2~4),这就没有影响了。
********************************************************************************/
TIM_Cmd(TIM8, ENABLE); //使能TIM1
}
/*******************************************************************************
第六步:中断函数编写
SVPWM1_P......:正弦表
********************************************************************************/
uint16_t count = 0;
uint16_t num = 360;//sizeof(SVPWM1_P)/(sizeof(SVPWM1_P[0]));
void TIM8_CC_IRQHandler(void)
{
if (TIM_GetITStatus(TIM8, TIM_IT_CC2) != RESET)
{
TIM8->SR = (uint16_t)~TIM_IT_CC2; //清除TIMx的中断待处理位:TIM 中断源
TIM8->CCR2 = SVPWM1_P[count];
TIM8->CCR3 = SVPWM2_P[count];
TIM8->CCR4 = SVPWM3_P[count];
count++;
if(count==num)
{
count=0;
}
}
}
stm32f103_高级定时器——输入捕获/输出比较中断+pwm=spwm生成的更多相关文章
- stm32cube--通用定时器--输入捕获
用定时器输入捕获做红外线接收实验.(此次试验以通道2为例) ①stm32cube配置 ② ③ ④程序中主要用到的输入捕获相关寄存器 uint16_t tim_sr,tim_ccer,tim_ccr; ...
- STM32之定时器输入捕获
1.输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能.STM32的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿 ...
- stm32高级定时器1互补输出 验证代码
GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDe ...
- STM32F103ZET6通用定时器的输入捕获
1.通用定时器输入捕获功能简介 通用定时器的输入捕获模式可以用来测量脉冲宽度或者测量频率. STM32的每个通用定时器都有4个输入捕获的通道,分别是TIMx_CH1.TIMx_CH2.TIMx_CH3 ...
- 关于普通定时器与高级定时器的 PWM输出的初始化的区别
不管是普通定时器还是高级定时器,你用哪个通道,就在程序里用OC多少.比如CH3对应OC3 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_ ...
- 第32章 TIM—高级定时器—零死角玩转STM32-F429系列
第32章 TIM—高级定时器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...
- [置顶]
STM32 输入捕获的脉冲宽度及频率计算
输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能.以下是对脉冲宽度及频率的计算. 1.脉冲宽度 如下图所示,采集该高电平脉冲 ...
- STM32 输入捕获的脉冲宽度及频率计算
输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能.以下是对脉冲宽度及频率的计算. 1.脉冲宽度 如下图所示,采集该高电平脉冲 ...
- CC2530定时器3的输入捕获中断
CC2530定时器3的输入捕获中断 使用的是tim3的通道1的输入捕获P1_7口.//GPIO配置成复用功能,同时设置P1_7为输入.void irCaptureGpioInit(void){ P1S ...
随机推荐
- phpstorm+xdebug调试代码
1工具 #phpstorm 前面有文章介绍如何安装 #phpStudy 官网下的2018最新的安装包,php环境使用的也是最新的php7.0nts 2开启php Xdebug拓展 开启拓展,phpSt ...
- Linux内核哈希表分析与应用
目录(?)[+] Linux内核哈希表分析与应用 Author:tiger-johnTime:2012-12-20mail:jibo.tiger@gmail.comBlog:http:// ...
- \\Device\\PhysicalMemory
从Windows Server 2003 with SP1 以后就禁用了用户态访问\\Device\\PhysicalMemory,要访读取SMBIOS的信息,请使用以下API:•EnumSystem ...
- eclipse中tomcat调试正确关联源码
1.build path中jar包关联本地源码 2.tomcat中添加source关联工程lib下的jar包 以上两步即可. 可解决tomcat直接关联本地源码debug时无法计算表达式的情况. 错误 ...
- h5页面适配iPhone X的方法
一.原生适配iphoneX 原生适配很简单,查看机型图: 只要用 #define KIsiPhoneX ([UIScreen mainScreen].bounds.size.height>8 ...
- tomcat 配置域名访问应用
<Host appBase="webapps" autoDeploy="true" name="www.XXX.com" unpack ...
- 学习第一天-JAVA
第一题打印1到1000的奇数 public class OneToThousandOdd{ public static void main(String[] args) { short num = 1 ...
- MongoDB相关记录
win10中zip安装 下载地址:http://dl.mongodb.org/dl/win32/x86_64 首先解压至某文件夹, 使用管理员权限打开cmd或者powershell, 进入指定目录中的 ...
- 【Tomcat】Tomcat + Memcached 实现session共享
概述 web项目中,Tomcat的访问量总是有限的,这时候就需要用到Tomcat集群,多个Tomcat的时候就要考虑Session共享的问题,这里介绍一种使用Memcached做Session共享的解 ...
- SQL SERVER 如果判断text类型数据不为空
一个字段Remark的数据类型设置先设置为varcharr(255),后来考虑到扩展性需要将其定义为TEXT类型,但是SQL 语句报错. SQL 语句: SELECT * FROM ...