/* * @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成功用作于系统时钟的时钟源 // 0x00:HSI 作为系统时钟 // 0x04:HSE作为系统时钟 // 0x08:PLL作为系统时钟 while (RCC_GetSYSCLKSource() != 0x08) ; // 需与被选择的系统时钟对应起来,RCC_SYSCLKSource_PLL }