****************************首选我们了解一下它们的功能吧**************************************************************

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生成的更多相关文章

  1. stm32cube--通用定时器--输入捕获

    用定时器输入捕获做红外线接收实验.(此次试验以通道2为例) ①stm32cube配置 ② ③ ④程序中主要用到的输入捕获相关寄存器 uint16_t tim_sr,tim_ccer,tim_ccr; ...

  2. STM32之定时器输入捕获

    1.输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能.STM32的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿 ...

  3. stm32高级定时器1互补输出 验证代码

    GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDe ...

  4. STM32F103ZET6通用定时器的输入捕获

    1.通用定时器输入捕获功能简介 通用定时器的输入捕获模式可以用来测量脉冲宽度或者测量频率. STM32的每个通用定时器都有4个输入捕获的通道,分别是TIMx_CH1.TIMx_CH2.TIMx_CH3 ...

  5. 关于普通定时器与高级定时器的 PWM输出的初始化的区别

    不管是普通定时器还是高级定时器,你用哪个通道,就在程序里用OC多少.比如CH3对应OC3 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  TIM_ ...

  6. 第32章 TIM—高级定时器—零死角玩转STM32-F429系列

    第32章     TIM—高级定时器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  7. [置顶] STM32 输入捕获的脉冲宽度及频率计算

    输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能.以下是对脉冲宽度及频率的计算. 1.脉冲宽度 如下图所示,采集该高电平脉冲 ...

  8. STM32 输入捕获的脉冲宽度及频率计算

    输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能.以下是对脉冲宽度及频率的计算. 1.脉冲宽度 如下图所示,采集该高电平脉冲 ...

  9. CC2530定时器3的输入捕获中断

    CC2530定时器3的输入捕获中断 使用的是tim3的通道1的输入捕获P1_7口.//GPIO配置成复用功能,同时设置P1_7为输入.void irCaptureGpioInit(void){ P1S ...

随机推荐

  1. hdu 1198 (并查集 or dfs) Farm Irrigation

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1198 有题目图11种土地块,块中的绿色线条为土地块中修好的水渠,现在一片土地由上述的各种土地块组成,需要浇 ...

  2. *jquery操作DOM总结 (原创:最全、最系统、实例展示)

    jquery操作DOM包括八个方面: 一:jquery对DOM节点的基本操作:二:jquery对DOM节点的CSS样式操作:三:jquery遍历DOM节点:四:jquery创建DOM节点:五:jque ...

  3. Cannot switch on a value of type String for source level below 1.7. Only convertible int values or enum variables are permitted

    在java中写switch代码时,参数用的是string,jdk用的是1.8,但是还是报错,说不支持1.7版本以下的,然后查找了项目中的一些文件,打开一个文件如下,发现是1.6的版本,好奇怪啊,按照e ...

  4. Luogu2022 有趣的数-二分答案+数位DP

    Solution 我好像写了一个非常有趣的解法233, 我们可以用数位$DP$ 算出比$N$小的数中 字典序比 $X$ 小的数有多少个, 再和 $rank$进行比较. 由于具有单调性, 显然可以二分答 ...

  5. mysql 多表查询先排序,然后再取分组<mysql 先order by,然后再取group by分组>

    select * from ( select cv.lasttime,cm.mailbox,cv.clientip from `co_user_visitlog` as cv INNER JOIN ` ...

  6. c#中将字符串转换成带2位小数的浮点数

    今天遇到一个展示酒店价格的需求,觉得是要显示成“¥0.00”样式的,就做个小随笔,将字符串装换成带2位小数的浮点数 代码如下 "; string amount = string.Empty; ...

  7. .net使用NPOI的XSSFWorkbook进行web开发中导出Excel

    之前也使用过NPOI导出excel,这次是因为在导出的excel里新增了几个列,正好超出了255的限制,所以又要改了. 今天主要出了4个问题: 1. Invalid column index (256 ...

  8. android c 读写文件

    1.包含头文件 #include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcn ...

  9. 棋盘问题(NOIP1997)

    题目链接:棋盘问题 这道题水不水呢?还是很水的,为什么?因为数据太小了.直接算就行了. #include<bits/stdc++.h> using namespace std; int m ...

  10. MySQL Server参数优化 - innodb_file_per_table(独立表空间)

    1 简介    Innodb存储引擎可将所有数据存放于ibdata*的共享表空间,也可将每张表存放于独立的.ibd文件的独立表空间.    共享表空间以及独立表空间都是针对数据的存储方式而言的.    ...