找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2956|回复: 2
收起左侧

简易的引体向上计数器 单片机红外对管测数程序

[复制链接]
ID:595800 发表于 2019-8-5 20:35 | 显示全部楼层 |阅读模式
利用红外对管测数,之后把数据通过lcd1602显示出来

单片机源程序如下:
  1. /*============================================================
  2. /
  3. ==============================================================
  4. SMC1602A(16*2)模拟口线接线方式
  5. 连接线图:       
  6.        ---------------------------------------------------
  7.        |LCM-----51   |        LCM-----51   |        LCM------51      |
  8.        --------------------------------------------------|
  9.        |DB0-----P1.0 |        DB4-----P1.4 |        RW-------P3.4    |
  10.        |DB1-----P1.1 |        DB5-----P1.5 |        RS-------P3.3    |
  11.        |DB2-----P1.2 |        DB6-----P1.6 |        E--------P3.5    |
  12.        |DB3-----P1.3 |        DB7-----P1.7 |        VLCD接1K电阻到GND|
  13.        ---------------------------------------------------
  14. 接线:模块TRIG接 P2.6  ECH0 接P2.7


  15. =============================================================*/
  16. #include <AT89x51.H>                //器件配置文件
  17. #include <intrins.h>
  18. #define  Rin  P3_7

  19. #define LCM_RW  P1_1 //定义LCD引脚
  20. #define LCM_RS  P1_0
  21. #define LCM_E   P1_5
  22. #define LCM_Data  P0

  23. #define Key_Data P2_0 //定义Keyboard引脚
  24. #define Key_CLK  P3_2

  25. #define Busy    0x80 //用于检测LCM状态字中的Busy标识

  26. void LCMInit(void);
  27. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
  28. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
  29. void Delay5Ms(void);
  30. void Delay400Ms(void);
  31. void Decode(unsigned char ScanCode);
  32. void WriteDataLCM(unsigned char WDLCM);
  33. void WriteCommandLCM(unsigned char WCLCM,BuysC);
  34. void Conut(void);

  35. unsigned char ReadDataLCM(void);
  36. unsigned char ReadStatusLCM(void);
  37. unsigned char code mcustudio[] ={"number:"};
  38. unsigned char code Cls[] =      {"                "};
  39. unsigned char code ASCII[10] =    {'0','1','2','3','4','5','6','7','8','9'};

  40. static unsigned char DisNum = 0; //显示用指针       
  41. unsigned int  time=0;
  42. bit      flag =0;
  43. unsigned char disbuff[4]={ 0,0,0,0,};
  44. unsigned long S = 0;
  45. volatile bit FlagSucceed=0;     //测量成功标志
  46. sbit Beep=P2^0;          //报警蜂鸣器
  47. sbit LedAlarm = P2^1;

  48. void WriteDataLCM(unsigned char WDLCM)
  49. {
  50.         ReadStatusLCM(); //检测忙
  51.         LCM_Data = WDLCM;
  52.         LCM_RS = 1;
  53.         LCM_RW = 0;
  54.         LCM_E = 0; //若晶振速度太高可以在这后加小的延时
  55.         LCM_E = 0; //延时
  56.         LCM_E = 1;
  57. }

  58. //写指令
  59. void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
  60. {
  61.         if (BuysC) ReadStatusLCM(); //根据需要检测忙
  62.         LCM_Data = WCLCM;
  63.         LCM_RS = 0;
  64.         LCM_RW = 0;       
  65.         LCM_E = 0;
  66.         LCM_E = 0;
  67.         LCM_E = 1;       
  68.   }

  69. //读数据
  70. unsigned char ReadDataLCM(void)
  71. {
  72.         LCM_RS = 1;
  73.         LCM_RW = 1;
  74.         LCM_E = 0;
  75.         LCM_E = 0;
  76.         LCM_E = 1;
  77.         return(LCM_Data);
  78. }

  79. //读状态
  80. unsigned char ReadStatusLCM(void)
  81. {
  82.         LCM_Data = 0xFF;
  83.         LCM_RS = 0;
  84.         LCM_RW = 1;
  85.         LCM_E = 0;
  86.         LCM_E = 0;
  87.         LCM_E = 1;
  88.         while (LCM_Data & Busy); //检测忙信号
  89.         return(LCM_Data);
  90. }

  91. void LCMInit(void) //LCM初始化
  92. {
  93.         LCM_Data = 0;
  94.         WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  95.         Delay5Ms();
  96.         WriteCommandLCM(0x38,0);
  97.         Delay5Ms();
  98.         WriteCommandLCM(0x38,0);
  99.         Delay5Ms();

  100.         WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  101.         WriteCommandLCM(0x08,1); //关闭显示
  102.         WriteCommandLCM(0x01,1); //显示清屏
  103.         WriteCommandLCM(0x06,1); // 显示光标移动设置
  104.         WriteCommandLCM(0x0F,1); // 显示开及光标设置
  105. }

  106. //按指定位置显示一个字符
  107. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  108. {
  109.         Y &= 0x1;
  110.         X &= 0xF; //限制X不能大于15,Y不能大于1
  111.         if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
  112.         X |= 0x80; //算出指令码
  113.         WriteCommandLCM(X, 1); //发命令字
  114.         WriteDataLCM(DData); //发数据
  115. }

  116. //按指定位置显示一串字符
  117. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
  118. {
  119.         unsigned char ListLength;

  120.   ListLength = 0;
  121.         Y &= 0xFE;
  122.         X &= 0xFF; //限制X不能大于15,Y不能大于1
  123.         while (DData[ListLength]>0x19) //若到达字串尾则退出
  124.                 {
  125.                         if (X <= 0xF) //X坐标应小于0xF
  126.                                 {
  127.                                         DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
  128.                                         ListLength++;
  129.                                         X++;
  130.                                 }
  131.                 }
  132. }

  133. //5ms延时
  134. void Delay5Ms(void)
  135. {
  136.         unsigned int TempCyc = 5552;
  137.         while(TempCyc--);
  138. }

  139. //400ms延时
  140. void Delay400Ms(void)
  141. {
  142.         unsigned char TempCycA = 5;
  143.         unsigned int TempCycB;
  144.         while(TempCycA--)
  145.                 {
  146.                         TempCycB=7269;
  147.                         while(TempCycB--);
  148.                 };
  149. }
  150. /********************************************************/
  151. void Conut(void)
  152.         {                                       
  153.          time=TH0*256+TL0;
  154.          TH0=0;
  155.          TL0=0;
  156.          S+=1;     //算出来是
  157.          Beep = 0;       


  158.          if((S>=1000)||flag==1) //超出测量范围显示“-”
  159.          {         
  160.           flag=0;
  161.          
  162.           DisplayOneChar(0, 1, ASCII[0]);
  163.           DisplayOneChar(1, 1, ASCII[1]);
  164.           DisplayOneChar(2, 1, ASCII[2]);
  165.          }
  166.          else
  167.          {
  168.           disbuff[0]=S/100%10;
  169.           disbuff[1]=S/10%10;
  170.           disbuff[2]=S%10;
  171.           DisplayOneChar(0, 1, ASCII[disbuff[0]]);
  172.           DisplayOneChar(1, 1, ASCII[disbuff[1]]);
  173.           DisplayOneChar(2, 1, ASCII[disbuff[2]]);
  174.          }

  175.         }                       
  176.         /********************************************************/
  177.      void zd0() interrupt 1                  //T0中断用来计数器溢出,超过测距范围
  178.   {
  179.     flag=1;                                                         //中断溢出标志
  180.        
  181.   }
  182. /********************************************************/
  183.      void  StartModule()                          //启动模块
  184.   {
  185.            Rin=0;                                             //启动一次模块
  186.           _nop_();
  187.           _nop_();
  188.           _nop_();
  189.           _nop_();
  190.           _nop_();
  191.           _nop_();
  192.           _nop_();
  193.           _nop_();
  194.           _nop_();
  195.           _nop_();
  196.           _nop_();
  197.           _nop_();
  198.           _nop_();
  199.           _nop_();
  200.           _nop_();
  201.           _nop_();
  202.           _nop_();
  203.           _nop_();
  204.           _nop_();
  205.           _nop_();
  206.           _nop_();
  207.           Rin=1;
  208.   }
  209. /********************************************************/
  210. void delayms(unsigned int ms)
  211. {
  212.         unsigned char i=100,j;
  213.         for(;ms;ms--)
  214.         {
  215.                 while(--i)
  216.                 {
  217.                         j=10;
  218.                         while(--j);
  219.                 }
  220.         }
  221. }
  222. /*********************************************************/
  223. void main(void)
  224. {

  225.        
  226.         unsigned char TempCyc;
  227.         LedAlarm = 1;
  228.         Delay400Ms(); //启动等待,等LCM讲入工作状态
  229.         LCMInit(); //LCM初始化
  230.         Delay5Ms(); //延时片刻(可不要)
  231.         DisplayListChar(0, 0, mcustudio);
  232.         ReadDataLCM();//测试用句无意义
  233.         for (TempCyc=0; TempCyc<10; TempCyc++)
  234.         Delay400Ms(); //延时                       
  235.         while(1)
  236.           {
  237.              StartModule();
  238.                  DisplayOneChar(0, 1, ASCII[0]);

  239.              while(!Rin);                //当RX为零时等待
  240.                  TR0=0;                                //关闭计数
  241.                  
  242.          Conut();                        //计算
  243.                  Beep = 1;
  244.                  delayms(80);                //80MS

  245.              while(Rin);                        //当RX为1计数并等待
  246.                  EA=0;
  247.                         //以下为一次检测过程;先发出Trin电平,打开外部中断,清零T1
  248.                         //最后在外部中断下降沿触发时取出T1当前值,计算出Trig脉冲宽度
  249.              TR0=1;                            //开启计数
  250.                  Beep = 0;
  251.           }
  252.                         }       
  253.                                                 
复制代码

所有程序51hei提供下载:
调试.zip (173.52 KB, 下载次数: 18)

评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:285863 发表于 2019-8-6 09:51 | 显示全部楼层
采用多路红外检测才可靠吧
回复

使用道具 举报

ID:595800 发表于 2019-8-6 15:27 | 显示全部楼层
bemc 发表于 2019-8-6 09:51
采用多路红外检测才可靠吧

多路的我没试过,这是我大一下学期做的的一个东西,我的这个应该算是很简单的吧
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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