找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2842|回复: 1
收起左侧

基于51单片机的US-100(超声波模块)1602显示程序

[复制链接]
ID:289073 发表于 2018-3-8 10:37 | 显示全部楼层 |阅读模式
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define nops {_nop_();_nop_();_nop_();_nop_();}
  4. /******************************引脚及变量的定义****************************/
  5. sbit RS = P2^0;  //寄存器选择位
  6. sbit RW = P2^1;  //读取选择位
  7. sbit E = P2^2;   //使能信号位
  8. sbit BF = P0^7;  //忙碌信号位
  9. unsigned char code Tab[] = {"0123456789"};
  10. unsigned char code string[] = {"range:2cm--4.5m"};
  11. char part,ge,shi,bai;
  12. char idata GLengthLoh[2];    //接收缓冲区
  13. bit success_flag;      //定义测试成功标志位
  14. /*********************************************************/
  15. /*********函数名称:delay1ms(void)      ******************/
  16. /*********函数功能:延时1毫秒           ******************/
  17. /*********函数参数:void                ******************/
  18. /*********************************************************/
  19. void delay1ms(void)   //误差 -0.651041666667us
  20. {
  21.     char a,b;
  22.     for(b=102;b>0;b--)
  23.         for(a=3;a>0;a--);
  24. }         
  25. /*********************************************************/
  26. /*********函数名称:delaynms(char n)    ******************/
  27. /*********函数功能:延时n个1毫秒        ******************/
  28. /*********函数参数:n                   ******************/
  29. /*********************************************************/
  30. void delaynms(char n)
  31. {
  32.     char a;
  33.         for(a = 0;a > n;a--)
  34.             delay1ms();
  35. }
  36. /*********************************************************/
  37. /*********函数名称:BusyTest(void)      ******************/
  38. /*********函数功能:判断液晶模块忙碌状态******************/
  39. /*********函数参数:返回值:result  ******************/
  40. /*********************************************************/
  41. unsigned char BusyTest()
  42. {
  43.     bit result;         
  44.         RS = 0;                  
  45.         RW = 1;                  //RS为低电平,RW为高电平时,可以读状态
  46.         E = 1;                  //使能为高电平时可读取信息
  47.         nops;                  //延时40us,给硬件反应时间
  48.         result = BF;     //将忙碌标志位电平赋给result
  49.         E = 0;                  //使能1到0:执行指令
  50.         return result;
  51. }
  52. /*********************************************************/
  53. /*********函数名称:WriteInstruction(char dictate)*******/
  54. /*********函数功能:将模式设置指令或显示地址写入液晶模块**/
  55. /*********函数参数:dictate             ******************/
  56. /*********************************************************/
  57. void WriteInstruction(char dictate)
  58. {
  59.     while(BusyTest() == 1);         //如果忙碌标志位忙碌则等待
  60.         RS = 0;
  61.         RW = 0;                                 //RS/RW位同时为低电平时可写入指令
  62.         E = 0;                                 //使能0到1:写入指令
  63.         nops;
  64.         P0 = dictate;                    //将数据送入P0口,写入数据或地址
  65.         nops;
  66.         E = 1;                                 //使能0到1:写入指令
  67.         nops;
  68.         E = 0;                                 //使能1到0:执行指令
  69. }
  70. /*********************************************************/
  71. /*********函数名称:WriteAddress(char x)          *******/
  72. /*********函数功能:指定字符显示的实际地址     ***********/
  73. /*********函数参数:x                   ******************/
  74. /*********************************************************/
  75. void WriteAddress(char x)
  76. {
  77.     WriteInstruction(x|0x80);        //80H+地址码
  78. }
  79. /*********************************************************/
  80. /*********函数名称:WriteData(char y)             *******/
  81. /*********函数功能:将数据(字符的标准ASCII码)写入液晶模块*/
  82. /*********函数参数:y                   ******************/
  83. /*********************************************************/
  84. void WriteData(char y)
  85. {
  86.     while(BusyTest() == 1);          //如果忙碌标志位忙碌则等待
  87.         RS = 1;
  88.         RW = 0;                                  //RS为高电平,RW为低电平时,可以写入数据
  89.         E = 0;
  90.         P0 = y;
  91.         nops;
  92.         E = 1;
  93.         nops;
  94.         E = 0;
  95. }
  96. /*********************************************************/
  97. /*********函数名称:LCDInit(void)                  *******/
  98. /*********函数功能:液晶模块初始化        ****************/
  99. /*********函数参数:void                ******************/
  100. /*********************************************************/
  101. void LCDInit(void)
  102. {
  103.     delaynms(15);    //延时15毫秒,首次写入液晶指令应给反应时间
  104.         WriteInstruction(0x38);        //显示模式设置:16×2显示,5×7点阵,8位数据接口
  105.         delaynms(5);        //延时5秒,反应时间
  106.     WriteInstruction(0x38);
  107.         delaynms(5);        //延时5秒,反应时间
  108.         WriteInstruction(0x38);
  109.         delaynms(5);        //连续三次,确保初始化成功
  110.         WriteInstruction(0x0c);   //显示模式设置:显示开,无光标,光标不闪烁
  111.         delaynms(5);
  112.         WriteInstruction(0x06);        //显示模式设置:显示光标右移,屏幕不移动
  113.         delaynms(5);
  114.         WriteInstruction(0x01);   //清屏
  115.         delaynms(5);
  116. }
  117. /*********************************************************/
  118. /*********函数名称:UART_Send(char dat)            *******/
  119. /*********函数功能:串口发送函数          ****************/
  120. /*********函数参数:dat                 ******************/
  121. /*********************************************************/
  122. void UART_Send(char dat)
  123. {
  124.     TI = 0;            // 清发送标志
  125.     SBUF = dat;        //如果TI为0等待
  126.     while (!TI);        //等待发送数据
  127. }
  128. /*********************************************************/
  129. /*********函数名称:UART_Init()            ***************/
  130. /*********函数功能:串口初始化函数        ****************/
  131. /*********函数参数:无                  ******************/
  132. /*********************************************************/
  133. void UART_Init()
  134. {   
  135.     TH1 = 0xFD;
  136.     TL1 = 0xFD;
  137.     TMOD = 0x21;            //设置定时器1为模式2;定时器0为模式1      
  138.     TH0 =(65536-2500)/256;  //约2.50MS定时器初值
  139.     TL0 =(65536-2500)%256;  //约2.50MS定时器初值
  140.     ET0 = 1;
  141.     TR0 = 1;                //启动定时器
  142.     TR1 = 1;                //启动定时器           SM0  SM1
  143.     SM0 = 0;                //串口通信模式设置     0      0 = 0
  144.     SM1 = 1;                                //     0      1 = 1
  145.                                             //     1      0 = 2
  146.                                             //     1      1 = 3
  147.     REN = 1;       //串口允许接收数据
  148.     ES = 1;        //开串中断
  149.     EA = 1;
  150. }
  151. /*********************************************************/
  152. /*********函数名称:UART_ISR(void)         ***************/
  153. /*********函数功能:串口中断函数          ****************/
  154. /*********函数参数:void                ******************/
  155. /*********************************************************/
  156. void UART_ISR(void) interrupt 4
  157. {
  158.     char temp,k;
  159.     ES = 0;             //关中断            
  160.     if(RI)
  161.     {
  162.         RI = 0;         //清接收标志
  163.         temp = SBUF;
  164.         GLengthLoh[k] = temp;
  165.         k++;
  166.         if(k == 2) //k=数据长度
  167.         k = 0;
  168.     }   
  169.     ES = 1;      //开中断
  170. }
  171. /*********************************************************/
  172. /*********函数名称:timer0()               ***************/
  173. /*********函数功能:定时器函数            ****************/
  174. /*********函数参数:void                ******************/
  175. /*********************************************************/
  176. timer0() interrupt 1         // 定时器0中断是1号
  177. {
  178.     TH0 =(65536-2500)/256; //约2.50MS定时器初值
  179.     TL0 =(65536-2500)%256; //约2.50MS定时器初值    TH0 = 0xef;    TL0 = 0x94;    //写入定时器0初始值
  180. }
  181. /*********************************************************/
  182. /*********函数名称:conversion(int8 temp_data)     *******/
  183. /*********函数功能:数据转换              ****************/
  184. /*********函数参数:temp_data           ******************/
  185. /*********************************************************/
  186. void conversion(int temp_data)
  187. {
  188.     char part_data,ge_data,shi_data,bai_data;
  189.         bai_data = temp_data / 1000;
  190.         shi_data = (temp_data % 1000) / 100;
  191.         ge_data = (temp_data % 100) / 10;
  192.         part_data = temp_data % 10;
  193.         EA = 0;
  194.         bai = bai_data;
  195.         shi = shi_data;
  196.         ge = ge_data;
  197.         part = part_data;
  198.         EA = 1;
  199. }
  200. /*********************************************************/
  201. /*********函数名称:main(void)                      *******/
  202. /*********函数功能:主函数                ****************/
  203. /*********函数参数:void                 ******************/
  204. /*********************************************************/
  205. void main(void)
  206. {
  207.     int k;
  208.         long PreLength;                                          
  209.         LCDInit();                                           //调用液晶初始化函数
  210.         delaynms(10);
  211.     UART_Init();
  212.         PreLength = 0;
  213.         k = 0;
  214.         while(1)
  215.         {
  216.              WriteAddress(0x01);
  217.                  while(string[k] != '\0')
  218.                  {
  219.                       WriteData(string[k]);
  220.                           k++;
  221.                  }
  222.              UART_Send(0X55);
  223.                  PreLength = GLengthLoh[0] * 256 + GLengthLoh[1] - 5;
  224.          conversion(PreLength);
  225.              WriteAddress(0x41);           //从第2行第6列开始显示
  226.                  WriteData('J');                   //将特定的字符常量写入LCD
  227.                  WriteData('U');
  228.                  WriteData('L');
  229.                  WriteData('I');
  230.                  WriteData(':');
  231.                  if(PreLength <= 4500 && PreLength >= 20)
  232.                  {
  233.                      WriteData(Tab[bai]);           //将百位数字的字符常量写入LCD
  234.                      WriteData(Tab[shi]);           //将十位数字的字符常量写入LCD
  235.                      WriteData(Tab[ge]);           //将个位数字的字符常量写入LCD
  236.                             WriteData('.');
  237.                           WriteData(Tab[part]);
  238.                  }
  239.                  else
  240.                  {
  241.                      WriteData('-');         
  242.                      WriteData('-');
  243.                      WriteData('-');         
  244.                             WriteData('-');
  245.                           WriteData('-');
  246.                  }
  247.                  WriteData(' ');
  248.                  WriteData('c');
  249.                  WriteData('m');
  250.                  
  251.         }
  252. }
复制代码


回复

使用道具 举报

ID:313173 发表于 2018-7-10 20:38 | 显示全部楼层
为什么·12到25厘米之间无显示?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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