怎样做到stm32 定时器 定时时间可调,(又不用初始化)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎样做到stm32 定时器 定时时间可调,(又不用初始化)相关的知识,希望对你有一定的参考价值。

设置一个变量,然后给定时器的计数器幅值的时候,把变量的高低字节赋给计数寄存器。而这个变量可以在程序中,通过按键改变(增减)。这样就可以把时间可调。追问

能不能给我个具体的例程,谢谢

追答

我给你说的是原理,51的经常做。stm32的没有做过,不熟悉指令。有原理,你查下指令,很好做的。

参考技术A /*
************************************************
*文件名: 舵机(steering engine) 头文件
*版 本: 01
*功 能: PE15输出20ms占空比可调方波
*注 意:
PWM_high(500~2500)
500————————0°
1500————————90°
2500————————180°
线性(PWM_high增加125,对应舵机增加9°)

*创 建: 快乐的MCU 2011.4.24
************************************************
*/

//*******************全局变量**********************
u16 PWM_high;
u16 Expect_PWM_high;
u8 PWM_state=1;

//******************宏定义************************

#define Expect_degree_0 600 //如果是500舵机打到头颤抖
#define Expect_degree_45 1000
#define Expect_degree_90 1500
#define Expect_degree_135 2000
#define Expect_degree_180 2400//如果是2500舵机打到头颤抖

#define Degree 10 //125对应舵机转9°
#define PWM_high_state 1
#define PWM_low_state 0
#define PWM_low (20000-PWM_high)

/*
************************************************
*函数名: 定时3 初始化函数
*功 能:
*
*输 入:
*返 回:
************************************************
*/
void Timx_Init(void)

TIM_DeInit( TIM3);//复位TIM2定时器

GPIO_ResetBits(GPIOE, GPIO_Pin_15);

// PWM_high=1500; /*数值1500即对应1.5ms,为舵机的中间90度的位置*/

TIM_TimeBaseStructure.TIM_Period = 19999-PWM_high;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);
/* Clear TIM2 update pending flag[清除TIM2溢出中断标志] */
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
/* Enable TIM2 Update interrupt [TIM2溢出中断允许]*/
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
/* TIM2 enable counter [允许tim2计数]*/
TIM_Cmd(TIM3, ENABLE);


/*
************************************************
*函数名: 舵机步进函数
*功 能:
*
*输 入:
*返 回:
************************************************
*/
void motor_step()

if(Expect_PWM_high==PWM_high)//如果期待的脉冲与目前的脉冲相等,跳出

PWM_state=(PWM_state+1)%2; //PWM状态翻转
return;

if(Expect_PWM_high>PWM_high)//PWM为高电平时,如果期待的脉宽大于目前的脉宽,则低电平减少Degree;反之...
PWM_high+=Degree;
else
PWM_high-=Degree;

PWM_state=(PWM_state+1)%2; //PWM状态翻转


/*
************************************************
*函数名: 定时3 中断函数
*功 能:
*
*输 入:
*返 回:
************************************************
*/
void TIM3_IRQHandler(void)

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

if(GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_15)==0) //PWM电平翻转
GPIO_SetBits(GPIOE, GPIO_Pin_15);
else
GPIO_ResetBits(GPIOE,GPIO_Pin_15 );

switch(PWM_state)

case 0://PWM为低电平时
TIM_TimeBaseStructure.TIM_Period =PWM_low-1;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);
/* Clear TIM3 update pending flag[清除TIM3溢出中断标志] */
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
/* Enable TIM3 Update interrupt [TIM3溢出中断允许]*/
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

motor_step();
/* TIM2 enable counter [允许tim2计数]*/
TIM_Cmd(TIM3, ENABLE);
break;

case 1://PWM为高电平时
TIM_TimeBaseStructure.TIM_Period = PWM_high-1;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);
/* Clear TIM3 update pending flag[清除TIM3溢出中断标志] */
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
/* Enable TIM3 Update interrupt [TIM3溢出中断允许]*/
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

motor_step();
/* TIM2 enable counter [允许tim2计数]*/
TIM_Cmd(TIM3, ENABLE);
break;

default:
break;





/*
************************************************
*文件名: 舵机(steering engine) 头文件
*版 本: 01
*功 能: PE15输出20ms占空比可调方波
*注 意:
PWM_high、Expect_PWM_high(500~2500)
500————————0°
1500————————90°
2500————————180°
线性(PWM_high增加125,对应舵机增加9°)

*创 建: 快乐的MCU 2011.4.24
************************************************
*/

#include "stm32f10x_heads.h"
#include "Hello_car.h"
#include "Hello_motor.h"

int main(void)

BSP_Init(); // 开发板初始化

