標題:
STM32血氧程序無法編譯 求幫助
[打印本頁]
作者:
chenzuoxiang_
時間:
2021-12-31 11:22
標題:
STM32血氧程序無法編譯 求幫助
STM32血氧程序
#include "stm32f103c8t6.h"
//#include "stm32f1xx_hal_gpio.h"
#include "mbed.h"
#include "algorithm.h"
#include "MAX30102.h"
//#include "lcd_5110.h"
#include "ascii5x8.h" //5x8ASCII字符集
#include "charcode.h" //12x16(14)漢字子集
#include "asciicode.h" //5x8(8)ASCII子集
//#include "sys.h"
/************ 定義LCD相關(guān)的管腳功能 ***********/
#define LCD_RST_SET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_SET);}while(0) //復位腳① PB11
#define LCD_RST_RESET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_RESET);}while(0)
#define LCD_CE_SET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET);}while(0) //片選腳②PB10
#define LCD_CE_RESET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET);}while(0)
#define LCD_DC_SET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);}while(0) //數(shù)據(jù)/命令選擇腳③PB0
#define LCD_DC_RESET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);}while(0)
#define LCD_DIN_SET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);}while(0) //數(shù)據(jù)輸入④PB1
#define LCD_DIN_RESET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);}while(0)
#define LCD_CLK_SET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);}while(0) //時鐘信號腳⑤PB5
#define LCD_CLK_RESET do{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);}while(0)
/************** 結(jié)束管腳定義 *****************/
#define CLOCK 72/8 //時鐘=72M
#define MAX_BRIGHTNESS 255
uint32_t aun_ir_buffer[500]; //紅外LED傳感器數(shù)據(jù)
int32_t n_ir_buffer_length; //數(shù)據(jù)長度
uint32_t aun_red_buffer[500];//紅色LED傳感器數(shù)據(jù)
int32_t n_sp02; //SPO2血氧值
int8_t ch_spo2_valid; //血氧值有效標志
int32_t n_heart_rate; //心率值
int8_t ch_hr_valid; //心率值有效標志
uint8_t uch_dummy;
const uint8_t level[]={0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF};//波形
//const uint8_t level[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};//曲線
uint8_t disp=1; //動態(tài)顯示列
Serial pc(SERIAL_TX, SERIAL_RX);//初始化串行端口, TX-PA2, RX-PA3
PwmOut pwmled(PB_3); //初始化連接到LED的PWM輸出PB3(亮度變化)
DigitalIn INT(PB_7); //PB7連接MAX30102的INT輸出引腳
DigitalOut led(PC_13); //PC13連接板載用戶LED
void LCD_Config(void); //LCD配置引腳
void LCD_init(void); //LCD初始化
void LCD_write_byte(uint8_t dat,uint8_t dc);//LCD寫字節(jié)
void LCD_set_XY(uint8_t X,uint8_t Y);//LCD設(shè)置坐標
void LCD_clear(void); //LCD清屏
void LCD_write_ASCII(uint8_t X,uint8_t Y,uint8_t *stru);//LCD顯示5x7字符串
void LCD_write_ASC_SIN(uint8_t X,uint8_t Y,uint8_t cid);//LCD顯示5x7字符
void LCD_write_ASC7x12(uint8_t X,uint8_t Y,uint8_t cid);//LCD顯示7x12字符
void LCD_write_char(uint8_t x,uint8_t y,uint8_t cid); //LCD顯示12x14字符
void LCD_write_value(uint8_t X,uint8_t Y,uint8_t L,uint8_t D,uint16_t val);//LCD顯示變量
void LCD_write_string(uint8_t x,uint8_t y,uint8_t *stru);//LCD顯示12x14字符串
void display_main(void); //主屏幕顯示
void display_erro(void); //信號錯誤
void display_wait(void); //等待信號
void display_ir(uint16_t ir);//動態(tài)顯示曲線
/*------------------------------------------------------------
us延時函數(shù)
------------------------------------------------------------*/
void delay_us(uint16_t us)
{
uint8_t n;
while(us--)for(n=0;n<CLOCK;n++);
}
/*------------------------------------------------------------
ms延時函數(shù)
------------------------------------------------------------*/
void delay_ms(uint16_t ms)
{
while(ms--)delay_us(1000);
}
// 當您按重置時,設(shè)置程序運行一次。
int main() {
uint32_t un_min, un_max, un_prev_data;//用于計算反映心跳的車載LED亮度的變量
int i;
int32_t n_brightness;
float f_temp;
uint8_t flag = 0;
maxim_max30102_reset(); //重置MAX30102
//初始化串行口波特率
pc.baud(115200);
pc.format(8,SerialBase::None,1);
wait(1);
//初始化LCD5110
LCD_init();
display_main();
//讀取和清除狀態(tài)寄存器
maxim_max30102_read_reg(0,&uch_dummy);
maxim_max30102_init(); //初始化MAX30102
n_brightness=0;
un_min=0x3FFFF;
un_max=0;
n_ir_buffer_length=500; //緩沖區(qū)長度100存儲以100sps運行的5秒樣本
//讀取前500個樣本,確定信號范圍
for(i=0;i<n_ir_buffer_length;i++)
{
while(INT.read()==1);//等待直到中斷pin生效
maxim_max30102_read_fifo((aun_red_buffer+i),(aun_ir_buffer+i));//從MAX30102的FIFO讀數(shù)據(jù)
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i];//更新信號最小值
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i];//更新信號最大值
pc.printf("red=");
pc.printf("%i", aun_red_buffer[i]);
pc.printf(", ir=");
pc.printf("%i\n\r", aun_ir_buffer[i]);
}
un_prev_data=aun_red_buffer[i];
//計算前500個樣本(前5秒樣本)后的心率和血氧數(shù)值。
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
//從MAX31022連續(xù)取樣。每1秒計算一次心率和血氧飽和度。
while(1)
{
i=0;
un_min=0x3FFFF;
un_max=0;
//將前100組樣本轉(zhuǎn)儲到內(nèi)存中,并將最后400組樣本移到頂部
for(i=100;i<500;i++)
{
aun_red_buffer[i-100]=aun_red_buffer[i];
aun_ir_buffer[i-100]=aun_ir_buffer[i];
//更新信號最小值和最大值
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i];
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i];
}
//在計算心率前取100組樣本。
for(i=400;i<500;i++)
{
un_prev_data=aun_red_buffer[i-1];
while(INT.read()==1); //等待傳感器信號
maxim_max30102_read_fifo((aun_red_buffer+i), (aun_ir_buffer+i));
if(aun_red_buffer[i]>un_prev_data) //只是根據(jù)相鄰兩個AD數(shù)據(jù)的偏差來確定LED的亮度
{
f_temp=aun_red_buffer[i]-un_prev_data;
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness-=(int)f_temp;
if(n_brightness<0)
n_brightness=0;
}
else
{
f_temp=un_prev_data-aun_red_buffer[i];
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
n_brightness+=(int)f_temp;
if(n_brightness>MAX_BRIGHTNESS)
n_brightness=MAX_BRIGHTNESS;
}
if(flag==0) //兩個循環(huán)顯示一次
{
if(n_heart_rate>180)//脈搏過速
display_erro();
else
{
if(n_heart_rate<20)
display_wait();
else
display_ir((float)n_brightness/5);
}
flag++;
}
else
flag = 0;
pwmled.write(1-(float)n_brightness/256);//PWM控制LED亮度
if(n_brightness<120)
led=1;
else
led=0;
}
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
pc.printf("HR=%i, ", n_heart_rate);
pc.printf("SpO2=%i",n_sp02);
LCD_write_value(24,5,3,0,n_sp02);
LCD_write_value(67,5,3,0,n_heart_rate);
}
}
/*********************************************
* 函數(shù)名稱:LCD_Config
* 函數(shù)功能:配置LCD引腳
* 入口參數(shù):無
* 出口參數(shù):無
*********************************************/
void LCD_Config(void)
{
GPIO_InitTypeDef GPIO_InitTypeDef; //定義結(jié)構(gòu)體
GPIO_InitTypeDef.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 | GPIO_PIN_10 | GPIO_PIN_11; //配置LCD引腳
GPIO_InitTypeDef.Mode = GPIO_MODE_OUTPUT_PP; //推挽輸出
GPIO_InitTypeDef.Speed = GPIO_SPEED_FREQ_HIGH; //速度
HAL_GPIO_Init(GPIOB, &GPIO_InitTypeDef); //初始化GPIO
}
/*********************************************
* 函數(shù)名稱:LCD_init
* 函數(shù)功能:5110初始化
* 入口參數(shù):無
* 出口參數(shù):無
* 備注:接通電源后需要一個RES低電平脈沖復位,當VDD變?yōu)楦唠娖街?br />
* 最多100ms,RST輸入低電平(<0.3VDD)
*********************************************/
void LCD_init(void)
{
LCD_Config(); //配置LCD連線
LCD_RST_RESET; //LCD_RST = 0 復位LCD5110
delay_us(2);
LCD_RST_SET; //LCD_RST = 1;
LCD_CE_RESET; //LCD_CE = 0; 關(guān)閉LCD
delay_us(2);
LCD_CE_SET; //LCD_CE = 1; 關(guān)閉LCD
LCD_write_byte(0x21,0); //使用擴展LCD令設(shè)置LCD模式
LCD_write_byte(0xc8,0); //設(shè)置液晶偏置電壓
LCD_write_byte(0x06,0); //溫度校正(溫度系數(shù)2)
LCD_write_byte(0x13,0); //1:48
LCD_write_byte(0x20,0); //使用基本命令,V=0,水平尋址
LCD_write_byte(0x0c,0); //設(shè)定顯示模式,正常顯示
LCD_clear(); //清屏
LCD_CE_SET; //LCD_CE = 1; //關(guān)閉LCD
}
/*********************************************
* 函數(shù)名稱:LCD_write_byte
* 函數(shù)功能:模擬SPI接口時序?qū)憯?shù)據(jù)/命令LCD
* 入口參數(shù):data :寫入的數(shù)據(jù);
* dc :寫數(shù)據(jù)1/命令0選擇
* 出口參數(shù):無
* 備注:管腳D/C(LCD_DC)用于選擇寫的是命令(D/C=0)還是數(shù)據(jù)(D/C=1)
*********************************************/
void LCD_write_byte(uint8_t dat,uint8_t dc)
{
uint8_t i;
LCD_CLK_RESET; //先拉低時鐘CLK
LCD_CE_RESET; //LCD_CE = 0; 選擇5110
if (dc == 1)
{
LCD_DC_SET; //LCD_DC = dc; dc=0數(shù)據(jù),dc=1命令
}
else {
LCD_DC_RESET;
}
for (i=0; i<8; i++) //發(fā)送8位
{
if (dat & 0x80)
{
LCD_DIN_SET; //LCD_DIN = 1;
}
else {
LCD_DIN_RESET; //LCD_DIN = 0;
}
LCD_CLK_SET; //LCD_CLK = 1;
delay_us(1);
dat = dat << 1; //移位,準備發(fā)送下一位
LCD_CLK_RESET; //LCD_CLK = 0; //發(fā)送同步時鐘
}
LCD_CE_SET; //LCD_CE = 1; //關(guān)閉5110
}
/*********************************************
* 函數(shù)名稱:LCD_set_XY
* 函數(shù)功能:設(shè)置LCD坐標函數(shù)
* 入口參數(shù):X :0-83;
* Y :0-5
* 出口參數(shù):無
* 備注:
*********************************************/
void LCD_set_XY(uint8_t X,uint8_t Y)
{
LCD_write_byte(0x40 | Y,0); //column?
LCD_write_byte(0x80 | X,0); //row?
}
/*********************************************
* 函數(shù)名稱:LCD_clear
* 函數(shù)功能:5110清屏(用空白寫滿屏幕)
* 入口參數(shù):無
* 出口參數(shù):無
* 備注:
*********************************************/
void LCD_clear(void)
{
uint8_t i,j;
LCD_set_XY(0,0); //定位左上角
for (i=0; i<6; i++)
{
for (j=0; j<84; j++)
{
LCD_write_byte(0x00,1);
}
}
}
/*********************************************
* 函數(shù)名稱:LCD_write_ASCII
* 函數(shù)功能:顯示字符串5*7(8)
* 入口參數(shù):x,y,cid :顯示ASCII字符
* 出口參數(shù):無 編號(行號)32~127
* 備注:ASCII碼表的數(shù)組ASC_5[95][8]來尋址
*********************************************/
void LCD_write_ASCII(uint8_t X,uint8_t Y,uint8_t *stru)
{
uint8_t i;
LCD_set_XY(X,Y); //定位(左上角)
while (1)
{
for ( i=0; i<5; i++) //輸出一個5*7字符
{
LCD_write_byte(ASC_5[*stru-32][i],1);
}
stru++;
if(*stru == '\0') break; //在每個字符串的最后,會有一個'\0'
LCD_write_byte(0x00,1); //插入空列
}
}
/*********************************************
* 函數(shù)名稱:LCD_write_ASC_SIN
* 函數(shù)功能:顯示單個字符5*7(8)
* 入口參數(shù):x,y,cid :顯示ASCII字符
* 出口參數(shù):無 編號(行號)32~127
* 備注:ASCII碼表的數(shù)組ASC_5[95][8]來尋址
*********************************************/
void LCD_write_ASC_SIN(uint8_t X,uint8_t Y,uint8_t cid)
{
uint8_t i;
LCD_set_XY(X,Y); //定位(左上角)
for ( i=0; i<5; i++) //輸出一個5*7字符
{
LCD_write_byte(ASC_5[cid-32][i],1);
}
}
/*********************************************
* 函數(shù)名稱:LCD_write_ASC7x12
* 函數(shù)功能:顯示自定義字符7*12(16)
* 入口參數(shù):x,y,cid :顯示的字符 0 1 2 3 4 5 6 7 8 9 = m s
* 出口參數(shù):無 編號(行號)0,1,2,3,4,5,6,7,8,9,10,11,12
* 備注:ASCII碼表的數(shù)組ASC_7[13][14]來尋址
*********************************************/
void LCD_write_ASC7x12(uint8_t X,uint8_t Y,uint8_t cid)
{
uint8_t i;
LCD_set_XY(X,Y); //定位{左上角)
for (i=0; i<7; i++) //顯示字符的上半部分(7列)
{
LCD_write_byte(ASC_7[cid][i],1);
}
LCD_set_XY(X,Y+1); //顯示字符的下半部分
for (i=7; i<14; i++)
{
LCD_write_byte(ASC_7[cid][i],1);
}
}
/*********************************************
* 函數(shù)名稱:LCD_write_CHAR
* 函數(shù)功能:顯示自定義字符12*14(16)
* 入口參數(shù):x,y,cid :顯示的字符 電子點焊機接間隔毫秒時
* 出口參數(shù):無 編號(行號)0,1,2,3,4,5,6,7,8,9,10
* 備注:CHAR字庫的數(shù)組CHAR_12[11][24]來尋址
***********************************************/
void LCD_write_char(uint8_t x,uint8_t y,uint8_t cid)
{
uint8_t i;
LCD_set_XY(x,y); //定位(左上角)
for (i=0; i<12; i++) //寫字符的上半部分(12列)
{
LCD_write_byte(CHAR_12[cid][i],1);
}
LCD_set_XY(x,y+1); //寫字符的下半部分
for (i=12; i<24; i++)
{
LCD_write_byte(CHAR_12[cid][i],1);
}
}
/*********************************************
* 函數(shù)名稱:LCD_write_value
* 函數(shù)功能:顯示變量字符5*7(8)或7*12(16)
* 入口參數(shù):x,y,L,val :座標、長度、小數(shù)、變量
* 出口參數(shù):無 編號(行號)
* 備注:ASCII碼表的數(shù)組ASC_5[95][8]來尋址
*********************************************/
void LCD_write_value(uint8_t X,uint8_t Y,uint8_t L,uint8_t D,uint16_t val)
{
uint8_t i,j,f = 0; //列循環(huán)、字循環(huán)、顯示標志
uint16_t n,t,cid; //當前倍數(shù)、余數(shù)、當前數(shù)字
t = val;
n = 1;
for (j = 0; j < L; j++)
n = n * 10;
LCD_set_XY(X,Y); //定位(左上角)
for (j = L; j > 0; j--) //字符循環(huán)開始
{
n = j < 2 ? 1: n / 10; //計算當前的倍數(shù)
cid = t / n; //當前位數(shù)字
t = t - (cid * n);
if (cid > 0)
f = 16;
for ( i=0; i<5; i++) //寫一個5*7字符
{
LCD_write_byte(ASC_5[cid + f][i],1);
}
if ( D > 0 & D == (j - 1))
{
for ( i=0; i<5; i++) //寫小數(shù)點
{
LCD_write_byte(ASC_5[14][i],1);
}
}
else
if(j>1) LCD_write_byte(0x00,1);//插入空列
}
}
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
MAX30102_uvision5_stm32f103c8.7z
2022-1-6 04:39 上傳
點擊文件名下載附件
678.56 KB, 下載次數(shù): 2
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1