找回密码
 立即注册

QQ登录

只需一步,快速开始

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

诚心请问下前辈关于循迹小车程序PWM变速问题

[复制链接]
ID:235166 发表于 2017-9-24 11:24 | 显示全部楼层 |阅读模式
#include <REG52.h>
#define uchar unsigned char
#define uint unsigned int
unsigned char zkb1=0 ; //左右占空比1、2
unsigned char zkb2=0 ;
unsigned char i,j;
sbit IN1=P1^0;
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;
sbit IN5=P3^0;
sbit IN6=P3^1;
sbit IN7=P1^6;
sbit IN8=P1^7;//驱动轮子口
sbit left_red1=P0^0;//红外探测
sbit left_red2=P0^1;
sbit right_red1=P0^4;
sbit right_red2=P0^5;
sbit ENA=P2^7; //我用的是四轮循迹小车,分别设置了四个循迹小车
sbit ENB=P2^6;
sbit ENC=P2^5; //
sbit END=P2^4;
void delay(uint z)//延时函数
{
   uchar i;
while(z--)
{
  for(i=0;i<121;i++);
}
}
void init()//定义一个初始化函数
{
  left_red1=1;//小车正对黑线时红外感应灯的状态
  left_red2=0;
  right_red1=0;
  right_red2=1;
  TMOD=0X01;
  TH0=(65536-100)/256;
  TL0=(65536-100)%256;
  EA=1;
  ET0=1;
  TR0=1;
  ENA=1;
  ENB=1;
  ENC=1;
  END=1;
}
void time0(void) interrupt 1//中断函数
{
  i++;
  j++;
  if(i<=zkb1)
  {
   ENA=1;
   ENB=1;
  }
  else
  {
   ENA=0;
   ENB=0;
  }
  if(i==40)//i到40us就开始下一个循环
  {
   ENA=~ENA;
   ENB=~ENB;
   i=0;
  }
    if(j<=zkb2)
  {
   ENC=1;
   END=1;
  }
  else
  {
   ENC=0;
   END=0;
  }
  if(j==40)
  {
   ENC=~ENC;
   END=~END;
   i=0;
  }
  TH0=(65536-100)/256;
  TL0=(65536-100)%256;
}
void straight()//直走
{
  zkb1=39;
  zkb2=39;
  IN1=1;IN2=0;
  IN3=0;IN4=1;//左边两个轮子
  IN5=0;IN6=1;
  IN7=0;IN8=1;//右边两个轮子
}
void turn_left() //左转
{
  zkb1=5;
  zkb2=39;
  IN1=0;IN2=1;
  IN3=1;IN4=0;
  IN5=0;IN6=1;
  IN7=0;IN8=1;
}
void turn_right() //右转
{
  zkb1=39;
  zkb2=5;
  IN1=1;IN2=0;
  IN3=0;IN4=1;
  IN5=1;IN6=0;
  IN7=1;IN8=0;
}
void infrared() //开始循迹
{
  if(left_red1==1&&left_red2==1&&right_red1==1&&right_red2==1)//直走1
  {
   straight();
  }  
  if(left_red1==1&&left_red2==0&&right_red1==1&&right_red2==1)//直走2 防止左右摇晃
  {
   straight();
  }  
   if(left_red1==1&&left_red2==1&&right_red1==0&&right_red2==1)//直走3 防止左右摇晃
  {
   straight();
  }  
  if(left_red1==0&&left_red2==1&&right_red1==1&&right_red2==1)//左转
  {
   turn_left();
  }  
  if(left_red1==0&&left_red2==0&&right_red1==1&&right_red2==1)//左转2
  {
   turn_left();
  }  
  if(left_red1==1&&left_red2==1&&right_red1==1&&right_red2==0)//右转
  {
   turn_right();
  }  
  if(left_red1==0&&left_red2==0&&right_red1==0&&right_red2==0)//右转2
  {
   turn_right();
  }  
  
}
  void main(void)//定义主函数,不断循环
  {
   init();
   delay(100);
   while(1)
   {
    infrared();
   }
  }
void int0(void) interrupt 0
  {
  }

我写了之后没有错误,但就是没反应,小车的连线我觉得也没有问题。
之前我没用PWM来写了一个程序,轮子可以控制,但速度太快,对于大弯道会直接冲出去。
如果前辈们有什么好的建议(可改进等)尽可提出来,我定会虚心接纳、学习。
回复

使用道具 举报

ID:231376 发表于 2017-9-24 18:58 | 显示全部楼层
直接用PID算法
回复

使用道具 举报

ID:164602 发表于 2017-9-25 09:57 | 显示全部楼层
我有别人的程序,我使用过,没问题,你可以试试,也可以根据这个程序,学习、修改自己的程序。
头文件bst_car.h
#ifndef __BSTCAR_H__
#define __BSTCAR_H__

