Job_SignsPads/STM32/Code/STM32F405/Application/timer.c

554 lines
17 KiB
C
Raw Normal View History

2025-04-22 02:29:37 +00:00
/*
* @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
}