stm32f103zet6高级,通用,基本定时器功能汇总:1普通定时,2输入捕获,3输出比较,4PWM,5单脉冲模式输出,6标...

2019-07-21 02:22发布

本帖最后由 nashui_sx 于 2019-7-15 09:06 编辑

修正一个错误,输出比较的时候,两个定时器共用CH1_Flag造成干扰,前面分别加上定时器标记 TIM1_CH1_Flag,别的还未发现错误,已经重新上传
//每个功能都在stm32f103zet6上测试通过
// 1普通定时               2输入捕获                     3输出比较                          4PWM                5单脉冲输出
//TIMx_Time_Init   TIMx_InputCapture_Init   TIMx_OutputCompare_Init    TIMx_Pwm_Init   TIMx_OnePulseOutput_Init
//基本定时器TIM6,7只有1定时的功能,剩余的4个功能分别用高级TIM1 通用TIM2进行测试,便于大家移植
在time.h 中切换功能
#define  TIMx_Time_Init_Test                  0
#define  TIMx_InputCapture_Init_Test       0
#define  TIMx_OutputCompare_Init_Test   0
#define  TIMx_Pwm_Init_Test                 0
#define  TIMx_OnePulseOutput_Init_Test  0
定时器5种模式实验.rar (314.4 KB, 下载次数: 1166) 4 天前 上传 点击文件名下载附件 具体细节参考程序内部说明
例如输出比较可以产生特殊波形
QQ截图20190715083707.jpg
增加两个定时器功能:6标志量触发单脉冲输出             7定时器主从模式产生准确脉冲个数
添加2功能 定时器5种模式实验.rar (315.12 KB, 下载次数: 1104) 4 天前 上传 点击文件名下载附件
1普通定时    : 基本定时
2输入捕获   :一个通道捕获高电平,测量占空比,一个通道测量两个上升沿间隔测量周期
3输出比较   :一个定时器可以产生4中周期不同占空比的pwm,还可以翻转任意io实现任意引脚输出pwm
                  (还可以实现一个定时器实现4种基本定时,大家自己扩展吧)                 
4PWM        :一个定时器产生一种周期的4种占空比pwm
5单脉冲输出:通道2检测到上升沿后,通道1延时设定时间后输出一个设定时间的高电平脉冲

6标志量触发单脉冲输出            
7定时器主从模式产生准确脉冲个数
8 TIM计数模式c8t6做的 TIM 计数模式.rar (3.28 MB, 下载次数: 675) 2017-12-5 20:12 上传 点击文件名下载附件   TIM1在43楼
单脉冲输出的现象:
1.png



























友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
49条回答
Chongki
1楼-- · 2019-07-26 05:14
楼主又试过TIM的ETR捕获吗?我试的一直不行。。。
nashui_sx
2楼-- · 2019-07-26 07:25
Chongki 发表于 2018-12-18 22:52
楼主又试过TIM的ETR捕获吗?我试的一直不行。。。

试过,c8t6的,只有两个定时器可用
Chongki
3楼-- · 2019-07-26 13:14
nashui_sx 发表于 2018-12-19 13:28
试过,c8t6的,只有两个定时器可用

没说清楚,是TIM1不行。。。现在的是TIM2的可以,,,TIM1的不行,搞不清楚什么原因,网上的方案基本都试过了,不知道楼主有没有什么好办法?
nashui_sx
4楼-- · 2019-07-26 16:18
 精彩回答 2  元偷偷看……
Chongki
5楼-- · 2019-07-26 21:49
nashui_sx 发表于 2018-12-19 21:13
第8条就是呀  tim1 tim2都写好了

8 TIM计数模式c8t6做的   TIM 计数模式.rar (3.28 MB, 下载次数: 519)  这个?这个里面没有TIM1啊...
nashui_sx
6楼-- · 2019-07-27 03:21
Chongki 发表于 2018-12-19 22:05
8 TIM计数模式c8t6做的   TIM 计数模式.rar (3.28 MB, 下载次数: 519)  这个?这个里面没有TIM1啊...
不好意思,估计发的早没有,新的复制给你了
[mw_shl_code=applescript,true]#include "tim_count.h"
//计数器模式

