STM32的普通定时器有四路输出:TIMx_CH1、TIMx_CH2、TIMx_CH3和TIMx_CH4,可以使用输出比较的方法产生不同频率的方波输出,简单的方法是:
1)设置计数器为向上计数模式,将自动重装载寄存器设置为0xFFFF;这样计数器会循环计数。
2)每个定时器通道设置为输出比较模式,并设置比较匹配时对应的输出管脚翻转输出。
3)按照输出波形的半波周期计算出一个数值称作Half_Cyc。例如:定时器的时钟频率是72MHz,需要产生3456Hz的方波,则Half_Cyc = 72M/(3456*2) = 41667;如需要产生200kHz的方波,则Half_Cyc = 72M/(200k*2) = 180。
4)设置每个通道在输出比较匹配时产生中断,在中断中将比较寄存器的数值读出并加上Half_Cyc的数值,如果计算出的数值超过16位则舍弃超出的部分,再把这个新的数值写回相应的比较寄存器;这样下次比较成功将刚好发生在一个半波周期之后,对应的管脚将被翻转。
上述方法在要求频率不高时十分有效,但如果频率较高时会有频繁的中断产生,这时可以使用DMA加以改善。
上述方法的基础是通过不断改变输出比较的匹配点进而产生管脚翻转输出,我们可以事先计算好这些比较匹配点,并通过DMA在每次匹配时逐次更新比较寄存器的内容:
方法一、使用两个DMA缓冲区,在DMA控制器操作一个缓冲区时,程序计算好另一个缓冲区的数据,然后在DMA传输结束的中断处理中切换DMA操作的缓冲区。
方法二、使用一个大的DMA缓冲区,先计算好半个缓冲区的内容,启动DMA为循环模式并设置它在DMA传送一半和完成时均产生中断;启动DMA后继续计算好另外半个缓冲区的内容,当发生DMA中断时表示有一半缓冲区变空,这时在中断处理中计算好这半个缓冲区。
只要DMA缓冲区开的足够大,方法二可以保证CPU有充足的时间进行数据处理,并且保证不断地输出波形。
声明:以上说明没有经过实际验证,只是一个原理说明,也许还有没考虑周全的地方。
关键字:STM32 普通定时器 不同频率 方波
引用地址:
使用STM32的单个普通定时器产生4路不同频率的方波
推荐阅读最新更新时间:2024-03-16 13:58
stm32中断服务函数c语言,STM32中断使用总结——不使用固件库
ST提供的固件库给我们很大的方面,但我十分不喜欢使用固件库因为它不简洁等一些原因,所以自己不断琢磨怎么用汇编和C语言编写自己想要的程序。以定时器TMI1上溢中断的产生为例总结一下这种方法。硬件条件是:外部晶振使用HIE=6MHz;目标是:定时器每10S进中断一次使LED闪烁。 首先要知道这个中断(TIM1上溢事件)的中断向量地址在哪?汇编部分就是编写一个跳转程序,用来保证在产生中断时会跳入自己写的C程序中,这个可以参考启动代码STM32F10X.S中的复位函数的编写,但要注意地址的对准,这里不在赘述。 然后根据需要编写一个中断处理程序,这个里面必须将TIM1的上溢中断标志清零(TIM1_SR中第0位),否则时间没到程序一直
[单片机]
stm32初学之LED按键中断
首先,我们选定需要控制的特定引脚, 然后为其配置特定的功能, 最后就可以通过按键控制LED的亮与灭了。 对于LED和按键的初始化比较相似,都是通过GPIO_InitTypeDef结构体来配置。 typedef struct { uint16_t GPIO_Pin; //引脚号 GPIOSpeed_TypeDef GPIO_Speed; //配置速度 GPIOMode_TypeDef GPIO_Mode; //工作模式 }GPIO_InitTypeDef; 这里还可以通过 GPIO_SetBits(GPIOC,GPIO_Pin_3);和GPIO_ResetBits(GPIOC,GPIO_Pin_3) 来使LED
[单片机]
STM32获取MPU6050数据
参考视频:https://www.bilibili.com/video/BV1Fy4y1t7me https://www.bilibili.com/video/BV1kx411k7JT?p=63 效果图: 接线: SDA–PB11 SCL–PB10 MPU6050模块的介绍: MPU6050内部整合了三轴MEMS陀螺仪、三轴MEMS加速度计以及一个可扩展的数字运动处理器DMP(Digital Motion Processor),而且还可以连接一个第三方数字传感器(如磁力计),这样的话,就可以通过IIC接口输出一个9轴信号(链接第三方数字传感器才可以输出九轴信号,否则只有六轴信号)。更加方便的是,有了DMP,可以结合In
[单片机]
STM32操作访问内部Flash
目录: 1、STM32 FLASH操作流程 2、Flash基本知识点 3、OK,上干货,上代码 ------------------------------------------------------------------------------------------------- STM32中存储区分为:随机存取存储器RAM和只读存储器ROM。 其中: RAM为常说的内存,比如手机的2G内存4G内存等,就是程序跑起来的时候所占用的存储空间,特点是掉电数据丢失。 ROM为常说的硬盘,比如手机的64G和128G等,可以简单的理解为硬盘的存储空间,特点是掉电数据不丢失,所以又叫“非易失性存储器件”。 R
[单片机]
STM32 I2C初始化函数,非使用STM32库方式
STM32 I2C初始化函数,非使用STM32库方式。 //========================================================================= // ADC_Configuration(void) //========================================================================= void STM32_I2C_Configuration(void) { //GPIO_InitTypeDef GPIO_InitStructure; //I2C_InitTypeDef I2C_Init
[单片机]
stm32学习笔记(四)外部中断
#include exti.h #include led.h #include key.h #include delay.h #include usart.h ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //Mini STM32开发板 //外部中断 驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //修改日期:2010/12/01 //版本:V1.0 //版权所有,盗版必究。 //Cop
[单片机]
STM32 在 MDK环境下 插入汇编
先在网上查有的说是__asm{NOP;},从intrins.h里调用,可犄角旮旯全找了,也没看到什么intrint.h的文件。如果直接用,就出现 error: #1113: Inline assembler not permitted when generating Thumb code 最后搜索这条错误,知道是因为__asm( 指令 );这种语法是内联汇编(inline assembly)的语法。而RMDK下,内联汇编仅支持ARM汇编语言,不支持Thumb或者Thumb-2汇编语言;但内嵌汇编器支持Thumb和Thumb-2。 __asm放到一个单独的子函数再被调用就没问题了 如下: __asm void nop(void)
[单片机]
STM32基础知识:中断系统
中断系统 1 数据传输方式 无条件传输 :处理器不必了解外部设备状态,直接进行数据传输,用于指示灯和按键等简单设备.。 查询方式 :传输前,一方先查询另一方的状态,若已经准备好就传输,否则就继续查询。 中断方式 :一方通过申请中断的方式与另一方进行数据传输,收发双方可以并行工作。 直接存储器访问 :处理器内部建立片内外设和内存之间的数据传输通道,传输过程不需要处理器参与。 2 中断系统的基本概念 2.1 中断全过程 中断发生: 当CPU在处理某一事件A时,发生了另一事件B,请求CPU迅速去处理。 中断处理: CPU暂停当前的工作,转去处理事件B。 中断返回: 当CPU将事件B处理完毕后,再回到事件A中被暂停的地方继
[单片机]