USART_Configuration(); // 串口1(USART1)初始化

printf("Hello Robot!\n");

PWM_high=1500;
Expect_PWM_high=1500;

Timx_Init();//定时器初始化函数

while (1)

Expect_PWM_high=Expect_degree_45;
delay_nms(2000);
Expect_PWM_high=Expect_degree_90;
delay_nms(1000);
Expect_PWM_high=Expect_degree_135;
delay_nms(1000);
Expect_PWM_high=Expect_degree_45;
delay_nms(2000);
Expect_PWM_high=Expect_degree_0;
delay_nms(1000);
Expect_PWM_high=Expect_degree_180;
delay_nms(2000);

;

stm32打怪升级之瞥眼定时器

定时器TIM------->DMA
(不用看功能直接忽略介绍)

外部中断得开启复用功能

定时器TIM)
时钟源:stm32时钟系统框图(需要下载)
外部中断得开启复用功能
实验目的:定时1s让灯亮
库:定时用到了stm3210x_tim.h库
模版:工程模版+TIM3_IRQHandler模版

流程
1.复制工程模版
2.打开工程模版在app中新建文件定时器
3.新建time.h和time.c文件添加至app定时器中
4.在time.h文件中写入声明voidtime_init
(void),且修改#define _TIME_H
5.在time.c文件中#include “time.h”,
6.在app中添加time.c中文件
7.在option中的c/c++中包含定时器路径
8.由于使用定时器使用了stm32f10x_tim.h库,所以在存放所用库fwilb中添加stm32f10x_tim.h,并且在公共函数库public中添加#include "stm3210x_tim.h"
9.开始在time.h中编写time_init()函数(查阅固件库中文手册)
10.编写完毕后,在stmf10x_it.h文件中编写定时器中断函数void TIM3_IRQHandler(),没有声明需要在.h中进行声明
11.编写主函数
注意:
1.我们用到了定时器,必须在此工程使用的头文件fwilb中添加此头文件
而且得把这个头文件添加到公共头文件里面,不然会报错
.\output\工程模板.axf: Error: L6218E: Undefined symbol TIM_TimeBaseInit (referred from time.o).
2.每次编写中断函数的时候,必须先进行擦除操作,即 TIM_ClearITPendingBit(TIM3,TIM_IT_Update);

以下是time_init()模版代码

 1 void time_init(void)
 2 {
 3     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;  //定时结构体  
 4 
 5     NVIC_InitTypeDef NVIC_InitStructure;                 //中断结构体
 6 
 7     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  //系统时钟,注意APB1和TIM3的关系
 8 
 9     TIM_ClearITPendingBit(TIM3,TIM_IT_Update);        //清除之前的中断数据,必须用,包括写中断函数的时候     
10     TIM_TimeBaseInitStructure.TIM_Period = 2000;    
11     TIM_TimeBaseInitStructure.TIM_Prescaler = 35999;  
#计算定时时间=TIM_Period\72M\
TIM_Prescaler+1
12   TIM_TimeBaseInitStructure.TIM_ClockDivision = 0; //是否时钟分割 

13   TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数模式
14   TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);

15  TIM_Cmd(TIM3,ENABLE); //使能
16
17  TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE ); //设置中断参数TIM3
18
19
20   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //设置NVIC参数,注意groop_1

21   NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //全局中断设置

22   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; 配对groop_1

23   NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;

24   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能

25   NVIC_Init(&NVIC_InitStructure);

26 }

 

打下划线的是根据自己需求而改的

思路:定时1s的流水灯,需要使用定时器,所以使用tim.h库,通过配置time_init(计算定时时间=TIM_Period\72M\TIM_Prescaler+1)定时1s,编写中断函数void TIM3_IRQHandler()对灯进行控制

可能对TIM3和APBx有疑问,在stm32时钟分配图中有介绍

 TIM1/8---->APB2    TIM2-7-------->APB1

这也可以在库中可以找到

stm32f10x.h  ,

类似于结构体可以搜索InitStructure找到相关结构体写法,然后使用go to definition直接找到结构体里面的参数

以上是关于怎样做到stm32 定时器 定时时间可调,(又不用初始化)的主要内容,如果未能解决你的问题,请参考以下文章

如何运用STM32 的一个通用定时器产生频率可调的PWM

如何用stm32的定时器产生一路pwm输出,周期为500hz,占空比0%~100%可调,完整c语言程序。

想用stm32的定时器,定时一分钟,该怎样做呀?尽量描述细点,谢谢了

stm32怎样实现不同定时器产生不同频率的PWM波?

怎样使stm32f4内部产生正弦波驱动wm8978发出声音

stm32中如何通过定时器来设置ADC的采样率????