毕业设计需要使用比较多的定时器,但手上的F103C8T6核心板定时器资源比较少,所以被迫使用高级定时器1(一直都是用通用定时器,毕竟以前玩F429的时候管脚资源充足,就没有去学习高级定时器的用法,以为完全一样的用法,但是移植程序过程还是发现好些需要注意的地方)。下面列出程序中与通用定时器有差别的地方。
用到的定时器是TIM1通道4,原型是作为超声波捕获,单独拿出配置定时器输入捕获函数和中断服务函数来说明,程序都写了注释,没有一一说明的地方可以直接看注释。
//使能TIM1和GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);//初始化TIME时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//初始化GPIOA时钟
2. GPIOA中的PA11配置为输入模式,PA12设置为输出模式
//配置PA11
GPIOA_Initstructure.GPIO_Pin=GPIO_Pin_11;//PA11
GPIOA_Initstructure.GPIO_Mode=GPIO_Mode_IPD;//输入
GPIO_ResetBits(GPIOA,GPIO_Pin_11); //PA11 下拉
GPIO_Init(GPIOA,&GPIOA_Initstructure);
//配置PA12
GPIOA_Initstructure.GPIO_Pin=GPIO_Pin_12;//PA12
GPIOA_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;//输出
GPIOA_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIOA_Initstructure);
关于GPIO口的八种模式原子论坛有帖子说的很详细,以前看过的,有兴趣可以去搜索。
//初始化 TIM1, 设置 TIM1 的 ARR 和 PSC
TIM1_CH4_Handler.TIM_Prescaler=psc;//预分频系数
TIM1_CH4_Handler.TIM_Period=arr;//自动重装载值
TIM1_CH4_Handler.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
TIM1_CH4_Handler.TIM_ClockDivision=TIM_CKD_DIV1;//预分频系数为1
TIM1_CH4_Handler.TIM_RepetitionCounter=0;//设置重复溢出次数,就是多少次溢出后进入中断,一般为0,只有高级定时器才有用
TIM_TimeBaseInit(TIM1,&TIM1_CH4_Handler);
//设置 TIM1 的输入比较参数,开启输入捕获
TIM1_IC_Handler.TIM_Channel=TIM_Channel_4;//TIM1通道4
TIM1_IC_Handler.TIM_ICFilter=0x00;//输入滤波器长度为0
TIM1_IC_Handler.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升沿捕获
TIM1_IC_Handler.TIM_ICPrescaler=TIM_ICPSC_DIV1;//预分频系数,不分频
TIM1_IC_Handler.TIM_ICSelection=TIM_ICSelection_DirectTI; //映射到 TI1 上
TIM_ICInit(TIM1,&TIM1_IC_Handler);
TIM1_CH4_Handler.TIM_RepetitionCounter=0;//设置重复溢出次数,就是多少次溢出后进入中断,一般为0,只有高级定时器才有用到
//使能捕获和更新中断(设置 TIM1 的 DIER 寄存器)
TIM_ITConfig( TIM1,TIM_IT_Update|TIM_IT_CC4,ENABLE);//允许更新中断和捕获中断
//设置中断分组
NVIC_Initstructure.NVIC_IRQChannel=TIM1_CC_IRQn;//定时器1
NVIC_Initstructure.NVIC_IRQChannelCmd=ENABLE;//使能TIM1
NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2
NVIC_Initstructure.NVIC_IRQChannelSubPriority=0;//子优先级0
NVIC_Init(&NVIC_Initstructure);
TIM_CtrlPWMOutputs(TIM1,ENABLE); //主输出使能
//使能定时器(设置 TIM1 的 CR1 寄存器)
TIM_Cmd(TIM1,ENABLE);//使能定时器1
//定时器1中断服务程序
void TIM1_CC_IRQHandler(void)
{
if((TIM1CH4_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{
if(TIM1CH4_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM1CH4_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM1CH4_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM1CH4_CAPTURE_VAL=0XFFFF;
}else TIM1CH4_CAPTURE_STA++;
}
}
if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET)//捕获 1 发生捕获事件
{
if(TIM1CH4_CAPTURE_STA&0X40) //捕获到一个下降沿
{
TIM1CH4_CAPTURE_STA|=0X80; //标记成功捕获到一次上升沿
TIM1CH4_CAPTURE_VAL=TIM_GetCapture4(TIM1);
TIM_OC4PolarityConfig(TIM1,TIM_ICPolarity_Rising);
//CC1P=0 设置为上升沿捕获
}else //还未开始,第一次捕获上升沿
{
TIM1CH4_CAPTURE_STA=0; //清空
TIM1CH4_CAPTURE_VAL=0;
TIM_SetCounter(TIM1,0);
TIM1CH4_CAPTURE_STA|=0X40; //标记捕获到了上升沿
TIM_OC4PolarityConfig(TIM1,TIM_ICPolarity_Falling);
//CC1P=1 设置为下降沿捕获
}
}
}
TIM_ClearITPendingBit(TIM1, TIM_IT_CC4|TIM_IT_Update); //清除中断标志位
}
以上,就是使用TIM1做输入捕获的过程。