找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机设计求助,现在lcd显示脉搏特别奇怪,数字特别小,特别容易报警?

[复制链接]
跳转到指定楼层
楼主


单片机源程序如下:
  1. #include <reg52.h>             //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义    变量范围0~255
  3. #define uint  unsigned int     //无符号整型 宏定义    变量范围0~65535

  4. uchar menu_1;           //设置不同报警参数的变量
  5. uchar flag_200ms ;        //200毫秒的变量

  6. unsigned char i=0,rate=0,timecount=0;
  7. unsigned int time[6]={0};
  8. uchar rate_l=2,rate_h=200;   //脉搏上下限报警值

  9. sbit rs=P1^0;     //寄存器选择信号 H:数据寄存器      L:指令寄存器
  10. sbit rw=P1^1;     //寄存器选择信号 H:数据寄存器      L:指令寄存器
  11. sbit e =P1^2;     //片选信号   下降沿触发
  12. sbit beep = P3^7;       //蜂鸣器IO口定义,仿真
  13. sbit key1 = P3^6;        //按键IO口定义,仿真
  14. sbit key2 = P3^5;        //按键IO口定义,仿真
  15. sbit key3 = P3^4;        //按键IO口定义,仿真

  16. /***********************1ms延时函数*****************************/
  17. void delay_1ms(uint q)
  18. {
  19.     uint i,j;
  20.     for(i=0;i<q;i++)
  21.         for(j=0;j<120;j++);
  22. }

  23. /********************************************************************
  24. * 名称 : delay_uint()
  25. * 功能 : 小延时。
  26. * 输入 : 无
  27. * 输出 : 无
  28. ***********************************************************************/
  29. void delay_uint(uint q)
  30. {
  31.     while(q--);
  32. }

  33. /********************************************************************
  34. * 名称 : write_com(uchar com)
  35. * 功能 : 1602指令函数
  36. * 输入 : 输入的指令值
  37. * 输出 : 无
  38. ***********************************************************************/
  39. void write_com(uchar com)
  40. {
  41.      rs=0;         //写指令
  42.     rw=0;         //对1602写操作
  43.     P0=com;         //P0口对1602写指令
  44.     delay_uint(25);
  45.     e=1;         //e=1使能信号
  46.     delay_uint(100);   //延时一下等1602完成操作
  47.     e=0;
  48. }

  49. /********************************************************************
  50. * 名称 : write_data(uchar dat)
  51. * 功能 : 1602写数据函数
  52. * 输入 : 需要写入1602的数据
  53. * 输出 : 无
  54. ***********************************************************************/
  55. void write_data(uchar dat)
  56. {
  57.      rs=1;         //写数据
  58.     rw=0;         //对1602写操作
  59.     P0=dat;          //P0口对1602写数据
  60.     delay_uint(25);
  61.     e=1;         //e=1使能信号
  62.     delay_uint(100);   //延时一下等1602完成操作
  63.     e=0;   
  64. }

  65. /********************************************************************
  66. * 名称 : write_string(uchar hang,uchar add,uchar *p)
  67. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  68.           write_string(1,5,"ab cd ef;")
  69. * 输入 : 行,列,需要输入1602的数据
  70. * 输出 : 无
  71. ***********************************************************************/
  72. void write_string(uchar hang,uchar add,uchar *p)
  73. {
  74.     if(hang==1)   
  75.         write_com(0x80+add);       //写1602第一行的地址
  76.     else
  77.         write_com(0x80+0x40+add);   //写1602第二行的地址
  78.     while(1)                                                         
  79.     {
  80.         if(*p == '\0')  break;    //\0字符串的结尾标志  break结束while循环 结束写字符
  81.         write_data(*p);        //写数据
  82.         p++;                //指针地址加1  
  83.     }   
  84. }

  85. /*****************控制光标函数********************/
  86. void write_guanbiao(uchar hang,uchar add,uchar date)
  87. {        
  88.     if(hang==1)   
  89.         write_com(0x80+add);
  90.     else
  91.         write_com(0x80+0x40+add);
  92.     if(date == 1)
  93.         write_com(0x0f);     //显示光标并且闪烁   
  94.     else
  95.         write_com(0x0c);   //关闭光标
  96. }   

  97. /***********************lcd1602上显示3位十进制数************************/
  98. void write_lcd3(uchar hang,uchar add,uint date)
  99. {
  100.     if(hang==1)   
  101.         write_com(0x80+add);       //写1602第一行的地址
  102.     else
  103.         write_com(0x80+0x40+add);  //写1602第二行的地址
  104.     write_data(0x30+date/100%10);    //显示百位数,加0x30转换为ASCII字符
  105.     write_data(0x30+date/10%10);    //显示十位数
  106.     write_data(0x30+date%10);       //显示个位数   
  107. }

  108. /***********************lcd1602初始化设置************************/
  109. void init_1602()
  110. {
  111.     write_com(0x38);  //显示模式设置:16×2显示,5×7点阵,8位数据接口 不检测忙信号
  112.     write_com(0x0c);  //开显示 不显示光标
  113.     write_com(0x06);  //当写一个字符是,地址指针加 1
  114.     write_string(1,0,"    000/min    ");      //初始化1602显示
  115.     write_string(2,0,"  H:000  L:000  ");      //初始化1602显示
  116.     write_lcd3(2,4,rate_h);           
  117.     write_lcd3(2,11,rate_l);
  118. }

  119. /*************定时器0初始化程序***************/
  120. void time_init()      
  121. {
  122.     EA   = 1;           //开总中断
  123.     TMOD = 0X01;      //定时器0工作方式1
  124.     ET0  = 1;          //开定时器0中断
  125.     TR0  = 1;          //允许定时器0定时
  126. }

  127. /***********外部中断0初始化程序****************/
  128. void init_int0()      //外部中断0初始化程序
  129. {
  130.     EX0=1;              //允许外部中断0中断
  131.     EA=1;               //开总中断
  132.     IT0 = 1;           //外部中断0负跳变中断
  133. }
  134.   
  135. /********************独立按键程序*****************/
  136. uchar key_can;     //按键值

  137. void key()     //独立按键程序
  138. {
  139.     static uchar key_new;        //key_new  这个变量的功能是做按键松手检测的
  140.     key_can = 0;                //按键值还原成0
  141.      if(key1 == 0 || key2 == 0 || key3 == 0)        //有按键按下
  142.     {
  143.         delay_1ms(1);             //按键延时消抖动
  144.         if(key_new == 1)
  145.         {                     
  146.             key_new = 0;        //key_new = 0   说明按键已按下
  147.             if(key1 == 0)        //确认是按键按下
  148.                 key_can = 1;     //得到按键值
  149.             if(key2 == 0)        //确认是按键按下
  150.                 key_can = 2;     //得到按键值
  151.             if(key3 == 0)        //确认是按键按下
  152.                 key_can = 3;     //得到按键值
  153.         }            
  154.     }
  155.     else
  156.         key_new = 1;     //key_new = 1   说明按键已经松开了   
  157. }

  158. /**********************设置函数************************/
  159. void key_with()
  160. {
  161.     if(key_can == 1)    //设置键
  162.     {
  163.         menu_1++;
  164.         if(menu_1 > 2)   
  165.         {
  166.             menu_1 = 0;          //menu_1 = 0 退出设置了,在正常显示界面下
  167.             init_1602();      //初始化液晶显示
  168.         
  169.         }
  170.     }
  171. /***************设置*********************/
  172.     if(menu_1 != 0)
  173.     {
  174.         if(menu_1 == 1)          //设置脉搏上限报警值
  175.         {
  176.             if(key_can == 2)    //加键
  177.             {
  178.                 rate_h ++;           //设置脉搏上限报警值 加1
  179.                 if(rate_h >= 255)
  180.                     rate_h = 0;
  181.             }        
  182.             if(key_can == 3)    //减键      
  183.             {
  184.                 rate_h -- ;           //设置脉搏上限报警值 减1
  185.                 if(rate_h <= rate_l)
  186.                     rate_h = rate_l + 1;    //限制脉搏上限不能低于脉搏下限
  187.             }   
  188.         }
  189.         if(menu_1 == 2)          //设置脉搏下限报警值
  190.         {
  191.             if(key_can == 2)    //加键
  192.             {
  193.                 rate_l ++;                   //设置脉搏下限报警值 加1
  194.                 if(rate_l >= rate_h)
  195.                     rate_l = rate_h - 1;   //限制脉搏下限不能高于脉搏上限
  196.             }   
  197.             if(key_can == 3)    //减键      
  198.             {
  199.                 if(rate_l == 0)
  200.                     rate_l = 1;
  201.                 rate_l -- ;                  //设置脉搏下限报警值 减1
  202.             }
  203.         }
  204.         write_lcd3(2,4,rate_h);               //显示上限报警值
  205.         write_lcd3(2,11,rate_l);        //显示下限报警值
  206.         delay_1ms(10);   
  207.     }
  208. }

  209. /****************报警函数***************/
  210. void clock_h_l()
  211. {
  212.     if(rate != 0)
  213.     {
  214.         if((rate <= rate_l) || (rate >= rate_h))
  215.         {
  216.             beep = ~beep;       //蜂鸣器报警            
  217.         }
  218.         else
  219.         {
  220.             beep = 1;    //取消报警
  221.         }
  222.     }else
  223.     {
  224.         beep = 1;   //取消报警   
  225.     }
  226.             
  227. }

  228. /****************主函数***************/
  229. void main()
  230. {   


  231.     init_1602();                    //1602初始化
  232.     time_init();                    //初始化定时器
  233.     init_int0();      //外部中断0初始化程序
  234.     while(1)
  235.     {            
  236.         key();                     //按键函数
  237.          key_with();                 //按键设置函数
  238.           rate=60000/(time[1]+time[2]+time[3]+time[4]+time[5])/5;      //计算脉搏次数
  239.             write_lcd3(1,5,rate);     //显示脉搏
  240.             clock_h_l();             //报警函数
  241.         delay_1ms(1);          //延时1毫秒
  242.     }
  243. }

  244. void int0() interrupt 0         //外部中断0,由P3.2端口引入,低电平或下降沿引起
  245. {
  246.     if(timecount<8)   //当连续两次检测时间间隔小于8*50ms=400ms不处理
  247.         {
  248.            TR0=1;//开定时器
  249.         }
  250.     else
  251.     {
  252.          time[i]=timecount*50+TH0+TL0;//算出间隔时间,timecount是50ms计数,每隔50ms timecount加1
  253. //         time[i]=timecount*50+TH0*0.256+TL0/1000;
  254. //         time[i]=TH0*256+TL0;
  255.          TH0 = 0x3c;
  256.          TL0 = 0xb0;     // 50ms         12M
  257.          timecount=0;//50ms计数清零
  258.           i++;
  259.         if(i==6)//记录到超过等于6次时间
  260.         {
  261.             i=1;//计数从1开始
  262.         }
  263.     }                                
  264. }


  265. void time0_int() interrupt 1
  266. {        
  267.         TH0 = 0x3c;
  268.         TL0 = 0xb0;     // 50ms         12M
  269.         timecount++;//每50ms一次计数
  270.         if(timecount>25)     //当超过25*50ms=1.5s没有检测到信号停止显示
  271.         {
  272.             i=0;//数据个数清零
  273.             timecount=0;//50ms计数清零
  274.             TR0=0;//定时器关
  275.             TH0 = 0x3c;
  276.             TL0 = 0xb0;     // 50ms         12M
  277.         }
  278. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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