找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机脉宽测量程序

[复制链接]
跳转到指定楼层
楼主
ID:390798 发表于 2018-8-28 15:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机源程序如下:
  1. #include <reg51.H>  //器件配置文件
  2. #include <intrins.h>
  3. sbit  RX = P3^6;
  4. sbit TX = P3^7 ;
  5. sbit LCM_RW = P2^5; //定义LCD引脚
  6. sbit LCM_RS = P2^6 ;
  7. sbit LCM_E = P2^4 ;
  8. #define LCM_Data P0
  9. sbit Key_Data = P3^3 ;//定义Keyboard引脚
  10. sbit Key_CLK = P3^2 ;
  11. #define Busy    0x80 //用于检测LCM状态字中的Busy标识
  12. void LCMInit(void);
  13. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
  14. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
  15. void Delay5Ms(void);
  16. void Delay400Ms(void);
  17. void Decode(unsigned char ScanCode);
  18. void WriteDataLCM(unsigned char WDLCM);
  19. void WriteCommandLCM(unsigned char WCLCM,BuysC);
  20. unsigned char ReadDataLCM(void);
  21. unsigned char ReadStatusLCM(void);
  22. unsigned char code mcustudio[] ={"==Range Finder=="};
  23. unsigned char code email[] =    {"heyaodz@163.com "};
  24. unsigned char code Cls[] =      {"                "};
  25. unsigned char code ASCII[15] =    {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
  26. static unsigned char DisNum = 0; //显示用指针      
  27.        unsigned int  time=0;
  28.     unsigned long S=0;
  29.     bit      flag =0;
  30.     unsigned char disbuff[4]    ={ 0,0,0,0,};

  31. //写数据
  32. void WriteDataLCM(unsigned char WDLCM)
  33. {
  34. ReadStatusLCM(); //检测忙
  35. LCM_Data = WDLCM;
  36. LCM_RS = 1;
  37. LCM_RW = 0;
  38. LCM_E = 0; //若晶振速度太高可以在这后加小的延时
  39. LCM_E = 0; //延时
  40. LCM_E = 1;
  41. }
  42. //写指令
  43. void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
  44. {
  45. if (BuysC) ReadStatusLCM(); //根据需要检测忙
  46. LCM_Data = WCLCM;
  47. LCM_RS = 0;
  48. LCM_RW = 0;
  49. LCM_E = 0;
  50. LCM_E = 0;
  51. LCM_E = 1;
  52. }
  53. //读数据
  54. unsigned char ReadDataLCM(void)
  55. {
  56. LCM_RS = 1;
  57. LCM_RW = 1;
  58. LCM_E = 0;
  59. LCM_E = 0;
  60. LCM_E = 1;
  61. return(LCM_Data);
  62. }
  63. //读状态
  64. unsigned char ReadStatusLCM(void)
  65. {
  66. LCM_Data = 0xFF;
  67. LCM_RS = 0;
  68. LCM_RW = 1;
  69. LCM_E = 0;
  70. LCM_E = 0;
  71. LCM_E = 1;
  72. while (LCM_Data & Busy); //检测忙信号
  73. return(LCM_Data);
  74. }
  75. void LCMInit(void) //LCM初始化
  76. {
  77. LCM_Data = 0;
  78. WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  79. Delay5Ms();
  80. WriteCommandLCM(0x38,0);
  81. Delay5Ms();
  82. WriteCommandLCM(0x38,0);
  83. Delay5Ms();
  84. WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  85. WriteCommandLCM(0x08,1); //关闭显示
  86. WriteCommandLCM(0x01,1); //显示清屏
  87. WriteCommandLCM(0x06,1); // 显示光标移动设置
  88. WriteCommandLCM(0x0F,1); // 显示开及光标设置
  89. }
  90. //按指定位置显示一个字符
  91. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  92. {
  93. Y &= 0x1;
  94. X &= 0xF; //限制X不能大于15,Y不能大于1
  95. if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
  96. X |= 0x80; //算出指令码
  97. WriteCommandLCM(X, 1); //发命令字
  98. WriteDataLCM(DData); //发数据
  99. }
  100. //按指定位置显示一串字符
  101. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
  102. {
  103. unsigned char ListLength;
  104.   ListLength = 0;
  105. Y &= 0x1;
  106. X &= 0xF; //限制X不能大于15,Y不能大于1
  107. while (DData[ListLength]>0x19) //若到达字串尾则退出
  108.   {
  109.    if (X <= 0xF) //X坐标应小于0xF
  110.     {
  111.      DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
  112.      ListLength++;
  113.      X++;
  114.     }
  115.   }
  116. }
  117. //5ms延时
  118. void Delay5Ms(void)
  119. {
  120. unsigned int TempCyc = 5552;
  121. while(TempCyc--);
  122. }
  123. //400ms延时
  124. void Delay400Ms(void)
  125. {
  126. unsigned char TempCycA = 5;
  127. unsigned int TempCycB;
  128. while(TempCycA--)
  129.   {
  130.    TempCycB=7269;
  131.    while(TempCycB--);
  132.   };
  133. }
  134. /********************************************************/
  135.     void Conut(void)
  136. {
  137.   time=TH0*256+TL0;
  138.   TH0=0;
  139.   TL0=0;

  140.   S=(time*1.8)/10;     //算出来是MM
  141.   if((S>=7000)||flag==1) //超出测量范围显示“-”
  142.   {  
  143.    flag=0;
  144.   
  145.    DisplayOneChar(0, 1, ASCII[11]);
  146.    DisplayOneChar(1, 1, ASCII[10]); //显示点
  147.    DisplayOneChar(2, 1, ASCII[11]);
  148.    DisplayOneChar(3, 1, ASCII[11]);
  149.    DisplayOneChar(4, 1, ASCII[11]);
  150.    DisplayOneChar(5, 1, ASCII[12]); //显示M
  151.   }
  152.   else
  153.   {
  154.    disbuff[0]=S/1000;
  155.    disbuff[1]=S/100%10;
  156.    disbuff[2]=S/10%10;
  157.    disbuff[3]=S%10;
  158.    DisplayOneChar(0, 1, ASCII[disbuff[0]]);
  159.    DisplayOneChar(1, 1, ASCII[10]); //显示点
  160.    DisplayOneChar(2, 1, ASCII[disbuff[1]]);
  161.    DisplayOneChar(3, 1, ASCII[disbuff[2]]);
  162.    DisplayOneChar(4, 1, ASCII[disbuff[3]]);
  163.    DisplayOneChar(5, 1, ASCII[12]); //显示M
  164.   }
  165. }
  166. /********************************************************/
  167.      void zd0() interrupt 1    //T0中断用来计数器溢出,超过测距范围
  168.   {
  169.     flag=1;        //中断溢出标志
  170. RX=0;
  171.   }
  172. /********************************************************/
  173.      void  StartModule()            //启动模块
  174.   {
  175.    TX=1;                        //启动一次模块
  176.    _nop_();
  177.    _nop_();
  178.    _nop_();
  179.    _nop_();
  180.    _nop_();
  181.    _nop_();
  182.    _nop_();
  183.    _nop_();
  184.    _nop_();
  185.    _nop_();
  186.    _nop_();
  187.    _nop_();
  188.    _nop_();
  189.    _nop_();
  190.    _nop_();
  191.    _nop_();
  192.    _nop_();
  193.    _nop_();
  194.    _nop_();
  195.    _nop_();
  196.    _nop_();
  197.    TX=0;
  198.   }
  199. void Timer_Count(void)
  200. {
  201.    TR0=1;       //开启计数
  202.       while(RX);   //当RX为1计数并等待
  203.       TR0=0;    //关闭计数
  204.          Conut();   //计算
  205. }
  206. /********************************************************/
  207. void delayms(unsigned int ms)
  208. {
  209. unsigned char i=100,j;
  210. for(;ms;ms--)
  211. {
  212.   while(--i)
  213.   {
  214.    j=10;
  215.    while(--j);
  216.   }
  217. }
  218. }
  219. /*********************************************************/
  220. void main(void)
  221. {
  222.     unsigned int valA;
  223. unsigned char TempCyc;
  224. Delay400Ms(); //启动等待,等LCM讲入工作状态
  225. LCMInit(); //LCM初始化
  226. Delay5Ms(); //延时片刻(可不要)
  227. DisplayListChar(0, 0, mcustudio);
  228. DisplayListChar(0, 1, email);
  229. ReadDataLCM();//测试用句无意义
  230. for (TempCyc=0; TempCyc<10; TempCyc++)
  231. Delay400Ms(); //延时
  232. DisplayListChar(0, 1, Cls);
  233.   TMOD=0x01;     //设T0为方式1,GATE=1;
  234.   TH0=0;
  235.   TL0=0;         
  236.   ET0=1;             //允许T0中断
  237.   EA=1;      //开启总中断   

  238.   while(1)
  239.    {
  240.   
  241.   delayms(60);
  242.   RX=1;
  243.      StartModule();
  244.         for(valA=7510;valA>0;valA--)
  245.      {
  246.      
  247.         if(RX==1)
  248.      {
  249.            Timer_Count();
  250.      }
  251.       }
  252.    }
  253. }


复制代码


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

使用道具 举报

沙发
ID:1 发表于 2018-8-28 18:45 | 只看该作者
补全原理图或者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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