Job_SignsPads/STM32/Code/STM32F405/Application/timer.c
2025-04-22 10:29:37 +08:00

554 lines
17 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @Description:
* @Version: 1.0
* @Autor: lzc
* @Date: 2022-08-19 12:48:36
* @LastEditors: lzc
* @LastEditTime: 2024-05-16 14:51:06
*/
#include "main.h"
#include "drv_SGM58031.h"
#include "MyBandFitter.h"
extern WarningMsg_t WarningMsg;
extern uint16_t TimeClock_Recalibrate_Count;
/* 当前保存时间的变量 */
TimingVarTypeDef Time;
uint32_t time_up_num = 0;
/* 系统滴答定时器的中断次数 */
uint32_t TimeupTimes;
/////////////////////////////////通用定时器2中断初始化ADC///////////////////////////////////
// arr自动重装值。
// psc时钟预分频数
// 定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
// 200*160 /16 = 2ms
// 定时器时钟84M分频系数8400所以84M/8400=10Khz的计数频率计数5000次为500ms
// Ft=定时器工作频率,单位:Mhz
// 这里使用的是定时器3!
void TIM2_Int_Init(u16 arr, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /// 使能TIM3时钟
TIM_TimeBaseInitStructure.TIM_Period = arr; // 自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler = psc; // 定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); // 初始化TIM3
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 允许定时器3更新中断
TIM_Cmd(TIM2, DISABLE); // 使能定时器3
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // 定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; // 抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; // 子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int FitterCount_Heart = 0;
int FitterCount_Breath = 0;
int FitterCount_CheckBed = 0;
char FitterCollectDoneFlag_Heart = 0;
char FitterCollectDoneFlag_Breath = 0;
char FitterCollectDoneFlag_CheckBed = 0;
// 定时器2中断服务函数
char TIM2_EntryFlag = 0;
uint16_t TIM2_CountVal = 0;
float SGM58031_ADC_Value = 0.0f;
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) // 溢出中断
{
if (TIM2_CountVal >= 10)
{
TIM2_CountVal = 0;
// printf("TickDone !!!\r\n");
SGM58031_ADC_Value = SGM58031_ReadADCValue();
FitterOPMData_Heart[FitterCount_Heart] = 10 * log10(SGM58031_ADC_Value / pow(10, channel_1310)) + cal_1310;
FitterOPMData_Breath[FitterCount_Breath] = 10 * log10(SGM58031_ADC_Value / pow(10, channel_1310)) + cal_1310;
FitterOPMData_CheckBed[FitterCount_CheckBed] = 10 * log10(SGM58031_ADC_Value / pow(10, channel_1310)) + cal_1310;
if (FitterCollectDoneFlag_Heart != 1)
{
FitterCount_Heart++;
if (FitterCount_Heart == HEART_FITTER_LENGTH)
{
FitterCount_Heart = HEART_FITTER_LENGTH - 50;
FitterCollectDoneFlag_Heart = 1;
}
}
if (FitterCollectDoneFlag_Breath != 1)
{
FitterCount_Breath++;
if (FitterCount_Breath == LENGTH_SAMPLES_BREATH)
{
FitterCount_Breath = LENGTH_SAMPLES_BREATH - 50;
FitterCollectDoneFlag_Breath = 1;
}
}
if (FitterCollectDoneFlag_CheckBed != 1)
{
FitterCount_CheckBed++;
if (FitterCount_CheckBed == LENGTH_SAMPLES_IN_OFF_BED)
{
FitterCount_CheckBed = LENGTH_SAMPLES_IN_OFF_BED - 50;
FitterCollectDoneFlag_CheckBed = 1;
}
}
}
TIM2_CountVal++;
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志位
}
}
/////////////////////////////////通用定时器3中断初始化LED///////////////////////////////////
// arr自动重装值。
// psc时钟预分频数
// 定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
// 200*160 /16 = 2ms
// 定时器时钟84M分频系数8400所以84M/8400=10Khz的计数频率计数5000次为500ms
// Ft=定时器工作频率,单位:Mhz
// 这里使用的是定时器3!
void TIM3_Int_Init(u16 arr, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /// 使能TIM3时钟
TIM_TimeBaseInitStructure.TIM_Period = arr; // 自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler = psc; // 定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); // 初始化TIM3
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // 允许定时器3更新中断
TIM_Cmd(TIM3, DISABLE); // 使能定时器3
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // 定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; // 抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; // 子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// 定时器3中断服务函数
char TIM3_EntryFlag = 0;
uint16_t TIM3_CountVal = 0;
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) // 溢出中断
{
led_time++;
if (led_time > 250)
{
LED_judge();
led_time = 0;
// printf("Timer Tiger\n");
}
TIM3_EntryFlag = 1;
TIM3_CountVal++;
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 清除中断标志位
}
}
/**
* @function:
* @brief: None
* @return {*}
* @author: lzc
*/
/*
void TIM3_Callback(void)
{
if (TIM3_EntryFlag)
{
TIM3_EntryFlag = 0;
if (Key_Cal_Flag == 0)
{
if (wifi_len < model_num)
{
get_opm_number();
}
else if (wifi_len >= model_num) // model_num=500,一秒钟
{
wifi_len = 0;
BH_time++;
stage_time++;
currentSize_num++;
if (currentSize_num > 400)
currentSize_num = 300;
if (BH_time >= 10) // 10秒钟算一次呼吸
{
BH_time = 0;
start_calculate_flg = 1;
}
#if SLEEP_DEBUG_MODE
if (stage_time >= (12 / 2)) // 12秒钟算一次睡眠分期
#else
if (stage_time >= (12 / 2)) // 12秒钟算一次睡眠分期
#endif
{
stage_time = 0;
start_stage_flg = 1;
}
get_opm_number();
}
wifi_len++;
}
}
}
*/
void TIM3_Callback(void)
{
if (TIM3_EntryFlag)
{
TIM3_EntryFlag = 0;
if (Key_Cal_Flag == 0)
{
if (wifi_len >= model_num) // model_num=500,一秒钟
{
wifi_len = 0;
BH_time++;
stage_time++;
currentSize_num++;
if (currentSize_num > 400)
currentSize_num = 300;
if (BH_time >= 10) // 10秒钟算一次呼吸
{
BH_time = 0;
start_calculate_flg = 1;
}
}
get_opm_number();
wifi_len++;
}
}
}
/////////////////////////////////通用定时器4中断初始化(串口接收)///////////////////////////////////
// arr自动重装值。
// psc时钟预分频数
// 定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
// 200*160 /16 = 2ms
// 定时器时钟84M分频系数8400所以84M/8400=10Khz的计数频率计数5000次为500ms
// Ft=定时器工作频率,单位:Mhz
// 这里使用的是定时器4!
void TIM4_Int_Init(u16 arr, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /// 使能TIM4时钟
TIM_TimeBaseInitStructure.TIM_Period = arr; // 自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler = psc; // 定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure); // 初始化TIM3
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); // 允许定时器4更新中断
TIM_Cmd(TIM4, DISABLE); // 使能定时器4
Time.OverTimeVal = 2;
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; // 定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; // 抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x04; // 子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// 定时器4中断服务函数
uint16_t Count_ConnectVal = 0;
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET) // 溢出中断
{
#if USART_TIMER_IRQ_ENABLE
Time.CountNum++;
if (!USART_DealFlag && Time.CountNum >= Time.OverTimeVal)
{
// 串口超时,接收完成
USART_DealFlag = 1;
// 清除中断标志位
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
// 关闭定时器
TIM_Cmd(TIM4, DISABLE);
}
#endif
TIM_ClearITPendingBit(TIM4, TIM_IT_Update); // 清除中断标志位
}
}
/////////////////////////////////通用定时器7中断初始化系统定时器///////////////////////////////////
// arr自动重装值。
// psc时钟预分频数
// 定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
// 200*160 /16 = 2ms
// 定时器时钟84M分频系数8400所以84M/8400=10Khz的计数频率计数5000次为500ms
// Ft=定时器工作频率,单位:Mhz
// 这里使用的是定时器7!
void TIM7_Int_Init(u16 arr, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE); /// 使能TIM6时钟
TIM_TimeBaseInitStructure.TIM_Period = arr; // 自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler = psc; // 定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseInitStructure); // 初始化TIM7
TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE); // 允许定时器6更新中断
TIM_Cmd(TIM7, DISABLE); // 使能定时器6
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn; // 定时器7中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; // 抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x04; // 子优先级4
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// 定时器7中断服务函数
static uint16_t s_Count_ConnectVal = 0;
extern char MinutesTickCount;
extern char PowerOn_OneMinuteCount;
extern uint16_t FiveMinutesCount;
extern uint16_t OneMinutesCountDown;
extern uint32_t OverTimeCount;
extern uint64_t keepAliveCount;
extern uint32_t ThirdMinutesCountDown ;
void TIM7_IRQHandler(void)
{
if (TIM_GetITStatus(TIM7, TIM_IT_Update) == SET) // 溢出中断
{
s_Count_ConnectVal++;
timeClockCount += 2;
timeClockCount_Send += 2;
if (s_Count_ConnectVal >= 250) // 500ms
{
OverTimeCount++;
keepAliveCount++;
MinutesTickCount++;
PowerOn_OneMinuteCount++;
WarningMsg.SysTick_Count++;
TimeClock_Recalibrate_Count++;
// printf("SysTick : %d\n", MinutesTickCount);
s_Count_ConnectVal = 0;
if (OffBed_Flag == 4 && FiveMinutesCount <= 720) // 在床才会增加
FiveMinutesCount++;
// 时间戳下发成功
if (TimeClock_Flag)
{
if(ThirdMinutesCountDown >= (3 * 60 * 2))
OneMinutesCountDown++;
ThirdMinutesCountDown++;
}
else
{
OneMinutesCountDown = 0;
ThirdMinutesCountDown = 0;
}
}
TIM_ClearITPendingBit(TIM7, TIM_IT_Update); // 清除中断标志位
}
}
/////////////////////////////////通用定时器5中断初始化计算///////////////////////////////////
// arr自动重装值。
// psc时钟预分频数
// 定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
// 200*160 /16 = 2ms
// 定时器时钟84M分频系数8400所以84M/8400=10Khz的计数频率计数5000次为500ms
// Ft=定时器工作频率,单位:Mhz
// 这里使用的是定时器4!
void TIM5_Int_Init(u16 arr, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); /// 使能TIM5时钟
TIM_TimeBaseInitStructure.TIM_Period = arr; // 自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler = psc; // 定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure); // 初始化TIM3
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE); // 允许定时器5更新中断
TIM_Cmd(TIM5, DISABLE); // 使能定时器5
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; // 定时器5中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; // 抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; // 子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// 定时器5中断服务函数
void TIM5_IRQHandler(void)
{
static uint16_t PowerOnCounters = 0;
if (TIM_GetITStatus(TIM5, TIM_IT_Update) == SET) // 溢出中断
{
// 进入定时器关闭串口,防止宕机
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
USART_Cmd(USART1, DISABLE);
if (Key_Cal_Flag == 0)
{
BH_time++;
if (BH_time >= (500 * 2.2)) // 2.2s 算一次心率呼吸
{
BH_time = 0;
start_calculate_flg = 1;
}
// 初次上电先算500次
if (PowerOnCounters < 500)
{
get_opm_number();
PowerOnCounters++;
}
else
{
if (wifi_len < 60)
{
get_opm_number();
}
else if (wifi_len >= 60) // 一秒钟算一次
{
wifi_len = 0;
stage_time++;
currentSize_num++;
if (currentSize_num > 400)
currentSize_num = 300;
get_opm_number();
}
}
wifi_len++;
}
USART_Cmd(USART1, ENABLE);
TIM_ClearITPendingBit(TIM5, TIM_IT_Update); // 清除中断标志位
}
}
////////////////////////////////////滴答定时器初始化 unused/////////////////////////////////////////
/**
* @brief 配置系统滴答定时器 SysTick
* @param 无
* @retval 1 = failed, 0 = successful
*/
uint32_t SysTick_Init(void)
{
/* 关闭滴答定时器且禁止中断 */
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
/* set reload register */
// NOTE: 由于在延时部分将重载值更改,此处不做修改!
SysTick->LOAD = ((5000000) & SysTick_LOAD_RELOAD_Msk) - 1;
return (1);
}
/**
* @brief 滴答定时器 SysTick 计时启动
* @param 无
* @retval 无
*/
void SysTick_Time_Start(void)
{
/* 滴答定时器的数据寄存器清零 */
SysTick->VAL = 0;
/* 滴答定时器中断次数清零 */
WarningMsg.SysTick_Count = 0;
/* 启动滴答定时器 */
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
}
/**
* @brief 滴答定时器 SysTick 计时停止
* @param 无
* @retval 无
*/
void SysTick_Time_Stop(void)
{
/* 滴答定时器的数据寄存器清零 */
SysTick->VAL = 0;
/* 滴答定时器中断次数清零 */
WarningMsg.SysTick_Count = 0;
/* 关闭滴答定时器且禁止中断 */
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
}
/**
* @brief 滴答定时器 SysTick
* @param 无
* @retval 无
*/
uint32_t Get_SysTick_Time(void)
{
// return Time.CountNum;
return 0;
}
/**
* @brief 滴答定时器 SysTick
* @param 无
* @retval 无
*/
void Set_SysTick_OverTimeVal(uint32_t Val)
{
// Time.OverTimeVal = Val;
}
/**
* @function:RCC_Configuration
* @brief 时钟更改 单位是MHZ
* @return {*}
* @author: lzc
* @description:
*/
void RCC_Configuration(char SysClockFrq)
{
// 16MHz 就直接跳出
if (SysClockFrq == 16)
return; //
RCC_DeInit(); // 将外设 RCC寄存器重设为缺省值
RCC_AHB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // 使能GPIOB时钟
PWR_MainRegulatorModeConfig(PWR_Regulator_Voltage_Scale1);
RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = CLK SysClockFrq
RCC_PCLK1Config(RCC_HCLK_Div4); // APB1 = CLK SysClockFrq/4
RCC_PCLK2Config(RCC_HCLK_Div2); // APB2 = CLK SysClockFrq/2
RCC_HSICmd(ENABLE); // 使能HSI
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET)
; // 等待HSI使能成功
FLASH_PrefetchBufferCmd(ENABLE);
FLASH_SetLatency(FLASH_Latency_5);
// 设置 PLL 时钟源及倍频系数
RCC_PLLConfig(RCC_PLLSource_HSI, 8, SysClockFrq, 2, 4); // 16MHZ 8 分频->2MHZ 108 倍频 2 分频 = 108MHZ
RCC_PLLCmd(ENABLE); // 如果PLL被用于系统时钟,那么它不能被失能
// 等待指定的 RCC 标志位设置成功 等待PLL初始化成功
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
;
// 设置系统时钟SYSCLK 设置PLL为系统时钟源
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // 选择想要的系统时钟
// 等待PLL成功用作于系统时钟的时钟源
// 0x00HSI 作为系统时钟
// 0x04HSE作为系统时钟
// 0x08PLL作为系统时钟
while (RCC_GetSYSCLKSource() != 0x08)
; // 需与被选择的系统时钟对应起来RCC_SYSCLKSource_PLL
}