//定义小车驱动模块输入IO口
sbit IN1=P1^2;
sbit IN2=P1^3;
sbit IN3=P1^6;
sbit IN4=P1^7;
sbit EN1=P1^4;
sbit EN2=P1^5;

//定义按键
sbit K4=P3^7;
//sbit K3=P3^6;

//蜂鸣器驱动口定义
sbit FM=P2^3;

//循迹LED指示灯定义
sbit Left_1_led=P3^3;         //左循迹红外传感器      
sbit Right_1_led=P3^2;         //右循迹红外传感器  

//避障LED指示灯定义  
//sbit Left_2_led=P3^4;         //左避障红外传感器  
//sbit Right_2_led=P3^5;         //右避障红外传感器  


#define Left_moto_go      {IN1=0,IN2=1;}   //左电机向前走
//#define Left_moto_back    {IN1=1,IN2=0;}   //左边电机向后转
#define Left_moto_Stop    {EN1=0;IN1=0,IN2=0;}         //左边电机停转                     
#define Right_moto_go     {IN3=1,IN4=0;}   //右边电机向前走
//#define Right_moto_back   {IN3=0,IN4=1;}   //右边电机向后走
#define Right_moto_Stop   {EN2=0;IN3=0,IN4=0;}               //右边电机停转  
#endif






主程序main.c
//按下K4按键,1秒左右启电小车
//按下复位健可以停止小车       
//注意程序只做参考之用,要达到最理想的寻迹效果,还需要同学们细心调试。

#include <reg52.h>          
#include "bst_car.h"       

unsigned char pwm_val_left  =0;
unsigned char pwm_val_right =0;
unsigned char push_val_left =5;
unsigned char push_val_right=5;
                                                       
bit Right_PWM_ON=1;               
bit Left_PWM_ON =1;                       

void delay(unsigned int xms)                               
{
    unsigned int i,j;
        for(i=xms;i>0;i--)                      //i=xms即延时约xms毫秒
    for(j=112;j>0;j--);
}

//前进
void run(void)
{
    push_val_left=6;         //速度调节变量 0-20。。。0最小,20最大
        push_val_right=6;
        Left_moto_go ;
        Right_moto_go ;
}

//左转
void leftrun(void)
{         
     push_val_left=5;
         push_val_right=5;
         Right_moto_go ;
     Left_moto_Stop ;
}

//右转
void  rightrun(void)
{
         push_val_left=5;
         push_val_right=5;
     Left_moto_go  ;  
         Right_moto_Stop   ;
}

//停止
void  stop(void)
{
         Left_moto_Stop ;
         Right_moto_Stop   ;
}

void pwm_out_left_moto(void)
{  
     if(Left_PWM_ON)
     {
          if(pwm_val_left<=push_val_left)
              {
                   EN1=1;
              }
              else
              {
                   EN1=0;
          }
          if(pwm_val_left>=20)
              pwm_val_left=0;
     }
     else   
     {
          EN1=0;   //若未开启PWM则EN1=0 左电机 停止
     }
}

void pwm_out_right_moto(void)
{
    if(Right_PWM_ON)
    {
        if(pwm_val_right<=push_val_right)       
            {
                EN2=1;                                                
        }
            else
            {
                EN2=0;
        }
            if(pwm_val_right>=20)
            pwm_val_right=0;
    }
    else   
    {
        EN2=0;       
    }
}


//TIMER0中断服务子函数产生PWM信号
void timer0()interrupt 1 using 2
{
     TH0=0XFC;          //1Ms定时
         TL0=0X66;
         pwm_val_left++;
         pwm_val_right++;
         pwm_out_left_moto();
         pwm_out_right_moto();
}       

void keyscan(void)              //按键扫描函数
{
    A:    if(K4==0)               
                {
                    delay(10);               
                        if(K4==0)               
                         {
                            FM=0;            
                            while(K4==0);       
                            FM=1;         
                          }
                    else
                     {
                       goto A;     
                      }
                }
                else
                {
                  goto A;           
                }
}


void main(void)
{       
    P1=0X00;  
    keyscan();       
        delay(1000);

        TMOD=0X01;
    TH0= 0XFC;
    TL0= 0X66;
    TR0= 1;
    ET0= 1;
        EA = 1;         


        while(1)       
        {
        if(Left_1_led==0&&Right_1_led==0)
            run();
        else if(Left_1_led==1&&Right_1_led==0)         
                        {
                             leftrun();                     
                        }                          
                else if(Right_1_led==1&&Left_1_led==0)               
                        {          
                                 rightrun();                 
                    }
                else
                        stop();         
         }
}




评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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