//这种计数器模式方案只能用ETR引脚
//stm32f103c8只有TIM1_ETR(PA12),和TIM2_CH1_ETR(PA0)两个可以用


volatile u16 Tim1_Update_Flag=0,Tim2_Update_Flag=0;        


//计数模式arr=计数到多少产生中断,psc没用,设置0
void TIM1_Init(u16 arr,u16 psc,IRQ_IRQHandler_Callback cb)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        
        
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;           //上拉输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
        GPIO_Init(GPIOA, &GPIO_InitStructure);
   
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //时钟使能
        

        TIM_DeInit(TIM1);//将外设TIMx寄存器重设为缺省值
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到100
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率                  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设0置时钟分割:TDTS = Tck_tim           psc
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

  //注册回调函数
  TIM1_UP_IRQHandler_Callback=cb;
               
        //中断优先级NVIC设置
        NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;  //TIM2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIM1_UP_IRQHandler_NVIC_PP;  //先占优先级2级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级2级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
  
        TIM_ETRClockMode2Config(TIM1, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0); //设置为外部计数模式
        
        TIM_SetCounter(TIM1, 0);//计数器清零
        TIM_ClearITPendingBit(TIM1,TIM_IT_Update); //清除中断标志位
  TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断
        TIM_Cmd(TIM1, ENABLE);  //使能TIMx外设        
}


//计数模式arr=计数到多少产生中断,psc没用,设置0
void TIM2_Init(u16 arr,u16 psc,IRQ_IRQHandler_Callback cb)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        
        
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;           //上拉输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
        GPIO_Init(GPIOA, &GPIO_InitStructure);
   
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
        TIM_DeInit(TIM2);//将外设TIMx寄存器重设为缺省值
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到100
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率                  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设0置时钟分割:TDTS = Tck_tim           psc
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

  //注册回调函数
  TIM2_IRQHandler_Callback=cb;
        
        //中断优先级NVIC设置
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级2级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
  
        TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0); //设置为外部计数模式
        
               
        TIM_SetCounter(TIM2, 0);//计数器清零
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //清除中断标志位
  TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断
        TIM_Cmd(TIM2, ENABLE);  //使能TIMx外设
}
void Count_Init(u16 yichu_max)
{
  TIM1_Init(yichu_max-1,0,TIM1_UP_IRQHandler_Callback_Count);
  TIM2_Init(yichu_max-1,0,TIM2_IRQHandler_Callback_Count);//计数模式arr=Update_TIM_Period计数到100多少产生中断,psc没用,设置0
}
void TIM1_UP_IRQHandler_Callback_Count(void)   
{
                if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)  
                {
                                TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
                          Tim1_Update_Flag++;//标记溢出次数
                }
}
//定时器2中断服务程序
void TIM2_IRQHandler_Callback_Count(void)   //TIM3中断
{
                if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM6更新中断发生与否
                {
                                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除TIMx更新中断标志
        Tim2_Update_Flag++;//标记溢出次数               
                }
}
u32 Get_MaiChong(u8 ch)
{
         u32 count=0;
         switch(ch)
         {
                 case 1:count=Tim1_Update_Flag*Update_TIM_Period+TIM_GetCounter(TIM1);break;
                 case 2:count=Tim2_Update_Flag*Update_TIM_Period+TIM_GetCounter(TIM2);break;
         }
         return count;
}






#ifndef _tim_count_H_
#define _tim_count_H_         
#include "sys.h"


#define Update_TIM_Period  1000

void Count_Init(u16 yichu_max);
void TIM1_Init(u16 arr,u16 psc,IRQ_IRQHandler_Callback cb);
void TIM2_Init(u16 arr,u16 psc,IRQ_IRQHandler_Callback cb);

u32  Get_MaiChong(u8 ch);
void TIM1_UP_IRQHandler_Callback_Count(void);   
void TIM2_IRQHandler_Callback_Count(void);  
                                    
#endif[/mw_shl_code]

一周热门 更多>