找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2563|回复: 0
打印 上一主题 下一主题
收起左侧

脉搏测试仪(电子设计竞赛试题)

[复制链接]
跳转到指定楼层
楼主
脉搏测试仪(电子设计竞赛试题)


单片机源程序如下:
  1. #include <MSP430x14x.h>      //F149的头文件
  2. #include "LCD12864.h"
  3. #include "key.h"
  4. #define uchar unsigned char     
  5. #define uint  unsigned int

  6. void put(char x,char y,int c);  //电压显示
  7. void put_time(char x,char y,char z);//时间显示
  8. void put_HZ(char A,char B,char shu);
  9. void put_one(char A,char B,char shu);
  10. void draw(double a);
  11. void pict(uint n);
  12. void count();
  13. void clear();
  14. void huaxian();
  15. void key_action();

  16. uint minute=0,second=0,second_1=0;
  17. uint n=0,number=0,temp0=0,temp2=0;//定义周期个数,边沿
  18. double u,fanhui=0;
  19. uint data[128],save[128],z[128];
  20. uint y,start=0,time_flag=0;
  21. uint basic_flag=0;      //基本模式标志
  22. uchar key_val,jilu=0;
  23. uint cont_flag=0;
  24. uint comp_max,comp_min;//最大值和最小值上限下限
  25. uint key1_val=0,key2_val=0;//按键键值  (代表按键按几次)
  26. uint ceshi[128]={
  27.   23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
  28.   23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
  29.   23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
  30.   23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
  31.   23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
  32.   23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
  33.   23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12,
  34.   23,25,18,10,5,2,8,12,23,25,18,10,5,2,8,12
  35.    
  36. };

  37. //系统时钟初始化
  38. void sys_Init()
  39. {
  40.   volatile unsigned int i;
  41.   BCSCTL1&=~XT2OFF;          //打开XT2振荡器
  42.   do
  43.   {
  44.     IFG1 &= ~OFIFG;     // 清除振荡器失效标志
  45.     for (i = 0xFF; i > 0; i--);  // 延时,等待XT2起振
  46.   } while ((IFG1 & OFIFG) != 0);    // 判断XT2是否起振
  47.   BCSCTL2 =SELM_2+SELS;     //选择MCLK=SMCLK为XT2
  48. }
  49. //定时器A初始化
  50. void timer0()
  51. {
  52.   TACTL = TASSEL_2 + MC_2;  // 设置定时器A使用MCLK,不分频,连续计数模式  
  53.   CCR0 = 40000;              //CCR0初值
  54.   CCTL0 =  CCIE;             // 允许CCR0 中断
  55. }
  56. //ADC初始化
  57. void ADC_Init()
  58. {
  59.   P6SEL |= 0x02; // P6.1为ADC输入
  60.   ADC12CTL0 = REFON+ REF2_5V;     // REFON为打开内部电压发生器的意思,REF2_5V为设置参考电压选择为2.5v的意思
  61.   ADC12CTL0 |= SHT0_2 + ADC12ON;   // 设置采样保持时间为4个ADC12CLK(SHT_2),开启ADC12模块(ADC12ON)
  62.   ADC12CTL1 = SHP;
  63.   ADC12MCTL0 = INCH_1+SREF_1;             // Vr+=Vref+=2.5V
  64.   ADC12IE = 0x01;                  // 设置ADC12的中断使能,不用对应A1通道
  65.   ADC12CTL0 |= ENC;               //  // 使能AD转换
  66. }
  67. uchar flag=0;
  68. void main(void)
  69. {
  70.   WDTCTL = WDTPW + WDTHOLD;   // Stop WDT,关闭看门狗定时器
  71.   sys_Init();
  72.   timer0();
  73.   ADC_Init();
  74.   P2DIR |=0XFF;
  75.   LCD_init();    //液晶模块的初始化  
  76.   Write_Cmd(0x01);
  77.   GUI_Fill_GDRAM(0x00);      //清屏函数
  78.   LCD_write_string(0,0,"系统启动。。");
  79.   LCD_write_string(0,1,"通信工程系fu!!");
  80.   LCD_write_string(0,2,"通工系fu!!");
  81.   LCD_write_string(0,3,"系统启动fu。。");
  82.   _EINT();      //开启总中断(fuliang)
  83.   //_BIS_SR(LPM0_bits + GIE);        // 进入 LPM0 低功耗模式,允许中断,CPU停止工作,单片机等待
  84.   while(1)
  85.   {
  86.    
  87.     if(start==1)   //每20ms判断成立一次,下面的句子才能运行
  88.     {     
  89.       switch(key2_val)   //每20ms运行一次,switch这些句子能否运行要取决于“shart=1”
  90.       {  
  91.       case 1:      //本按键按一次的情况
  92.         if(flag==1)    //设置flag变量目的只让这里面的程序执行一次,
  93.         {
  94.           LCD_write_string(0,0,"回放模式");  //虽然程序只执行一次,但下面并没有清屏,所以只要按
  95.                                            //键不再一次按下,字符不会消失
  96.          
  97.           for(int i=0;i<128;i++)
  98.           {
  99.             z[i]=save[i];
  100.           }
  101.           count();//显示次数
  102.           for(int i=0;i<128;i+=16)
  103.           {
  104.             pict(i);
  105.           }
  106.           flag=0;
  107.         }
  108.         break;
  109.       case 2:         //本按键再次按下情况
  110.         LCD_write_string(0,0,"光电脉搏动态显示");
  111.         for(int i=0;i<128;i++)
  112.         {
  113.           z[i]=save[i];
  114.         }
  115.         
  116.         for(int i=0;i<128;i+=16)
  117.         {
  118.           pict(i);
  119.         }
  120.         break;
  121.       case 3:        //本按键第三次按下情况
  122.         LCD_write_string(0,0,"监护模式");
  123.         time_flag=1;//倒计时标志
  124.         put_time(7,1,60-second_1);
  125.         count();//显示次数
  126.         put_HZ(0,3,cont_flag);
  127.         
  128.       default: break;
  129.       }
  130.       start=0;      //最后要记得清零
  131.     }   
  132.   }  
  133. }

  134. // Timer A0 interrupt service routine
  135. //CCR0比较捕捉中断服务函数
  136. #pragma vector=TIMERA0_VECTOR
  137. __interrupt void Timer_A0 (void)
  138. {  
  139.   static uchar temp;
  140.   CCR0 += 40000;    //8M/40000=200Hz==>5ms//计时
  141.   if(++temp==200)  //5ms*200=1s
  142.   {
  143.   P2OUT ^=BIT0;
  144.   temp=0;
  145.   if(time_flag==1)  //监护模式倒计时标志
  146.   {
  147.     second_1++;     
  148.     if(second_1>59)
  149.     {
  150.     time_flag=0;
  151.     second_1=0;
  152.     cont_flag=0;  
  153.     }
  154.   }
  155.   else second_1=0;   
  156.   second++;
  157.   if(basic_flag==1&&second_1>58)//测试完成判断
  158.   {
  159.     Write_Cmd(0x01);
  160.     LCD_write_string(0,0,"完成!");
  161.     basic_flag=0;
  162.     time_flag=0;
  163.   }
  164.   if(basic_flag==1&&(second<10))
  165.   {
  166.     Write_Cmd(0x01);
  167.     LCD_write_string(0,0,"请重新放入!");  
  168.   }
  169.   if(second==1&&minute==0)
  170.   {
  171.     Write_Cmd(0x01);
  172.     LCD_write_string(0,0,"系统已工作ABC!");
  173.     LCD_write_string(0,1,"光纤通信一班符亮");
  174.   }
  175.   if(second>59)
  176.   {
  177.     second=0;
  178.     minute++;
  179.     if(minute>19)
  180.     {
  181.       minute=0;
  182.     }   
  183.   }
  184.   }   
  185.   if(temp%4==0)    //每5ms*4==20ms运行一次按键程序,对应下面的"start"标志
  186.   {
  187.     key_action();      
  188.   }
  189.   if(temp%10==0)
  190.   {
  191.     cont_flag++;
  192.     ADC12CTL0 |= ADC12SC;  //启动ADC12转换,让ADC12每隔50ms转换一次,
  193.   }
  194. }

  195. //AD中断
  196. #pragma vector=ADC_VECTOR
  197. __interrupt void ADC12_ISR (void)
  198. {
  199.   static double d=0;
  200.   static int x=0;
  201.   d=ADC12MEM0;//累加ad转换的值,多次转换可以保证转换的精度
  202.   u=d*25*100/4096;        
  203.   y=(int)((u/2500.0)*32);
  204.   save[x]=31-y;
  205.   x++;
  206.   if(x>127)
  207.   {     
  208.     x=0;
  209.   }
  210. }
  211. /*********************************************************
  212. 函数名称:display()
  213. 函数功能:在1602指定位置显示两位数,被显示的数值应在0~99之间
  214. ***********************************************************/

  215. void put(char x,char y,int c)
  216. {  
  217.   uchar ch[]=":0.000V";
  218.   ch[1]=c/1000%10+'0';
  219.   ch[3]= c/100%10+'0';
  220.   ch[4]= c/10%10+'0';
  221.   ch[5]= c%10+'0';   
  222.   LCD_write_string(x,y,ch);   //显示千位,v的单位为mV
  223. }

  224. void put_time(char x,char y,char z)
  225. {
  226.   uchar time[]="  ";
  227.   time[0]=z/10%10+'0';
  228.   time[1]=z%10+'0';
  229.   LCD_write_string(x,y,time);
  230. }

  231. void put_HZ(char A,char B,char shu)
  232. {
  233.   uchar hz[]="次数:   ";
  234.   hz[5]=shu/100%10+'0';
  235.   hz[6]=shu/10%10+'0';
  236.   hz[7]=shu%10+'0';
  237.   LCD_write_string(A,B,hz);
  238. }
  239. void put_one(char A,char B,char shu)
  240. {
  241.   uchar hz[]="个数:   ";
  242.   hz[5]=shu/100%10+'0';
  243.   hz[6]=shu/10%10+'0';
  244.   hz[7]=shu%10+'0';
  245.   LCD_write_string(A,B,hz);
  246. }

  247. /*********************/
  248. //画线//
  249. /********************/
  250. void pict(uint n)
  251. {
  252.   uint i,j;
  253.   uint d[32],k;
  254.   //Write_Cmd(0x34); //设置为8 位MPU 接口,扩充指令集,绘图模式关
  255.   LCD_en_command(0x36);
  256.   for(i=0;i<32;i++)
  257.     d[i]=0;
  258.   k=0x8000;
  259.   for(i=n;i<n+16;i++)
  260.   {
  261.     if(z[i]<=z[i+1])
  262.     {
  263.       for(j=z[i];j<=z[i+1];j++)
  264.       {
  265.         d[j]|=k;
  266.       }
  267.     }
  268.     else
  269.     {
  270.       for(j=z[i+1];j<=z[i];j++)
  271.       {
  272.         d[j]|=k;
  273.       }
  274.     }
  275.     k>>=1;
  276.   }
  277.   
  278.   for(j=0;j<32;j++)
  279.   {
  280.     LCD_en_command(0x80+j); //垂直地址Y
  281.     LCD_en_command(0x88+(n/16)); //水平地址X
  282.     LCD_en_dat(d[j]>>8);
  283.     LCD_en_dat(d[j]&0x00ff);
  284.   }
  285.   // Write_Cmd(0x36); //打开绘图模式
  286.   LCD_en_command(0x30); //恢复基本指令集,关闭绘图模式
  287. }

  288. void key_action()    //按键函数,每20ms运行一次这个函数
  289. {
  290.   start=1;    //按键按下的情况为“1”,每20ms运行一次(定时器里面是这么设置的)
  291.   key_val=inkey();
  292.   if(key_val!=0xff)    //如果按键按下的情况,0xff表没有按键按下
  293.     Write_Cmd(0x01);   //清除显示
  294.   if(key_val==1)       //第一个按键按下
  295.   {   
  296.     key2_val++;
  297.     if(key2_val==1)
  298.     {
  299.       flag=1;
  300.     }
  301.     if(key2_val==4)
  302.       key2_val=0;
  303.   }
  304.   if(key_val==2)        //当第二个按键按下情况
  305.   {
  306.    // exit_flag++;
  307.     key2_val=0;
  308.     Write_Cmd(0x01);
  309.     LCD_write_string(0,1,"基本模式");
  310.     LCD_write_string(0,2,"请等待!");
  311.     basic_flag=1;    //基本模式标志
  312.     time_flag=1;
  313.   }
  314.   
  315. }

  316. ……………………

  317. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
脉搏.zip (492.68 KB, 下载次数: 17)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表