找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1211|回复: 0
收起左侧

求大佬看下单片机程序的问题,在实物中小车不动

[复制链接]
回帖奖励 2 黑币 回复本帖可获得 2 黑币奖励! 每人限 1 次
ID:728262 发表于 2020-5-23 22:50 | 显示全部楼层 |阅读模式
  1. <避障小车的问题,在实物中小车不动
  2. #include<reg52.h>                                          //此文件中定义了单片机的一些特殊功能寄存器
  3. #include"lcd.h"
  4. #include<intrins.h>
  5. #define uchar unsigned char                          //无符号字符型 宏定义        变量范围0~255
  6. #define uint unsigned int                          //无符号整型 宏定义        变量范围0~65535
  7. /***************超声波**I/O口******************/        
  8. sbit Trig = P2^3;                     //超声波测距模块Trig                                
  9. sbit Echo = P2^4;                                          //超声波测距模块Echo
  10. /*****************蜂鸣器******************/
  11. sbit beep = P2^7;                                          //蜂鸣器
  12. /*****************舵机******************/
  13. sbit SG_PWM = P3^7;                                          //舵机
  14. /****************电机驱动**IO口******************/
  15. /*使能端*/
  16. sbit ENA = P2^5;                //左下电机pwm信号端
  17. sbit ENB = P2^6;                //右下电机pwm信号端
  18. sbit ENC = P3^0;                //左上电机pwm信号端
  19. sbit END = P3^1;                //右上电机pwm信号端
  20. /*电机口*/
  21. sbit IN1 = P1^0;        
  22. sbit IN2 = P1^1;
  23. sbit IN3 = P1^2;        
  24. sbit IN4 = P1^3;
  25. sbit IN5 = P1^4;        
  26. sbit IN6 = P1^5;
  27. sbit IN7 = P1^6;        
  28. sbit IN8 = P1^7;
  29. /***************定义全局变量******************/
  30. static unsigned char DisNum = 0;         //显示用指针
  31.            unsigned char table[]="Distance:";  
  32.        unsigned char code ASCII[13] = {'0','1','2','3','4','5','6','7','8','9','.','-','M',};                  
  33.        unsigned int  time=0;                        //用于存放定时器时间的值
  34.        unsigned long S=0;                                //用于存放距离的值
  35.            unsigned long S1=0;
  36.            unsigned long S2=0;
  37.            unsigned long S3=0;
  38.            unsigned int timer=10000;                         //延时基准变量
  39.        bit      flag =0;                                //超声波超出量程溢出标志位      
  40.            unsigned char disbuff[4] = { 0,0,0,0,};          //用于存放距离的值0.1mm、mm、cm和m的值
  41.            unsigned char pwm_val_left1 = 0;        //左下电机变量定义
  42.            unsigned char pwm_val_right1 =0;               //右下电机变量定义
  43.            unsigned char pwm_val_left2 = 0;               //左上电机变量定义
  44.            unsigned char pwm_val_right2 = 0;           //右下电机变量定义
  45.            unsigned char push_val_left1 = 0;       //左下电机占空比N/20
  46.            unsigned char push_val_right1 =0;       //右下电机占空比N/20
  47.            unsigned char push_val_left2 = 0;           //左上电机占空比N/20
  48.            unsigned char push_val_right2 = 0;           //右下电机占空比N/20
  49.            unsigned char count=0;                       //0.2ms次数标识   
  50.        unsigned char PWM_count=5;                   //舵机归中
  51. /******************************************************************************
  52. * 函 数 名         : Delay1ms
  53. * 函数功能                   : 延时函数,延时1ms
  54. *******************************************************************************/
  55. void Delay1ms(uint j)
  56. {
  57.     uchar k;        
  58.         while(j--)                          
  59.         {                  
  60.            for(k = 120; k > 0; k--);
  61.         }                                   
  62. }
  63. /******************************************************************************
  64. * 函 数 名         : feng
  65. * 函数功能                   : 报警函数
  66. *******************************************************************************/
  67. void feng()
  68. {
  69.         if(S<=40)
  70.           {
  71.             beep=~beep;
  72.             Delay1ms(50);
  73.           }
  74.         else
  75.                 beep=1;
  76. }               
  77. void StartModule()                          //启动模块
  78. {
  79.           Trig=1;                                             //启动一次模块
  80.           _nop_();
  81.           _nop_();
  82.           _nop_();
  83.           _nop_();
  84.           _nop_();
  85.           _nop_();
  86.           _nop_();
  87.           _nop_();
  88.           _nop_();
  89.           _nop_();
  90.           _nop_();
  91.           _nop_();
  92.           _nop_();
  93.           _nop_();
  94.           _nop_();
  95.           _nop_();
  96.           _nop_();
  97.           _nop_();
  98.           _nop_();
  99.           _nop_();
  100.           _nop_();
  101.           Trig=0;
  102. }
  103. //计算距离
  104. void Conut(void)                                          
  105.         {
  106.          TH0=0;
  107.          TL0=0;         
  108.          while(!Echo);                //当RX为零时等待
  109.          TR0=1;                            //开启计数
  110.          while(Echo);                        //当RX为1计数并等待
  111.          TR0=0;                                //关闭计数
  112.          time=TH0*256+TL0;
  113.          TH0=0;
  114.          TL0=0;
  115.         
  116.          S=(time*1.7)/100;     //算出来是CM
  117.          if((S>=450)||flag==1) //超出测量范围显示“-”
  118.          {         
  119.           flag=0;
  120.          
  121.           DisplayOneChar(10, 0, ASCII[11]);
  122.           DisplayOneChar(11, 0, ASCII[10]);        //显示点
  123.           DisplayOneChar(12, 0, ASCII[11]);
  124.           DisplayOneChar(13, 0, ASCII[11]);
  125.           DisplayOneChar(14, 0, ASCII[12]);        //显示M
  126.          }
  127.          else
  128.          {
  129.           disbuff[0]=S%1000/100;
  130.           disbuff[1]=S%1000%100/10;
  131.           disbuff[2]=S%1000%10 %10;
  132.           DisplayOneChar(10, 0, ASCII[disbuff[0]]);
  133.           DisplayOneChar(11, 0, ASCII[10]);        //显示点
  134.           DisplayOneChar(12, 0, ASCII[disbuff[1]]);
  135.           DisplayOneChar(13, 0, ASCII[disbuff[2]]);
  136.           DisplayOneChar(14, 0, ASCII[12]);        //显示M
  137.          }
  138.         }
  139. void Timer0() interrupt 1                          //T0中断用来计数器溢出,超过测距范围
  140. {
  141.     flag=1;                                                         //中断溢出标志
  142. }
  143. void run(void)                                                //前进
  144. {
  145.           push_val_left1 = 10;                //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
  146.           push_val_right1 = 10;      
  147.           push_val_left2 = 10;         
  148.           push_val_right2 = 10;
  149.           IN1 = 1;
  150.           IN2 = 0;
  151.           IN3 = 1;
  152.           IN4 = 0;
  153.           IN5 = 1;
  154.           IN6 = 0;
  155.           IN7 = 1;
  156.           IN8 = 0;
  157. }
  158. void backrun(void)                                                //后退
  159. {
  160.           push_val_left1 = 8;                       //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
  161.           push_val_right1 = 8;      
  162.           push_val_left2 = 8;         
  163.           push_val_right2 = 8;
  164.           IN1 = 0;
  165.           IN2 = 1;
  166.           IN3 = 0;
  167.           IN4 = 1;
  168.           IN5 = 0;
  169.           IN6 = 1;
  170.           IN7 = 0;
  171.           IN8 = 1;
  172. }
  173. void leftrun(void)                                                //左转
  174. {
  175.           push_val_left1 = 7;                       //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
  176.           push_val_right1 = 7;      
  177.           push_val_left2 = 7;         
  178.           push_val_right2 = 7;
  179.           IN1 = 0;
  180.           IN2 = 0;
  181.           IN3 = 1;
  182.           IN4 = 0;
  183.           IN5 = 0;
  184.           IN6 = 0;
  185.           IN7 = 1;
  186.           IN8 = 0;
  187. }
  188. void rightrun(void)                                                //右转
  189. {
  190.           push_val_left1 = 7;                       //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
  191.           push_val_right1 = 7;      
  192.           push_val_left2 = 7;         
  193.           push_val_right2 = 7;
  194.           IN1 = 1;
  195.           IN2 = 0;
  196.           IN3 = 0;
  197.           IN4 = 0;
  198.           IN5 = 1;
  199.           IN6 = 0;
  200.           IN7 = 0;
  201.           IN8 = 0;
  202. }
  203. void stop(void)                                                //停止
  204. {
  205.           IN1 = 0;
  206.           IN2 = 0;
  207.           IN3 = 0;
  208.           IN4 = 0;
  209.           IN5 = 0;
  210.           IN6 = 0;
  211.           IN7 = 0;
  212.           IN8 = 0;
  213. }
  214. //pwm控制电机速度
  215. void pwm_out_left1_moto(void)                                   //左下电机
  216. {
  217.    if(pwm_val_left1<=push_val_left1)
  218.                ENA=1;
  219.    else
  220.                   ENA=0;
  221.    if(pwm_val_left1>=20)
  222.                  pwm_val_left1=0;
  223.    else
  224.                   ENA=0;
  225. }
  226. void pwm_out_right1_moto(void)                                   //右下电机
  227. {
  228.    if(pwm_val_right1<=push_val_right1)
  229.                ENB=1;
  230.    else
  231.                   ENB=0;
  232.    if(pwm_val_right1>=20)
  233.                  pwm_val_right1=0;
  234.    else
  235.                   ENB=0;
  236. }
  237. void pwm_out_left2_moto(void)                                   //左上电机
  238. {
  239.    if(pwm_val_left2<=push_val_left2)
  240.                ENC=1;
  241.    else
  242.                   ENC=0;
  243.    if(pwm_val_left2>=20)
  244.                  pwm_val_left2=0;
  245.    else
  246.                   ENC=0;
  247. }
  248. void pwm_out_right2_moto(void)                                   //右上电机
  249. {
  250.    if(pwm_val_right2<=push_val_right2)
  251.                END=1;
  252.    else
  253.                   END=0;
  254.    if(pwm_val_right2>=20)
  255.                  pwm_val_right2=0;
  256.    else
  257.                   END=0;
  258. }
  259. void timer1 () interrupt 3                           //中断产生pwm信号
  260. {
  261.   TH1=0xFC;
  262.   TL1=0x18;                                         //1ms延时
  263.   pwm_val_left1++;
  264.   pwm_val_right1++;
  265.   pwm_val_left2++;
  266.   pwm_val_right2++;

  267.   pwm_out_left1_moto();
  268.   pwm_out_right1_moto();
  269.   pwm_out_left2_moto();
  270.   pwm_out_right2_moto();
  271. }
  272. //舵机控制方向函数
  273. void COMM(void)
  274. {
  275.           count=1;                                                        //舵机向左转90度
  276.           Delay1ms(1000);                                        //延时1000ms让舵机转到位置
  277.           StartModule();                                                //启动测距        
  278.           Conut();                                                        
  279.           S2=S;                                                                        //得到左边距离

  280.           count=9;                                                        //舵机右转
  281.           Delay1ms(1000);                                            //延时1000ms让舵机转到位置
  282.           StartModule();                                                //启动测距
  283.           Conut();                                                               
  284.           S3=S;                                                                        //得到右边距离

  285.           count=5;                                                        //舵机归中
  286.           Delay1ms(1000);                                            //延时1000ms让舵机转到位置
  287.           StartModule();                                                //启动测距
  288.           Conut();
  289.           S1=S;                                                                        //得到中间距离

  290.           if((S2<10)||(S3<10))                                        //只要左右各有距离小于10CM小车后退
  291.           {
  292.                    backrun();
  293.                  Delay1ms(1000);
  294.           }

  295.           if(S2>S3)                                                                 //车的左边比车的右边距离小右转
  296.           {
  297.                    rightrun();
  298.                  Delay1ms(1000);
  299.           }
  300.           else                                                                         //车的左边比车的右边距离大 左转
  301.           {
  302.                    leftrun();
  303.                  Delay1ms(1000);
  304.           }
  305. }
  306. void Timer2() interrupt 5
  307. {
  308.         TF2=0;
  309.         TH2=(65536-200)>>8;
  310.         TL2=(65536-200);
  311.         count=count+1;
  312.             
  313.         if(count >100)   
  314.         {
  315.    
  316.                 count = 0;
  317.         }        
  318.         if(count<=compare)  
  319.         {
  320.         SG_PWM=1;   
  321.         }
  322.     else
  323.     {
  324.             SG_PWM=0;  
  325.     }                          //次数始终保持为40即保持周期为20ms
  326. }
  327. /***************初始化定时器************/
  328. void init_T0()
  329. {
  330.      TMOD=0x01;                   //设T0为方式1,GATE=1;
  331.          TH0=0;
  332.          TL0=0;         
  333.          ET0=1;             //允许T0中断
  334.          EA=1;                           //开启总中断
  335. }
  336. void init_T1()
  337. {
  338.      TMOD=0x11;                   //设T1为方式1,GATE=1;
  339.          TH1=0xFC;
  340.          TL1=0x18;          //1ms延时
  341.          ET1=1;             //允许T1中断
  342.          EA=1;                           //开启总中断
  343.          TR1=1;                        //t1开启及时
  344. }
  345. void init_T2()
  346. {

  347.      T2CON=0;
  348.          TH2=0xfe;
  349.          TL2=0x0c;          //0.5ms
  350.          ET2=1;             //允许T1中断
  351.          EA=1;                           //开启总中断
  352.          TR2=1;                           //t2开启及时
  353. }
  354. void main()
  355. {
  356.          init_T0();
  357.          init_T1();
  358.          init_T2();
  359.          
  360.          LcdInit();
  361.          LcdShowStr(0,0,table);                  
  362.          Delay1ms(5);
  363.          count=5;
  364.          while(1)
  365.          {                                 
  366.          StartModule();
  367.                  Conut();
  368.                  feng();
  369.                     if(S<=10)
  370.                 {
  371.                           stop();
  372.                           COMM();
  373.                 }
  374.                  else
  375.                 {
  376.                         run();
  377.                 }
  378.          }
  379. }   
复制代码


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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