本帖最后由 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 天前 上传
点击文件名下载附件
具体细节参考程序内部说明
例如输出比较可以产生特殊波形
增加两个定时器功能: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楼
单脉冲输出的现象:
试过,c8t6的,只有两个定时器可用
没说清楚,是TIM1不行。。。现在的是TIM2的可以,,,TIM1的不行,搞不清楚什么原因,网上的方案基本都试过了,不知道楼主有没有什么好办法?
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]
一周热门 更多>