标题:
脉搏测试仪(电子设计竞赛试题)
[打印本页]
作者:
fuliang
时间:
2017-7-17 12:14
标题:
脉搏测试仪(电子设计竞赛试题)
脉搏测试仪(电子设计竞赛试题)
0.png
(61.01 KB, 下载次数: 35)
下载附件
2017-7-18 00:37 上传
单片机源程序如下:
#include <MSP430x14x.h> //F149的头文件
#include "LCD12864.h"
#include "key.h"
#define uchar unsigned char
#define uint unsigned int
void put(char x,char y,int c); //电压显示
void put_time(char x,char y,char z);//时间显示
void put_HZ(char A,char B,char shu);
void put_one(char A,char B,char shu);
void draw(double a);
void pict(uint n);
void count();
void clear();
void huaxian();
void key_action();
uint minute=0,second=0,second_1=0;
uint n=0,number=0,temp0=0,temp2=0;//定义周期个数,边沿
double u,fanhui=0;
uint data[128],save[128],z[128];
uint y,start=0,time_flag=0;
uint basic_flag=0; //基本模式标志
uchar key_val,jilu=0;
uint cont_flag=0;
uint comp_max,comp_min;//最大值和最小值上限下限
uint key1_val=0,key2_val=0;//按键键值 (代表按键按几次)
uint ceshi[128]={
23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12
};
//系统时钟初始化
void sys_Init()
{
volatile unsigned int i;
BCSCTL1&=~XT2OFF; //打开XT2振荡器
do
{
IFG1 &= ~OFIFG; // 清除振荡器失效标志
for (i = 0xFF; i > 0; i--); // 延时,等待XT2起振
} while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振
BCSCTL2 =SELM_2+SELS; //选择MCLK=SMCLK为XT2
}
//定时器A初始化
void timer0()
{
TACTL = TASSEL_2 + MC_2; // 设置定时器A使用MCLK,不分频,连续计数模式
CCR0 = 40000; //CCR0初值
CCTL0 = CCIE; // 允许CCR0 中断
}
//ADC初始化
void ADC_Init()
{
P6SEL |= 0x02; // P6.1为ADC输入
ADC12CTL0 = REFON+ REF2_5V; // REFON为打开内部电压发生器的意思,REF2_5V为设置参考电压选择为2.5v的意思
ADC12CTL0 |= SHT0_2 + ADC12ON; // 设置采样保持时间为4个ADC12CLK(SHT_2),开启ADC12模块(ADC12ON)
ADC12CTL1 = SHP;
ADC12MCTL0 = INCH_1+SREF_1; // Vr+=Vref+=2.5V
ADC12IE = 0x01; // 设置ADC12的中断使能,不用对应A1通道
ADC12CTL0 |= ENC; // // 使能AD转换
}
uchar flag=0;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT,关闭看门狗定时器
sys_Init();
timer0();
ADC_Init();
P2DIR |=0XFF;
LCD_init(); //液晶模块的初始化
Write_Cmd(0x01);
GUI_Fill_GDRAM(0x00); //清屏函数
LCD_write_string(0,0,"系统启动。。");
LCD_write_string(0,1,"通信工程系fu!!");
LCD_write_string(0,2,"通工系fu!!");
LCD_write_string(0,3,"系统启动fu。。");
_EINT(); //开启总中断(fuliang)
//_BIS_SR(LPM0_bits + GIE); // 进入 LPM0 低功耗模式,允许中断,CPU停止工作,单片机等待
while(1)
{
if(start==1) //每20ms判断成立一次,下面的句子才能运行
{
switch(key2_val) //每20ms运行一次,switch这些句子能否运行要取决于“shart=1”
{
case 1: //本按键按一次的情况
if(flag==1) //设置flag变量目的只让这里面的程序执行一次,
{
LCD_write_string(0,0,"回放模式"); //虽然程序只执行一次,但下面并没有清屏,所以只要按
//键不再一次按下,字符不会消失
for(int i=0;i<128;i++)
{
z[i]=save[i];
}
count();//显示次数
for(int i=0;i<128;i+=16)
{
pict(i);
}
flag=0;
}
break;
case 2: //本按键再次按下情况
LCD_write_string(0,0,"光电脉搏动态显示");
for(int i=0;i<128;i++)
{
z[i]=save[i];
}
for(int i=0;i<128;i+=16)
{
pict(i);
}
break;
case 3: //本按键第三次按下情况
LCD_write_string(0,0,"监护模式");
time_flag=1;//倒计时标志
put_time(7,1,60-second_1);
count();//显示次数
put_HZ(0,3,cont_flag);
default: break;
}
start=0; //最后要记得清零
}
}
}
// Timer A0 interrupt service routine
//CCR0比较捕捉中断服务函数
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A0 (void)
{
static uchar temp;
CCR0 += 40000; //8M/40000=200Hz==>5ms//计时
if(++temp==200) //5ms*200=1s
{
P2OUT ^=BIT0;
temp=0;
if(time_flag==1) //监护模式倒计时标志
{
second_1++;
if(second_1>59)
{
time_flag=0;
second_1=0;
cont_flag=0;
}
}
else second_1=0;
second++;
if(basic_flag==1&&second_1>58)//测试完成判断
{
Write_Cmd(0x01);
LCD_write_string(0,0,"完成!");
basic_flag=0;
time_flag=0;
}
if(basic_flag==1&&(second<10))
{
Write_Cmd(0x01);
LCD_write_string(0,0,"请重新放入!");
}
if(second==1&&minute==0)
{
Write_Cmd(0x01);
LCD_write_string(0,0,"系统已工作ABC!");
LCD_write_string(0,1,"光纤通信一班符亮");
}
if(second>59)
{
second=0;
minute++;
if(minute>19)
{
minute=0;
}
}
}
if(temp%4==0) //每5ms*4==20ms运行一次按键程序,对应下面的"start"标志
{
key_action();
}
if(temp%10==0)
{
cont_flag++;
ADC12CTL0 |= ADC12SC; //启动ADC12转换,让ADC12每隔50ms转换一次,
}
}
//AD中断
#pragma vector=ADC_VECTOR
__interrupt void ADC12_ISR (void)
{
static double d=0;
static int x=0;
d=ADC12MEM0;//累加ad转换的值,多次转换可以保证转换的精度
u=d*25*100/4096;
y=(int)((u/2500.0)*32);
save[x]=31-y;
x++;
if(x>127)
{
x=0;
}
}
/*********************************************************
函数名称:display()
函数功能:在1602指定位置显示两位数,被显示的数值应在0~99之间
***********************************************************/
void put(char x,char y,int c)
{
uchar ch[]=":0.000V";
ch[1]=c/1000%10+'0';
ch[3]= c/100%10+'0';
ch[4]= c/10%10+'0';
ch[5]= c%10+'0';
LCD_write_string(x,y,ch); //显示千位,v的单位为mV
}
void put_time(char x,char y,char z)
{
uchar time[]=" ";
time[0]=z/10%10+'0';
time[1]=z%10+'0';
LCD_write_string(x,y,time);
}
void put_HZ(char A,char B,char shu)
{
uchar hz[]="次数: ";
hz[5]=shu/100%10+'0';
hz[6]=shu/10%10+'0';
hz[7]=shu%10+'0';
LCD_write_string(A,B,hz);
}
void put_one(char A,char B,char shu)
{
uchar hz[]="个数: ";
hz[5]=shu/100%10+'0';
hz[6]=shu/10%10+'0';
hz[7]=shu%10+'0';
LCD_write_string(A,B,hz);
}
/*********************/
//画线//
/********************/
void pict(uint n)
{
uint i,j;
uint d[32],k;
//Write_Cmd(0x34); //设置为8 位MPU 接口,扩充指令集,绘图模式关
LCD_en_command(0x36);
for(i=0;i<32;i++)
d[i]=0;
k=0x8000;
for(i=n;i<n+16;i++)
{
if(z[i]<=z[i+1])
{
for(j=z[i];j<=z[i+1];j++)
{
d[j]|=k;
}
}
else
{
for(j=z[i+1];j<=z[i];j++)
{
d[j]|=k;
}
}
k>>=1;
}
for(j=0;j<32;j++)
{
LCD_en_command(0x80+j); //垂直地址Y
LCD_en_command(0x88+(n/16)); //水平地址X
LCD_en_dat(d[j]>>8);
LCD_en_dat(d[j]&0x00ff);
}
// Write_Cmd(0x36); //打开绘图模式
LCD_en_command(0x30); //恢复基本指令集,关闭绘图模式
}
void key_action() //按键函数,每20ms运行一次这个函数
{
start=1; //按键按下的情况为“1”,每20ms运行一次(定时器里面是这么设置的)
key_val=inkey();
if(key_val!=0xff) //如果按键按下的情况,0xff表没有按键按下
Write_Cmd(0x01); //清除显示
if(key_val==1) //第一个按键按下
{
key2_val++;
if(key2_val==1)
{
flag=1;
}
if(key2_val==4)
key2_val=0;
}
if(key_val==2) //当第二个按键按下情况
{
// exit_flag++;
key2_val=0;
Write_Cmd(0x01);
LCD_write_string(0,1,"基本模式");
LCD_write_string(0,2,"请等待!");
basic_flag=1; //基本模式标志
time_flag=1;
}
}
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
脉搏.zip
(492.68 KB, 下载次数: 17)
2017-7-17 12:13 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1