找回密码
 立即注册

QQ登录

只需一步,快速开始

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

通过超声波传感器控制电机的正反转单片机程序有问题,大神帮忙看一下来

[复制链接]
跳转到指定楼层
楼主
ID:108510 发表于 2017-7-11 20:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
50黑币
要求是:通过超声波传感器控制电机的正反转,当小于设定值A时,电机正转,等于时停止,大于时反转。现在程序写入后,设定值在个位数满足要求,但设定值超过个位后比如12或25时它还是按照2或5进行比较.不知道程序在哪出错了.怎么整
//超声波模块显示程序
  1. #include <reg52.h>     //包括一个52标准内核的头文件
  2. #include<intrins.h>  //包含_nop_()函数定义的头文件
  3. #define uchar unsigned char //定义一下方便使用
  4. #define uint  unsigned int
  5. #define ulong unsigned long
  6. sbit ZZ=P1^0;
  7. sbit FZ=P1^1;
  8. sbit k1=P1^4;
  9. sbit k2=P1^5;
  10. sbit k3=P1^6;
  11. sbit Tx=P3^2;
  12. sbit Rx=P3^3;
  13. sbit RS=P2^0;    //寄存器选择位,将RS位定义为P2.0引脚
  14. sbit RW=P2^1;    //读写选择位,将RW位定义为P2.1引脚
  15. sbit E=P2^2;     //使能信号位,将E位定义为P2.2引脚
  16. sbit BF=P0^7;    //忙碌标志位,,将BF位定义为P0.7引脚
  17. int  A=20;
  18. unsigned char code digit[ ]={"0123456789"}; //定义字符数组显示数字
  19. //uchar code SEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管0-9
  20. uint distance[4];  //测距接收缓冲区
  21. uchar ge,shi,bai,temp,flag,outcomeH,outcomeL,i;  //自定义寄存器
  22. bit succeed_flag;  //测量成功标志
  23. uint tdata;
  24. //********函数声明
  25. void conversion(uint temp_data);
  26. void delay_20us();
  27. void pai_xu();
  28. void DisplayA();


  29. /*****************************************************
  30. 函数功能:延时1ms
  31. (3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
  32. ***************************************************/
  33. void delay1ms()
  34. {
  35.    unsigned char i,j;        
  36.          for(i=0;i<10;i++)
  37.           for(j=0;j<33;j++)
  38.            ;                 
  39. }
  40. /*****************************************************
  41. 函数功能:延时若干毫秒
  42. 入口参数:n
  43. ***************************************************/
  44. void delay(unsigned char n)
  45. {
  46.    unsigned char i;
  47.         for(i=0;i<n;i++)
  48.            delay1ms();
  49. }
  50. /*****************************************************
  51. 函数功能:判断液晶模块的忙碌状态
  52. 返回值:result。result=1,忙碌;result=0,不忙
  53. ***************************************************/
  54. unsigned char BusyTest(void)
  55.   {
  56.     bit result;
  57.         RS=0;       //根据规定,RS为低电平,RW为高电平时,可以读状态
  58.     RW=1;
  59.     E=1;        //E=1,才允许读写
  60.     _nop_();   //空操作
  61.     _nop_();
  62.     _nop_();
  63.     _nop_();   //空操作四个机器周期,给硬件反应时间        
  64.     result=BF;  //将忙碌标志电平赋给result
  65.    E=0;         //将E恢复低电平
  66.     return result;
  67.   }
  68. /*****************************************************
  69. 函数功能:将模式设置指令或显示地址写入液晶模块
  70. 入口参数:dictate
  71. ***************************************************/
  72. void WriteInstruction (unsigned char dictate)
  73. {   
  74.     while(BusyTest()==1); //如果忙就等待
  75.          RS=0;                  //根据规定,RS和R/W同时为低电平时,可以写入指令
  76.          RW=0;   
  77.          E=0;                   //E置低电平(根据表8-6,写指令时,E为高脉冲,
  78.                              // 就是让E从0到1发生正跳变,所以应先置"0"
  79.          _nop_();
  80.          _nop_();             //空操作两个机器周期,给硬件反应时间
  81.          P0=dictate;            //将数据送入P0口,即写入指令或地址
  82.          _nop_();
  83.          _nop_();
  84.          _nop_();
  85.          _nop_();               //空操作四个机器周期,给硬件反应时间
  86.          E=1;                   //E置高电平
  87.          _nop_();
  88.          _nop_();
  89.          _nop_();
  90.          _nop_();               //空操作四个机器周期,给硬件反应时间
  91.           E=0;                  //当E由高电平跳变成低电平时,液晶模块开始执行命令
  92. }
  93. /*****************************************************
  94. 函数功能:指定字符显示的实际地址
  95. 入口参数:x
  96. ***************************************************/
  97. void WriteAddress(unsigned char x)
  98. {
  99.      WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
  100. }
  101. /*****************************************************
  102. 函数功能:将数据(字符的标准ASCII码)写入液晶模块
  103. 入口参数:y(为字符常量)
  104. ***************************************************/
  105. void WriteData(unsigned char y)
  106. {
  107.     while(BusyTest()==1);  
  108.           RS=1;           //RS为高电平,RW为低电平时,可以写入数据
  109.           RW=0;
  110.           E=0;            //E置低电平(根据表8-6,写指令时,E为高脉冲,
  111.                        // 就是让E从0到1发生正跳变,所以应先置"0"
  112.           P0=y;           //将数据送入P0口,即将数据写入液晶模块
  113.           _nop_();
  114.           _nop_();
  115.            _nop_();
  116.      _nop_();       //空操作四个机器周期,给硬件反应时间
  117.           E=1;          //E置高电平
  118.           _nop_();
  119.           _nop_();
  120.           _nop_();
  121.          _nop_();        //空操作四个机器周期,给硬件反应时间
  122.          E=0;            //当E由高电平跳变成低电平时,液晶模块开始执行命令
  123. }
  124. /*****************************************************
  125. 函数功能:对LCD的显示模式进行初始化设置
  126. ***************************************************/
  127. void LcdInitiate(void)
  128. {
  129.    delay(15);             //延时15ms,首次写指令时应给LCD一段较长的反应时间
  130.    WriteInstruction(0x38);  //显示模式设置:16×2显示,5×7点阵,8位数据接口
  131.         delay(5);               //延时5ms ,给硬件一点反应时间
  132.    WriteInstruction(0x38);
  133.         delay(5);
  134.         WriteInstruction(0x38); //连续三次,确保初始化成功
  135.         delay(5);
  136.         WriteInstruction(0x0c);  //显示模式设置:显示开,无光标,光标不闪烁
  137.         delay(5);
  138.         WriteInstruction(0x06);  //显示模式设置:光标右移,字符不移
  139.         delay(5);
  140.         WriteInstruction(0x01);  //清屏幕指令,将以前的显示内容清除
  141.         delay(5);
  142. }
  143. void DisplayA()
  144. {
  145.   unsigned char i,j;
  146.    i=A/10;
  147.    //计算设定值的十位
  148.         j=A%10;                //计算设定值的个位
  149.    WriteAddress(0x04);   //在第二行从第三位开始写数据
  150.         WriteData(digit[i]);  //将设定值的十位写入LCD
  151.         WriteData(digit[j]);  //将设定值的个位写入LCD
  152. }   








  153. void main(void)   // 主程序
  154. {  uint distance_data,a,b;
  155.    uchar CONT_1;  
  156.     LcdInitiate();         //调用LCD初始化函数  
  157.    delay(10);             //延时10ms,给硬件一点反应时间

  158.    i=0;

  159.    flag=0;
  160.         Tx=0;       //首先拉低脉冲输入引脚
  161.         TMOD=0x10;    //定时器0,定时器1,16位工作方式
  162. //        TR0=1;             //启动定时器0
  163.    IT1=0;        //由高电平变低电平,触发外部中断
  164.         //ET0=1;        //打开定时器0中断
  165.         EX1=0;        //关闭外部中断
  166.         EA=1;         //打开总中断0        

  167.         
  168. while(1)         //程序循环
  169.         {{if(k2==0)
  170. {delay1ms();
  171.         if(A<0)
  172. A=99;
  173. A++;}
  174. if(k3==0)
  175. {delay1ms();
  176.         if(A>99)
  177.                 A=0;
  178. A--;}
  179. B=A;
  180. WriteAddress(0x00);   
  181. WriteData('S');  
  182. WriteData('E');                          
  183. WriteData('T');  
  184. WriteData(':');
  185. DisplayA();
  186. WriteData('C');
  187. WriteData('M');
  188. delay(10);}
  189.          WriteAddress(0x43);   
  190. WriteData('J');  
  191. WriteData('U');                          
  192. WriteData('L');
  193.         WriteData('I');
  194.         WriteData(':');
  195.         WriteData(digit[bai]);
  196.         WriteData(digit[shi]);
  197. WriteData('.');
  198. WriteData(digit[ge]);

  199. WriteData('C');
  200. WriteData('M');  
  201. if(tdata==B)
  202. {WriteAddress(0x0c);      
  203. WriteData('S');  
  204. WriteData('T');
  205. WriteData('O');
  206. WriteData('P');
  207. ZZ=0;
  208. FZ=0;}
  209. else if(tdata>B)
  210. {WriteAddress(0x0c);      
  211. WriteData('F');  
  212. WriteData('X');
  213. WriteData('X');
  214. WriteData('Z');
  215. ZZ=0;
  216. FZ=1;}
  217. else
  218. {WriteAddress(0x0c);      
  219. WriteData('Z');  
  220. WriteData('X');
  221. WriteData('X');
  222. WriteData('Z');
  223. ZZ=1;
  224. FZ=0;}
  225.   EA=0;
  226.              Tx=1;
  227.         delay_20us();
  228.         Tx=0;         //产生一个20us的脉冲,在Tx引脚  
  229.         while(Rx==0); //等待Rx回波引脚变高电平
  230.              succeed_flag=0; //清测量成功标志
  231.              EX1=1;          //打开外部中断
  232.                    TH1=0;          //定时器1清零
  233.         TL1=0;          //定时器1清零
  234.              TF1=0;          //
  235.         TR1=1;          //启动定时器1
  236.    EA=1;

  237.       while(TH1 < 30);//等待测量的结果,周期65.535毫秒(可用中断实现)  
  238.                   TR1=0;          //关闭定时器1
  239.         EX1=0;          //关闭外部中断

  240.     if(succeed_flag==1)
  241.              {         
  242.                    distance_data=outcomeH;                //测量结果的高8位
  243.            distance_data<<=8;                   //放入16位的高8位
  244.                      distance_data=distance_data|outcomeL;//与低8位合并成为16位结果数据
  245.             distance_data*=12;                  //因为定时器默认为12分频
  246.            distance_data/=58;                   //微秒的单位除以58等于厘米
  247.          }                                      //为什么除以58等于厘米,  Y米=(X秒*344)/2
  248.                                                                // X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
  249.     if(succeed_flag==0)
  250.                    {
  251.             distance_data=0;                    //没有回波则清零

  252.            }

  253.            distance[i]=distance_data; //将测量结果的数据放入缓冲区
  254.             i++;
  255.                      if(i==3)
  256.                        {
  257.                          distance_data=(distance[0]+distance[1]+distance[2]+distance[3])/4;

  258.             pai_xu();
  259.              distance_data=distance[1];


  260.            a=distance_data;
  261.        if(b==a) CONT_1=0;
  262.        if(b!=a) CONT_1++;
  263.        if(CONT_1>=3)
  264.                    { CONT_1=0;
  265.                           b=a;
  266.                           conversion(b);
  267.                         }      
  268.                            i=0;
  269.                            }            
  270.          }
  271. }
  272. //***************************************************************
  273. //外部中断0,用做判断回波电平
  274. INTO_()  interrupt 2   // 外部中断是2号
  275. {   
  276.      outcomeH =TH1;    //取出定时器的值
  277.      outcomeL =TL1;    //取出定时器的值
  278.      succeed_flag=1;   //至成功测量的标志
  279.      EX1=0;            //关闭外部中断
  280.   }
  281. //****************************************************************
  282. //定时器0中断,用做显示
  283. timer0() interrupt 1  // 定时器0中断是1号
  284.    {
  285.          // TH0=0xfd; //写入定时器0初始值
  286.         // TL0=0x77;                 
  287.         
  288.    }

  289. //显示数据转换程序
  290. void conversion(uint temp_data)  
  291. {  
  292.     uchar ge_data,shi_data,bai_data ;
  293.          
  294.     bai_data=temp_data/100 ;
  295.     temp_data=temp_data%100;   //取余运算
  296.     shi_data=temp_data/10 ;
  297.     temp_data=temp_data%10;   //取余运算
  298.     ge_data=temp_data;

  299.     //bai_data=SEG7[bai_data];
  300.     //shi_data=SEG7[shi_data]&0x7f;
  301.     //ge_data =SEG7[ge_data];

  302.     EA=0;
  303.     bai = bai_data;
  304.     shi = shi_data;
  305.     ge  = ge_data ;
  306.          tdata=bai*10+shi;
  307.          EA=1;
  308. }
  309. //******************************************************************


  310. void delay_20us()
  311. {  uchar bt ;
  312.     for(bt=0;bt<60;bt++);
  313. }
  314.    void pai_xu()
  315.   {  uint t;
  316.   if (distance[0]>distance[1])
  317.     {t=distance[0];distance[0]=distance[1];distance[1]=t;}
  318.   if(distance[0]>distance[2])
  319.     {t=distance[2];distance[2]=distance[0];distance[0]=t;}
  320.   if(distance[1]>distance[2])
  321.     {t=distance[1];distance[1]=distance[2];distance[2]=t;}  
  322.     }
复制代码


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

使用道具 举报

沙发
ID:108510 发表于 2017-7-12 15:45 | 只看该作者
已解决
回复

使用道具 举报

板凳
ID:493518 发表于 2019-4-14 15:42 | 只看该作者

楼主怎么解决的,可以分享一下这份资料吗
回复

使用道具 举报

地板
ID:523121 发表于 2019-4-27 18:07 来自手机 | 只看该作者
1003 发表于 2017-7-12 15:45
已解决

还有这个资料没啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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