脉搏测试程序.docx
《脉搏测试程序.docx》由会员分享,可在线阅读,更多相关《脉搏测试程序.docx(16页珍藏版)》请在冰豆网上搜索。
![脉搏测试程序.docx](https://file1.bdocx.com/fileroot1/2023-1/27/e5066338-21dd-47f0-b0d7-d24bc3f76646/e5066338-21dd-47f0-b0d7-d24bc3f766461.gif)
脉搏测试程序
#include"msp430g2553.h"
#include"lcd12864.h"
#defineCPU_F((double)1000000)
#definedelay_us(x)__delay_cycles((long)(CPU_F*(double)x/1000000.0))//调用delay_us(x);延时Xus
#definedelay_ms(x)__delay_cycles((long)(CPU_F*(double)x/1000.0))//调用delay_ms(2000);延时2000MS
externunsignedcharKey_Flag;
constunsignedcharzuobiao[];
unsignedintms_count;
unsignedchardat,pulse_count=0,Pulse_Input;
unsignedintADC_max=0,ADC_result[106]={0};
unsignedchari,Cap_counter=0;
unsignedintCap_first,Cap_last,cap_time;
unsignedcharcap_flag,disp[7]={'','','','','','',''};//存放AD转换的电压值的字符数组disp[6],定义格式为123.45V
unsignedcharshuzu[3]={'','',''};//存放由整形数据转换的字符串
unsignedcharPulse_Max[3]={'0','0','0'},Pulse_Min[3]={'0','0','0'};
unsignedchargeshu,y_location,x_location;
floatvolt,freq;
unsignedcharnum_flag=0,Pulse_mHigh,Pulse_mLow;//键盘输入数字计数
/****************************************************************************
系统时钟初始化
***************************************************************************/
voidOSCILLATOR_Init(void)
{
if(CALBC1_1MHZ==0xFF||CALDCO_1MHZ==0xFF)
{while
(1);}//Ifcalibrationconstantserased,trapCPU!
!
BCSCTL1=CALBC1_1MHZ;//Setrange
DCOCTL=CALDCO_1MHZ;//SetDCOCLK=1MHz
//BCSCTL3|=LFXT1S_2;//SetLFXT1
IFG1&=~OFIFG;//ClearOSCFaultflag
BCSCTL2|=SELM_1+DIVM_0;//SetMCLK=DCOCLK=1MHz
}
voidADC_Init(void)
{
ADC10CTL0|=ADC10SHT_2+ADC10ON;//ADC10SHTx=10采样保持时间设为16个ADC10CLK周期,ADC10开启
ADC10CTL0|=SREF_1+REFON+REF2_5V;//选择内部参考源2.5V,打开基准源
ADC10CTL1|=CONSEQ_0+INCH_1+SHS_2;//INCHx=0001选择输入通道A1,
//CONSEQ_0,工作模式为单通道单次采样
ADC10AE0|=0x02;//外部输入通道A1(P1.1)使能
//__bis_SR_register(GIE);
}
voidDraw_columnPointer(unsignedcharx,unsignedchary)
{
lcd_cs0;
dat|=0x01<<(y&0x07);//更新要画点所在的页的字节数据
lcd_address((y/8+1),x);
transfer_data_lcd(dat);
lcd_cs1;
}
voidDraw_rowPointer(unsignedcharx,unsignedchary)
{
unsignedchardat=0;//画横向点的时候dat要清零
lcd_cs0;
dat|=0x01<<(y&0x07);//更新要画点所在的页的字节数据
//调用格式lcd_address(ucharpage,ucharcolumn)
//page:
1~8column:
1~128
lcd_address((y/8+1),x);
transfer_data_lcd(dat);
lcd_cs1;
}
voidnumber_to_char(floatvoltage)//分解成3位整数、2位小数的电压值显示
{
unsignedcharj;
//disp[0]=(unsignedint)(voltage)/100;//从整数中分离出百位
//voltage-=disp[0]*100;
disp[0]=(unsignedint)(voltage)/10;//分离出十位
voltage-=disp[0]*10;
disp[1]=(unsignedint)voltage;//分离出个位
voltage-=disp[1];
disp[3]=(unsignedint)(voltage*10);//分离十分位
voltage-=disp[3]*0.1;
disp[4]=(unsignedint)(voltage*100);//分离百分位
disp[0]|=0x30;
disp[1]|=0x30;
disp[2]='.';
disp[3]|=0x30;
disp[4]|=0x30;//将分离的各位整数转换成字符型数据
disp[5]='V';
disp[6]='';
for(j=0;j<2;j++)
{
if(disp[j]=='0')//如果数组中存放在有效整数之前有无效的0,则将'0'用''空格替换
disp[j]='';
else
break;
}
}
voidinter_to_char(floatnum)
{
unsignedchari;
shuzu[0]=(unsignedint)(num)/100;//从整数中分离出百位
num-=shuzu[0]*100;
shuzu[1]=(unsignedint)(num)/10;//分离出十位
num-=shuzu[1]*10;
shuzu[2]=(unsignedint)num;//分离出个位
shuzu[0]|=0x30;
shuzu[1]|=0x30;
shuzu[2]|=0x30;
for(i=0;i<2;i++)
{
if(shuzu[i]==0x30)
shuzu[i]=0x20;
else
break;
}
}
voidchar_to_number(unsignedchar*dp)
{
unsignedchark;
for(k=0;k<3;k++)
dp[k]=dp[k]-0x30;
if(num_flag==1)
Pulse_Input=dp[0];
elseif(num_flag==2)
Pulse_Input=dp[0]*10+dp[1];
else
Pulse_Input=dp[0]*100+dp[1]*10+dp[2];
}
unsignedchari,j,y;
/**************************************************************************/
voidmain(void)
{
unsignedcharfinish_flag=0;
WDTCTL=WDTPW+WDTHOLD;//Stopwatchdogtimer
OSCILLATOR_Init();//时钟初始化
LCD_IO_Init();//IO初始程序
Init_lcd();
clear_screen();//clearalldots
P1DIR|=BIT0+BIT2;//P1.0(测试)、P1.2输出(报警指示)
P1OUT|=0x01;
/**********************A/D转换设置************************************************/
ADC10CTL1|=INCH_1+SHS_1;//INCHx=0001选择输入通道A1(P1.1管脚);采样保持源TA1
ADC10AE0=0x02;//外部输入通道A1使能
/*********************定时比较触发AD转换********************************************/
TACCTL0=CCIE;
TACCR0=40-1;//采样周期40us
TACCTL1=OUTMOD_3;//比较模式3,TACCR1toggle
TACCR1=2;
TACTL=TASSEL_2+MC_1;//SMCLK,Upmode
/*************************捕获功能设置***********************************************
定时器Timer1的TA1CCR2捕获信号选择为TA1.2,由P2.4输入,CCI2A输入
**********************************************************************************/
P2DIR&=~BIT4;
P2SEL|=BIT4;//TA1.2/P2.4Timer1_ACCI2A
TA1CCTL2|=CM_1+SCS+CAP+CCIS_0+CCIE;//上升沿、同步捕获,CCI2A
TA1CTL|=TASSEL_1+ID_3+MC_2+TACLR;//ACLK=32768HZ,8分频为4096;连续计数模式
/**********************************************************************************/
display_string(1,1,"人体脉搏测试系统");
display_string(3,8,"A-输入脉搏上限");
display_string(5,8,"B-输入脉搏下限");
display_string(7,8,"C-脉搏图形显示");
delay_ms(3000);
while
(1)
{
//i=0;
Key_Scan();//做键扫描
if(Key_Flag)//如果Key_Flag标志不为0,则有键按下
{
Key_Flag=0;
delay_ms(15);
Key_Value();//做按键键值的判断
if(Key_Flag=='A')//等待输入脉搏上限值
{
clear_screen();
display_string(1,1,"最大脉搏次数:
");
display_string_57(8,71,"F-->EXIT");
delay_ms(1000);
while
(1)
{
Key_Scan();//做键扫描
if(Key_Flag)//如果Key_Flag标志不为0,则有键按下
{
Key_Flag=0;
delay_ms(15);
Key_Value();
switch(Key_Flag)
{
case'1':
Pulse_Max[num_flag]='1';break;
case'2':
Pulse_Max[num_flag]='2';break;
case'3':
Pulse_Max[num_flag]='3';break;
case'4':
Pulse_Max[num_flag]='4';break;
case'5':
Pulse_Max[num_flag]='5';break;
case'6':
Pulse_Max[num_flag]='6';break;
case'7':
Pulse_Max[num_flag]='7';break;
case'8':
Pulse_Max[num_flag]='8';break;
case'9':
Pulse_Max[num_flag]='9';break;
case'0':
Pulse_Max[num_flag]='0';break;
case'F':
finish_flag=1;break;
default:
break;
}
if(num_flag==3)num_flag=0;
if(!
finish_flag)//数据输入并显示
{display_5x7(5,20+num_flag*7,Pulse_Max[num_flag]);num_flag++;}
else
{
finish_flag=0;
char_to_number(Pulse_Max);//输入字符转换成数字
Pulse_mHigh=Pulse_Input;
num_flag=0;//输入数据结束,退出数据输入和显示循环
clear_screen();
display_string(3,8,"A-输入脉搏上限");
display_string(5,8,"B-输入脉搏下限");
display_string(7,8,"C-脉搏图形显示");
break;
}
}
}
}
if(Key_Flag=='B')//等待输入脉搏上限值
{
clear_screen();
display_string(1,1,"最小脉搏次数:
");
display_string_57(8,71,"F-->EXIT");
delay_ms(1000);
while
(1)
{
Key_Scan();//做键扫描
if(Key_Flag)//如果Key_Flag标志不为0,则有键按下
{
Key_Flag=0;
delay_ms(15);
Key_Value();
switch(Key_Flag)
{
case'1':
Pulse_Min[num_flag]='1';break;
case'2':
Pulse_Min[num_flag]='2';break;
case'3':
Pulse_Min[num_flag]='3';break;
case'4':
Pulse_Min[num_flag]='4';break;
case'5':
Pulse_Min[num_flag]='5';break;
case'6':
Pulse_Min[num_flag]='6';break;
case'7':
Pulse_Min[num_flag]='7';break;
case'8':
Pulse_Min[num_flag]='8';break;
case'9':
Pulse_Min[num_flag]='9';break;
case'0':
Pulse_Min[num_flag]='0';break;
case'F':
finish_flag=1;break;
default:
break;
}
if(num_flag==3)num_flag=0;
if(!
finish_flag)//数据输入并显示
{display_5x7(5,20+num_flag*7,Pulse_Min[num_flag]);num_flag++;}
else
{
finish_flag=0;
char_to_number(Pulse_Min);//输入字符转换成数字
Pulse_mLow=Pulse_Input;
num_flag=0;//输入数据结束,退出数据输入和显示循环
clear_screen();
display_string(3,8,"A-输入脉搏上限");
display_string(5,8,"B-输入脉搏下限");
display_string(7,8,"C-脉搏图形显示");
break;
}
}
}
}
if(Key_Flag=='C')
{
clear_screen();
display_12864(zuobiao);
display_string_57(8,7,"Vm");
display_string_57(8,38,"");
display_string_57(8,76,"Pu");
display_string_57(8,110,"/s");
_EINT();//开总中断
}
}
}
}
#pragmavector=TIMER0_A0_VECTOR//定时器Timer0中断
__interruptvoidTimer_A0_ISR(void)
{
ADC10CTL0|=ADC10SHT_2+ADC10ON+ADC10IE;//ADC10SHTx=10采样保持时间设为16个ADC10CLK周期,ADC10开启
ADC10CTL0|=SREF_1+REFON+REF2_5V;//选择内部参考源2.5V,打开基准源
//ADC10CTL0|=SREF_1+REFON;//选择内部参考源1.5V
ADC10CTL0|=ENC;//ADC10enableset
}
//将脉搏的电信号进行AD转换,并画出脉搏波形
#pragmavector=ADC10_VECTOR
__interruptvoidADC10_ISR(void)
{
ADC10CTL0&=~ENC;//ADC10disabled
ADC10CTL0=0;//ADC10,Vrefdisabledcompletely
if(pulse_count<106)
{
ADC_result[pulse_count]=ADC10MEM;//每次采样结果送入数组
geshu=ADC_result[pulse_count]*35/1023;
y_location=64-(18+geshu);
x_location=15+pulse_count;
Draw_rowPointer(x_location,y_location);//扫描点送显
if(ADC_maxADC_max=ADC_result[pulse_count];
}
else
{
pulse_count=0;
ADC_max=0;
i=0;
clear_area();//显示区域刷新;
}
pulse_count++;
volt=(ADC_max*2.5)/1023;
number_to_char(volt);
display_string_57(8,21,disp);//显示每一帧数据中的峰值
}
#pragmavector=TIMER1_A1_VECTOR//Timer1_A通道2捕获脉搏周期时间
__interruptvoidTimer1_A2_ISR(void)
{
switch(__even_in_range(TA1IV,0x0A))
{
caseTA1IV_NONE:
break;//Vector0:
Nointerrupt
caseTA1IV_TACCR1:
break;//Vector2:
TACCR1CCIFG
caseTA1IV_TACCR2:
//Vector4:
TACCR2CCIFG
if(TA1CCTL2&CCI)//CaptureInputPinStatus
{
P1OUT^=0x01;
//RisingEdgewascaptured
if(Cap_counter==0)
{
Cap_first=TA1CCR2;//第一次捕获上升沿的计数值
Cap_counter++;
cap_flag=0;
}
else
{
Cap_last=TA1CCR2;//第二次捕获上升沿的计数值
Cap_counter=0;
cap_flag=1;
_DINT();//关中断,禁止响应任何中断,避免破坏捕获数据
}
if(cap_flag==1)//完成2次捕获,即可计算周期
{
cap_time=Cap_last-Cap_first;
if(cap_time)
{
freq=((float)4096/cap_time);
freq*=60;//计算频率,x次/分钟
if((unsignedint)(freq)>Pulse_mHigh||(unsignedint)(freq)P1OUT|=BIT2;
else
P1OUT&=~BIT2;
inter_to_char(freq);
display_string_57(8,91,shuzu);//显示每分钟的脉搏次数
}
//else
//freq=0;
_EINT();//开总中断
}
}
br