/*************************** (C) COPYRIGHT 2018 Ping **************************** * 文件名 :timer.c * 描 述 :定时器驱动代码 * 版 本 :V1.0 * 作 者 :XuZhongPing * 日 期 :2017/02/07 *********************************************************************************/ #include "timer.h" #include "usart1.h" #include "device.h" #include "data_typedef.h" uint32_t time_value = 0;//uip 计时器,每10ms增加1. /* *********************************************************************** * 函 数 名: clock_time * 功能说明: 取得当前计时值 * 形 参: 无 * 返 回 值: 当前计时值 *********************************************************************** */ clock_time_t clock_time(void) { return time_value; /* 10ms 单位 */ } /* *********************************************************************** * 函 数 名: timer_set * 功能说明: 设置一个定时间隔 * 形 参: * t:定时变量 * interval:定时间隔值 * 返 回 值: 无 *********************************************************************** */ void timer_set(timer *t, clock_time_t interval) { t->interval = interval; t->start = clock_time(); } /* *********************************************************************** * 函 数 名: timer_reset * 功能说明: 对定时变量进行复位 * 形 参: * t:定时变量 * 返 回 值: 无 *********************************************************************** */ void timer_reset(timer *t) { t->start += t->interval; } /* *********************************************************************** * 函 数 名: timer_reset_interval * 功能说明: 重新设置定时时间 * 形 参: * t:定时变量 * 返 回 值: 无 *********************************************************************** */ void timer_reset_interval(timer *t, clock_time_t interval) { t->interval = interval; } /* *********************************************************************** * 函 数 名: timer_restart * 功能说明: 从当前时间点重新启动定时器 * 形 参: * t:定时变量 * 返 回 值: 无 *********************************************************************** */ void timer_restart(timer *t) { t->start = clock_time(); } /* *********************************************************************** * 函 数 名: timer_expired * 功能说明: 判断一个定时器是否达到定时时间 * 形 参: * t:定时变量 * 返 回 值: 非零则已经到了定时时间,零则定时还未到 *********************************************************************** */ int timer_expired(timer *t) { return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; } /* *********************************************************************** * 函 数 名: timer_remaining * 功能说明: 判断一个定时器还剩下多少时间达到定时时间 * 形 参: * t:定时变量 * 返 回 值: 返回定时器剩余时间 *********************************************************************** */ uint32_t timer_remaining(timer *t) { uint32_t res = 0; if(clock_time() < (t->start + (clock_time_t)t->interval)) { res = (t->start + (clock_time_t)t->interval) - clock_time(); return res; }else{ return 0; } } //定时器定时器2用于开始一个软件定时供外部程序使用 //单位为100ms(0.1S) /* *********************************************************************** * 函 数 名: TIM2_Int_Init * 功能说明: 定时器2初始化配置 * 形 参:arr:自动重装值 * psc:时钟预分频数 * 返 回 值: 无 *********************************************************************** */ void TIM2_Int_Init(uint16_t arr,uint16_t psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率(即0.1ms周期) TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITConfig( TIM2, TIM_IT_Update|TIM_IT_Trigger, ENABLE); //使能定时器2更新触发中断 TIM_Cmd(TIM2, ENABLE); //使能TIMx外设 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 } /* *********************************************************************** * 函 数 名: TIM2_IRQHandler * 功能说明: 定时器2中断服务子程序 * 形 参:无 * 返 回 值: 无 *********************************************************************** */ void TIM2_IRQHandler(void) //TIM2中断 { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 { time_value++; //计时器增加1 } TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源 } ///////////////////////////////////////////////////////////////////////////////////////////////// //定时器3部分(用于按键扫描)每10ms中断一次 /* *********************************************************************** * 函 数 名: TIM3_Int_Init * 功能说明: 定时器3初始化配置 * 形 参:arr:自动重装值 * psc:时钟预分频数 * 返 回 值: 无 *********************************************************************** */ void TIM3_Int_Init(uint16_t arr,uint16_t psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率(即0.1ms周期) TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITConfig( TIM3, TIM_IT_Update|TIM_IT_Trigger, ENABLE); //使能定时器2更新触发中断 TIM_Cmd(TIM3, ENABLE); //使能TIMx外设 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 } /* *********************************************************************** * 函 数 名: TIM3_IRQHandler * 功能说明: 定时器2中断服务子程序 * 形 参:无 * 返 回 值: 无 *********************************************************************** */ void TIM3_IRQHandler(void) //TIM3中断 { uint8_t keyTemp = 0; static uint8_t timerCut = 0; if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 { if(deviceInitFlag == 1) { // OptoKeyScanning(); // BottleScanning(); //调用瓶子扫描检测函数 if(keyType == 0) { keyTemp = KeyScanning(); }else if(keyType == 1){ keyTemp = TouchKeyScanning(); } if(keyTemp != 0) { keyValue = keyTemp; //输出键值由外部读取后清除 } } } TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源 } ///////////////////////////////////////////////////////////////////////////////////////////////// //定时器4部分(用于超声波测距) /* *********************************************************************** * 函 数 名: TIM4_Int_Init * 功能说明: 定时器4初始化配置 * 形 参:arr:自动重装值 * psc:时钟预分频数 * 返 回 值: 无 *********************************************************************** */ void TIM4_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能 //定时器TIM4初始化 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位 TIM_ITConfig(TIM4, TIM_IT_Update | TIM_IT_Trigger, ENABLE); //使能指定的TIM4中断,允许更新中断 //中断优先级NVIC设置 NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM4, DISABLE); // TIM_Cmd(TIM4, ENABLE); } /* *********************************************************************** * 函 数 名: TIM4_IRQHandler * 功能说明: 定时器4中断服务子程序 * 形 参:无 * 返 回 值: 无 *********************************************************************** */ void TIM4_IRQHandler(void) //TIM4中断 { if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查TIM4更新中断发生与否 { TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清除TIMx更新中断标志 } } ///////////////////////////////////////////////////////////////////////////////////////////////// //定时器4部分(用于二维码读头数据接收完成标记用) /* *********************************************************************** * 函 数 名: TIM5_Int_Init * 功能说明: 定时器5初始化配置 * 形 参:arr:自动重装值 * psc:时钟预分频数 * 返 回 值: 无 *********************************************************************** */ void TIM5_Int_Init(uint16_t arr, uint16_t psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //定时器TIM5初始化 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位 TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断 //中断优先级NVIC设置 NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; //TIM5中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级3级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级2级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器 TIM_Cmd(TIM5, DISABLE); //失能TIMx外设 } /* *********************************************************************** * 函 数 名: TIM5_IRQHandler * 功能说明: 定时器4中断服务子程序 * 形 参:无 * 返 回 值: 无 *********************************************************************** */ void TIM5_IRQHandler(void) { if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //检查TIM5更新中断发生与否 { USART1_RX_STA |= 1<<15; //标记接收完成 TIM_ClearITPendingBit(TIM5, TIM_IT_Update); //清除TIMx更新中断标志 TIM_Cmd(TIM5, DISABLE); //关闭TIMx } } /******************** (C) COPYRIGHT 2018 Ping *****END OF FILE*******************/