MAX30102的STM32驱动程序

news/2024/11/23 23:29:53/

MAX30102的STM32驱动程序
效果演示:

CSDN演示专用 MAX30102

程序实现心率计算,心率波形显示,血氧计算。
下载文件中包含程序源码和PCB工程文件,PCB工程文件成品如演示视频,除基本功能外加入锂电池供电和充电功能。
源码过多,只展示了部分,全部源码下载链接:
CSDN:
https://download.csdn.net/download/qq_19534483/20368390
百度云:
链接:https://pan.baidu.com/s/1SFQCT1Nd2H6Dm05Rs2tHQA 提取码:hss2
github:
https://github.com/ahukl1/MAX30102.git

部分源码如下:
MAX30102.c:

int maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data){HAL_I2C_Mem_Write(&hi2c1, I2C_WRITE_ADDR,uch_addr, I2C_MEMADD_SIZE_8BIT,&uch_data,1, 1000);
}int maxim_max30102_reset()
{maxim_max30102_write_reg(REG_MODE_CONFIG,0x40);maxim_max30102_write_reg(REG_MODE_CONFIG,0x03);
maxim_max30102_write_reg(REG_INTR_ENABLE_1,0x40); // INTR settingmaxim_max30102_write_reg(REG_INTR_ENABLE_2,0x50);maxim_max30102_write_reg(REG_FIFO_WR_PTR,0x00); //FIFO_WR_PTR[4:0]maxim_max30102_write_reg(REG_OVF_COUNTER,0x00);  //OVF_COUNTER[4:0]maxim_max30102_write_reg(REG_FIFO_RD_PTR,0x00) ; //FIFO_RD_PTR[4:0]maxim_max30102_write_reg(REG_FIFO_CONFIG,0x0f);  //sample avg = 1, fifo rollover=false, fifo almost full = 17
maxim_max30102_write_reg(REG_MODE_CONFIG,0x03)  ; //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LEDmaxim_max30102_write_reg(REG_SPO2_CONFIG,0x27);  // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS) 
maxim_max30102_write_reg(REG_LED1_PA,0x24) ;  //Choose value for ~ 7mA for LED1
maxim_max30102_write_reg(REG_LED2_PA,0x24) ;  // Choose value for ~ 7mA for LED2
maxim_max30102_write_reg(REG_PILOT_PA,0x7f) ;  // Choose value for ~ 25mA for Pilot LEDmaxim_max30102_write_reg(0x03,0x00);maxim_max30102_write_reg(0x21,0x01);}

MAX30102.h:

#define I2C_WRITE_ADDR 0xAE
#define I2C_READ_ADDR 0xAF
#include "main.h"
//register addresses
#define REG_INTR_STATUS_1 0x00
#define REG_INTR_STATUS_2 0x01
#define REG_INTR_ENABLE_1 0x02
#define REG_INTR_ENABLE_2 0x03
#define REG_FIFO_WR_PTR 0x04
#define REG_OVF_COUNTER 0x05
#define REG_FIFO_RD_PTR 0x06
#define REG_FIFO_DATA 0x07
#define REG_FIFO_CONFIG 0x08
#define REG_MODE_CONFIG 0x09
#define REG_SPO2_CONFIG 0x0A
#define REG_LED1_PA 0x0C
#define REG_LED2_PA 0x0D
#define REG_PILOT_PA 0x10
#define REG_MULTI_LED_CTRL1 0x11
#define REG_MULTI_LED_CTRL2 0x12
#define REG_TEMP_INTR 0x1F
#define REG_TEMP_FRAC 0x20
#define REG_TEMP_CONFIG 0x21
#define REG_PROX_INT_THRESH 0x30
#define REG_REV_ID 0xFE
#define REG_PART_ID 0xFF
extern I2C_HandleTypeDef hi2c1;
int maxim_max30102_reset();
#endif

oled.c:

struct oled_pot * start_pot[8];
void write(unsigned char data,int type){switch(type){case 0:HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);break;case 1:HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);break;}HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);HAL_SPI_Transmit(&hspi1,&data,1,1000);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
}
void OLED_WrCmd(uint8_t command){write(command,0);
}
void OLED_WrData(uint8_t data){write(data,1);
}
void OLED_Init(){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);HAL_Delay(100);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);unsigned int a;for(a=0;a<5000;a++);OLED_WrCmd(0xAE);//--turn off oled panelOLED_WrCmd(0x00);//---set low column addressOLED_WrCmd(0x10);//---set high column addressOLED_WrCmd(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)OLED_WrCmd(0xB0);OLED_WrCmd(0x81);//--set contrast control registerOLED_WrCmd(0xFF); // Set SEG Output Current BrightnessOLED_WrCmd(0xa1);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常OLED_WrCmd(0xc8);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常OLED_WrCmd(0xa6);//--set normal displayOLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64)OLED_WrCmd(0x3f);//--1/64 duty``OLED_WrCmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)OLED_WrCmd(0x00);//-not offsetOLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequencyOLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/SecOLED_WrCmd(0xd9);//--set pre-charge periodOLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 ClockOLED_WrCmd(0xda);//--set com pins hardware configurationOLED_WrCmd(0x12);OLED_WrCmd(0xdb);//--set vcomhOLED_WrCmd(0x40);//Set VCOM Deselect LevelOLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)OLED_WrCmd(0x02);//OLED_WrCmd(0x8d);//--set Charge Pump enable/disableOLED_WrCmd(0x14);//--set(0x10) disableOLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7)OLED_WrCmd(0xaf);//--turn on oled panelOLED_Clear();//OLED清屏
}
void OLED_Clear(void){
unsigned char i,n;for(i=0; i<8; i++){OLED_WrCmd(0xb0+i); //设置页地址(0~7)OLED_WrCmd(0x00); //设置显示位置—列低地址OLED_WrCmd(0x10); //设置显示位置—列高地址for(n=0; n<128; n++)	OLED_WrData(0x00); //写0x00到屏幕寄存器上}
}
void OLED_Start(void){unsigned char i,n;for(i=0; i<8; i++){OLED_WrCmd(0xb0+i); //设置页地址(0~7)OLED_WrCmd(0x00); //设置显示位置—列低地址OLED_WrCmd(0x10); //设置显示位置—列高地址for(n=0; n<128; n++)	OLED_WrData(start[i][n]); //写0x00到屏幕寄存器上}
}
void OLED_Close_page(void){unsigned char i,n;for(i=0; i<8; i++){OLED_WrCmd(0xb0+i); //设置页地址(0~7)OLED_WrCmd(0x00); //设置显示位置—列低地址OLED_WrCmd(0x10); //设置显示位置—列高地址for(n=0; n<128; n++)	OLED_WrData(close_img[i][n]); //写0x00到屏幕寄存器上}
}
void OLED_page2(void){
unsigned char i,n;for(i=0; i<8; i++){OLED_WrCmd(0xb0+i); //设置页地址(0~7)OLED_WrCmd(0x00); //设置显示位置—列低地址OLED_WrCmd(0x10); //设置显示位置—列高地址for(n=0; n<128; n++)	OLED_WrData(page_2[i][n]); //写0x00到屏幕寄存器上}
}
void OLED_SetPos(uint8_t x, uint8_t y){WriteCmd(0xb0+y);WriteCmd(((x&0xf0)>>4)|0x10);WriteCmd(x&0x0f);
}
void OLED_DrawPoint(unsigned char x,unsigned char y)
{unsigned char pos,bx,temp=0;if(x>127||y>63)return;//超出范围了.pos=7-y/8;bx=y%8;temp=1<<(7-bx);OLED_SetPos(x,pos);OLED_WrData(temp);}
void OLED_ON(void){WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X14);  //开启电荷泵WriteCmd(0XAF);  //OLED唤醒}
void OLED_OFF(void){WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X10);  //关闭电荷泵WriteCmd(0XAE);  //OLED休眠
}
void OLED_ShowChar(int x,int y,char txt[]){int i,j;y=y*8;OLED_WrCmd(0xb0+2*x);OLED_WrCmd(0x10|((0xf0&y)>>4));OLED_WrCmd(0x00|(0x0f&y));for(i=0;txt[i]!='\0';i++){if(txt[i]-' '<0||txt[i]-' '>94) continue;for(j=0;j<8;j++){OLED_WrData(asc2_1206[txt[i]-' '][j]);}}OLED_WrCmd(0xb0+2*x+1);OLED_WrCmd(0x10|((0xf0&y)>>4));OLED_WrCmd(0x00|(0x0f&y));for(i=0;txt[i]!='\0';i++){if(txt[i]-' '<0||txt[i]-' '>94) continue;for(j=0;j<8;j++){OLED_WrData(asc2_1206[txt[i]-' '][j+8]);}}
}
void OLED_ShowWord(int x,int y,int f){int i,j;y=y*8;OLED_WrCmd(0xb0+2*x);OLED_WrCmd(0x10|((0xf0&y)>>4));OLED_WrCmd(0x00|(0x0f&y));for(i=0;i<16;i++){OLED_WrData(word[f][i]);}OLED_WrCmd(0xb0+2*x+1);OLED_WrCmd(0x10|((0xf0&y)>>4));OLED_WrCmd(0x00|(0x0f&y));for(i=0;i<16;i++){OLED_WrData(word[f][i+16]);}
}
void OLED_ShowNum(int y,int x,int num)
{int j;x=x*8;OLED_WrCmd(0xb0+2*y);OLED_WrCmd(0x10|((0xf0&x)>>4));OLED_WrCmd(0x00|(0x0f&x));for(j=0;j<8;j++){OLED_WrData(font_num[num][j]);}OLED_WrCmd(0xb0+2*y+1);OLED_WrCmd(0x10|((0xf0&x)>>4));OLED_WrCmd(0x00|(0x0f&x));for(j=0;j<8;j++){OLED_WrData(font_num[num][j+8]);}
}
void OLED_ShowNums(int y,int x,int num,int len)
{int i;int dat;dat=num;for (i=0;i<len;i++){OLED_ShowNum(y,x+len-i-1,dat%10);dat=dat/10;}
}

main.c:

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under Ultimate Liberty license* SLA0044, the "License"; You may not use this file except in compliance with* the License. You may obtain a copy of the License at:*                             www.st.com/SLA0044********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "MAX30102.h"
#include "stdio.h"
#include "oled.h"
char data_save;
int heart;
int red_reg[200];
int led_reg[200];
int heart_reg;
char online=1;
int reg_num=0;
int reg_heart=1;
unsigned char pData[8];
float spo2;
int flag=3;
unsigned char char_show=0;
I2C_HandleTypeDef hi2c1;SPI_HandleTypeDef hspi1;UART_HandleTypeDef huart1;osThreadId_t defaultTaskHandle;
#ifdef __GNUC__/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printfset to 'Yes') calls __io_putchar() */#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{/* Place your implementation of fputc here *//* e.g. write a character to the USART */huart1.Instance->DR = (uint8_t) ch;/* Loop until the end of transmission */while(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TC) == RESET){}return ch;
}
const osThreadAttr_t defaultTask_attributes = {.name = "defaultTask",.priority = (osPriority_t) osPriorityNormal,.stack_size = 128 * 4
};
osThreadId_t myTask02Handle;
const osThreadAttr_t myTask02_attributes = {.name = "myTask02",.priority = (osPriority_t) osPriorityLow,.stack_size = 128 * 6
};
osThreadId_t myTask03Handle;
const osThreadAttr_t myTask03_attributes = {.name = "myTask03",.priority = (osPriority_t) osPriorityLow,.stack_size = 128 * 4
};
osThreadId_t myTask04Handle;
const osThreadAttr_t myTask04_attributes = {.name = "myTask04",.priority = (osPriority_t) osPriorityLow,.stack_size = 128 * 4
};
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
void StartDefaultTask(void *argument);
void StartTask02(void *argument);
void StartTask03(void *argument);
void StartTask04(void *argument);int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_I2C1_Init();MX_SPI1_Init();MX_USART1_UART_Init();OLED_Init();osKernelInitialize();defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);myTask02Handle = osThreadNew(StartTask02, NULL, &myTask02_attributes);myTask03Handle = osThreadNew(StartTask03, NULL, &myTask03_attributes);myTask04Handle = osThreadNew(StartTask04, NULL, &myTask04_attributes);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *//* USER CODE END RTOS_THREADS *//* Start scheduler */maxim_max30102_reset();osKernelStart();/* We should never get here as control is now taken by the scheduler *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK){Error_Handler();}
}static void MX_I2C1_Init(void)
{/* USER CODE BEGIN I2C1_Init 0 *//* USER CODE END I2C1_Init 0 *//* USER CODE BEGIN I2C1_Init 1 *//* USER CODE END I2C1_Init 1 */hi2c1.Instance = I2C1;hi2c1.Init.ClockSpeed = 100000;hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;hi2c1.Init.OwnAddress1 = 0;hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;hi2c1.Init.OwnAddress2 = 0;hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;if (HAL_I2C_Init(&hi2c1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN I2C1_Init 2 *//* USER CODE END I2C1_Init 2 */}static void MX_SPI1_Init(void)
{/* USER CODE BEGIN SPI1_Init 0 *//* USER CODE END SPI1_Init 0 *//* USER CODE BEGIN SPI1_Init 1 *//* USER CODE END SPI1_Init 1 *//* SPI1 parameter configuration*/hspi1.Instance = SPI1;hspi1.Init.Mode = SPI_MODE_MASTER;hspi1.Init.Direction = SPI_DIRECTION_2LINES;hspi1.Init.DataSize = SPI_DATASIZE_8BIT;hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;hspi1.Init.NSS = SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;hspi1.Init.TIMode = SPI_TIMODE_DISABLE;hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;hspi1.Init.CRCPolynomial = 10;if (HAL_SPI_Init(&hspi1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN SPI1_Init 2 *//* USER CODE END SPI1_Init 2 */}static void MX_USART1_UART_Init(void)
{/* USER CODE BEGIN USART1_Init 0 *//* USER CODE END USART1_Init 0 *//* USER CODE BEGIN USART1_Init 1 *//* USER CODE END USART1_Init 1 */huart1.Instance = USART1;huart1.Init.BaudRate = 115200;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USART1_Init 2 *//* USER CODE END USART1_Init 2 */}static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);/*Configure GPIO pin : PC13 */GPIO_InitStruct.Pin = GPIO_PIN_13;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);/*Configure GPIO pin : PC13 */GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);/*Configure GPIO pin : PC13 */GPIO_InitStruct.Pin = GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}void StartDefaultTask(void *argument)
{float r;float red;float led;int red_last=0;int led_last=0;int cha=0;int reg_num1=0;int reg_num2=0;int pot_i=0;while (1){HAL_I2C_Mem_Read(&hi2c1,I2C_READ_ADDR,REG_FIFO_DATA,I2C_MEMADD_SIZE_8BIT,(unsigned char *)pData,8,1000);red=(red+(((pData[3]&0x03)<<16)|(pData[4]<<8)|(pData[5])))/2;led=(led+(((pData[0]&0x03)<<16)|(pData[1]<<8)|(pData[2])))/2;if(red>5000){		//判断采集状态if(flag!=1) {OLED_Clear();flag=1;}online=1;cha=(cha+red-red_last)/2;  //求导if(cha<-10){data_save=data_save<<1|0;}else data_save=data_save<<1|1;r=red/led;spo2=-45.060*r*r+30.354*r + 94.845;if(pot_i<128){ 														//波形图显示OLED_DrawPoint(++pot_i,25-cha/6);}      //波形显示过大可把12调大,波形过小可调小12else {OLED_Clear();pot_i=0;}}else {if(flag!=0) {OLED_Clear();flag=0;OLED_Clear();pot_i=0;data_save=0xff;heart=0;online=0;reg_heart=0;reg_num=0;spo2=0;}OLED_ShowChar(1,2,"No FINGER!");}printf("a:%d,%d,%f,%f\n",cha,heart,red,spo2);red_last=red;maxim_max30102_write_reg(0x21,0x01);vTaskDelay(10);}
}
void StartTask02(void *argument)
{while(1){if(char_show==0){OLED_ShowChar(3,0,"H:");OLED_ShowNums(3,2,heart,3);OLED_ShowChar(3,6,"Spo2:");OLED_ShowNums(3,11,spo2,3);vTaskDelay(10);}}
}
void StartTask03(void *argument)
{int last;int now;int c;int num=1;while(1){if((data_save&0xf0)==0x00){now=HAL_GetTick();if(now<last){c=(0xffffffff-last+now);}else c=(now-last);if(c>=300){heart=60000/c;last=now;reg_heart=(reg_heart*reg_num+heart)/(reg_num+1);if(reg_num==30){heart_reg=reg_heart;reg_num=0;reg_heart=0;}elsereg_num++;}}}
}
void StartTask04(void *argument)
{for(;;){osDelay(1);}}
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state *//* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

源码过多,只展示了部分,全部源码下载链接:
https://download.csdn.net/download/qq_19534483/20368390


http://www.ppmy.cn/news/754318.html

相关文章

STM32F429之LTDC驱动图解

本文基于ST官方demo板STM32F429 Discovery硬件平台&#xff0c;以看图说话的形式给大家讲解LTDC的主要参数配置。关于本文提到的代码部分均摘自本人另一片文章《STM32F429之LTDC代码模板》&#xff0c;LCD硬件为240x320&#xff0c;驱动IC为ili9341。本文目的意在让大家通过几张…

STM32F103 驱动32x64双色点阵单元板 (标准HUB08 接口 F3.75)

MCU&#xff1a;STM32F103C8 点阵屏&#xff1a;32*64 F3.75 单元板 红绿双色 显示 接口&#xff1a;标准HUB08 OE &#xff1a;高电平有效 ,138译码 , 1/16 扫 欢迎加QQ群 交流讨论 废话不多说&#xff0c;直接贴代码 整个keil工程下载 https://download.csd…

STM32F4驱动42步进电机(采用驱动器)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 器件实物接线TB6600拨码卡关代码说明main.c 代码如下&#xff08;示例&#xff09;&#xff1a;main.c 代码&#xff08;极简版&#xff09;step_motor.c 代码如下&…

msp430和stm32 dht11驱动程序

最近使用msp430f5529读取dht11的温度和湿度数据&#xff0c;记录下驱动程序&#xff0c;需要可移植。 dht11模块是一块温湿度传感器模块&#xff0c;可以采集温度和湿度信息转化为数据发送出来&#xff0c;模块介绍如下&#xff1a; 概述&#xff1a;DHT11 是广州奥松有限公司…

STM32f401驱动【语音模块】

物理链路层 需要处理VOICE_BUSY与VOICE_DATA线 VOICE_BUSY:PC4 通用输入 VOICE_DATA:PC5 通用推挽输出 BUSE线说明:有声音输出高、无声音时输出低、发协议码之前先判断是否忙碌 while(VOICE_BUSY); VOICE_SEND(cmd); 数据层(软件层) 通过数据引脚(DATA)发送特定的协议码…

unity+pico neo3入门教程1-基础传送

tips&#xff1a;之前入门教程如果没有左手柄&#xff0c;查看一下自己的手柄设置&#xff0c;左右手柄&#xff0c; Helloworld型 1.基础传送&#xff0c;调式地面传送功能&#xff0c;通过手柄默认的“握手键”&#xff0c;瞬移&#xff0c; VR头显&#xff0c;添加Teleport…

ELK部署安装

目录 一、环境准备 1.准备三台服务器&#xff08;带图形化的linuxCentOS7&#xff0c;最小化缺少很多环境&#xff09; 2.修改主机名 3.关闭防火墙 4.elk-node1、elk-node2 用系统自带的java 5.上传软件包到node1和node2 二、部署elasticsearch 1、node1、node2操作 2.no…

dell电脑插耳机还外放

声卡驱动冲突&#xff0c;卸载其中一个