巡线车程序(完整版,也是最先的版本)

#ifndef _Macro.h_
#define _Macro.h_   
#include <msp430x14x.h>
#include <intrinsics.h>
#define uchar unsigned char 
#define uint unsigned int
#define one 11.11
#define LMAX 1999
#define RMAX 3999
#define CPU_F ((double)8000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))

#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define PC 20  // 比例放大系数
#define IC 0    //积分放大系数
#define DC 85    //大系数
#define LEFTOUT    TACCR1
#define RIGHTOUT   TACCR2
#define SensorIn   P5IN
#define F          5000//5000hz
#define Period     (8000000/F)
#define EnableLeftPos       P3OUT|=BIT1
#define UnenableLeftPos     P3OUT&=~BIT1

#define EnableLeftNeg       P3OUT|=BIT0
#define UnenableLeftNeg     P3OUT&=~BIT0

#define EnableRightPos      P3OUT|=BIT2
#define UnenableRightPos    P3OUT&=~BIT2

#define EnableRightNeg      P3OUT|=BIT3
#define UnenableRightNeg    P3OUT&=~BIT3

#define Basic_Left  100//百分之八十
#define Basic_Right 100//Basic_Left
#define MAX        (100)
#define MIN        (-100)
#define foreward   1
#define backward   0
#define max_speed  100
#define min_speed  -100
#define key        0


#define left_1 1
#define left_2 2
#define left_3 3
#define left_4 4
#define left_5 5
#define left_6 6
#define left_7 7//右直角

#define right_1 -1
#define right_2 -2
#define right_3 -3
#define right_4 -4
#define right_5 -5
#define right_6 -6
#define right_7 -7//左直角
#endif 



#include "Macro.h"
#include "sensor.h"
void Motorstop()
{
  LEFTOUT=0;
  RIGHTOUT=0;
}
void MotorLeft(int speed,int direction)
{
  if(speed>max_speed)speed=max_speed;
  if(direction==backward)//反转
  {
    EnableLeftNeg;
    UnenableLeftPos;
  }
  else if(direction==foreward)//正转
  {
    EnableLeftPos;
    UnenableLeftNeg;
  }
  LEFTOUT=Period/100*speed;
}
void MotorRight(int speed,int direction)
{
  if(speed>max_speed)speed=max_speed;
  
  if(direction==backward)//反转
  {
    EnableRightNeg;
    UnenableRightPos;
  }
  else if(direction==foreward)//正转
  {
    EnableRightPos;
    UnenableRightNeg;
  }
  RIGHTOUT=Period/100*speed;
}
void MotorDrive(int PIDout)
{
  int speedleft,speedright;
  speedleft=Basic_Left+PIDout;
  speedright=Basic_Right-PIDout;
  
  if(speedleft<0)
    MotorLeft(speedleft,backward);//反转
  else MotorLeft(speedleft,foreward);//正转
  
  if(speedright<0)
    MotorRight(speedright,backward);//反转
  else MotorRight(speedright,foreward);//正转
}
void  Rangle(float angle)
{
 // TBCTL|=TBCLR;
  TBCCR1=LMAX+(unsigned int)(angle*one); 
}




//下面是小车的程序。。用定时器A来输出两路PWM波。
//选用输出模式7(首先输出高电平。在TAR=CCRX时,电平自动变低。这样可以输出任意占空比的PWM波)
//    传感器接在P5口,电机的驱动接在P3口。
#include "Macro.h"
#include "motor.h"
typedef struct p
{
  float  error_1;//上次的误差
  float sumerror;
}PID;
PID Pid;
PID *pid=&Pid;
uchar detection,sample=0,corner,k,flag,tt=0;
int weight1[]={-8,-5,-3,-2,0,2,3,5,8};//传感器的权值
float sensorin;
int num,tag=1;
void IO_inti()//io口初始化
{
  P1SEL|=BIT2+BIT3;//p1为定时器输出端。
  P1DIR|=BIT2+BIT3;//设置为输出模式。P5为传感器输入。
  P3DIR|=BIT0+BIT1+BIT2+BIT3+BIT4;//0,1,2,3,作为电机控制的输出端,其他的作为传感器的输入端
  P5DIR=0X00;//P5为传感器输入端。设置P5为输入端。普通IO口。
  P5SEL=0x00;
  
  
  P2DIR=0X00;//输入
  
  P2IE|=BIT3;
  P2IES|=BIT3;
  
  P6DIR=0XFF;//纯粹是为了调试用的。
  P6OUT=0X00;
  
}
void delay(int t)
{
  unsigned int i;
  while(t--)
  {
    i=65535;
    while(i--);
  }
}
void CLK_inti()//时钟初始化
{
  BCSCTL1=0X00;//打开XT2
  do{
    IFG1&=~OFIFG;
    for(int i=0x20;i>0;i--);
  }while((IFG1&OFIFG)==OFIFG);//如果起震失败。。继续起震。知道成功为止
  BCSCTL2=0X00;
  BCSCTL2|=SELM_2|SELS;//mclk,sMCLK的时钟源为XT2,0分频。
}

void PID_inti()//PID初始化 
{
  pid->error_1=0;
  pid->sumerror=0;
}

void PWM_inti()//PWM初始化
{
  TACTL|=TASSEL_2|ID_0|MC_1|TACLR;//时钟源采用SMCLK,增计数模式。清空TAR,0分频
  TACCR0=8000000/F;//0分频。所以Period=8000000/5000
  TACCTL1|=OUTMOD_7;//两个PWM输出口的输出模式。
  TACCTL2|=OUTMOD_7;//
  LEFTOUT=0;
  RIGHTOUT=0;
}

float abs(float a)
{
  return a<0?-a:a;
}

void timer_inti()//用定时器B1来确定采样周期
{
  TBCTL|=TBSSEL_2|CNTL_0|ID_3|MC_1|TBCLR;//定时器B:SMCLK,16位,8分频,增计数
  TBCCTL0|=CCIE;//使能timerb1的中断。
  TBCCR0=5000;//八分频,1MHz,5000表示5ms。
  _EINT();//打开总中断。
}
void num_inti()
{
  sensorin=0;
  num=0;
}
void inti()//总初始化函数
{
  PID_inti();
  CLK_inti();
  PWM_inti();
  IO_inti();
  timer_inti();
  num_inti();
}
float ReadSensor2()
{
  int state=0,i,num=0;
  float sum=0;
  static float output=0;
  state=P3IN&0X80;
  state<<=1;
  state|=P5IN;
  for(i=0;i<9;i++)
    if(((1<<i)&state)==0)
    {
      sum+=weight1[i];
      num++;
    }   
   if(num>0&&num<7)//不是全白或者全黑
   {
     corner=0;
     if(num>=3)
     {
       corner=1;
       if(sum>0)
         output=10;
       else output=-10;
       return output;
     }
     output=sum/num;
   }
   else if(num>=7)//如果是全黑。
   {
     flag++;
     return output=0;
   }
   return output;
}
void Avoid(int time,int lspeed,int ldirection,int rspeed,int rdirection)
{
  int state=0;
  MotorLeft(lspeed,ldirection);//左转出去,n
  delay(time);
  MotorRight(lspeed,ldirection);
  MotorLeft(rspeed,rdirection);
  do{//右转,直到传感器压线。
  state=P3IN&0X80;
  state<<=1;
  state|=P5IN;
  }while(state==0X1FF);
  PID_inti();//PID初始化
}
int  PIDCal(float error)//PID计算。位置式。
{
  float output,derror;
  
    pid->sumerror+=error;
  
  derror=(error-pid->error_1);
  
  output=error*PC+derror*DC;
  
  pid->error_1=error;
  return (int)(output+0.5);
}
void main( void )
{
  WDTCTL=WDTHOLD+WDTPW;//close the watch dog;
  inti();
  sample=0;
  corner=0;
  flag=0;
  detection=0;
  while(1)
  {
    if(sample)
    {
      sensorin=ReadSensor2();
      if(flag==1)//下坡,用定时器定时。到坡底后减速,只有第一次扫到黑线后才要减速。
      {
       // P6OUT=0X81;
        WDTCTL=(WDTPW+WDTTMSEL+WDTCNTCL);
        IE1|=WDTIE;
        flag++;
        continue;
      }
      if(corner)//如果是直角,
      {
        int state=0;
        MotorLeft(100,1);//向前冲一段时间,然后再转。避免误判
        MotorRight(100,1);
	delay_ms(20);

        if(sensorin>0)//如果是右直角
        {
            MotorLeft(100,1);
            MotorRight(30,0);
         }
         else//如果是左直角
         {
            MotorRight(100,1);
             MotorLeft(30,0); 
         }
          do
          {
            state=0;
            state=P3IN&0X80;
            state<<=1;
            state|=P5IN;     
          }while(state==0x1ff);
          continue;
        }
      MotorDrive(PIDCal(sensorin));
      sample=0;
    }
    else if(!(P2IN&0X10)&&!detection)//壁障
    {
      detection=1;
      P6OUT=0XF0;
      MotorLeft(100,0);
      MotorRight(100,0);
      delay_ms(50);
      if(pid->sumerror<0)
      Avoid(5,60,0,100,1);//先左转,再右转
      else Avoid(5,100,1,60,0);//先右转,再左转
    }
  }
}
#pragma vector=TIMERB0_VECTOR
__interrupt void TimerB()//控制采样周期,大概10ms,中断正常。。
{
  sample=1;
}
#pragma vector=PORT2_VECTOR//用外部中断来判断并且处理避障
__interrupt void Outside()//最后的抓取。用定时器B才给舵机输出PWM波
{
  if(P2IFG&BIT3)
  {
    P2IFG&=~BIT3;
  //  P6OUT=0X07;
    TBCTL|=TBSSEL_2|CNTL_0|ID_3|MC_1|TBCLR|TBIE;//定时器B:SMCLK,16位,4分频,增计数
    TBCCR0=39999;//0分频。所以Period=8000000/500=16000
    TBCCTL1|=OUTMOD_7;//两个PWM输出口的输出模式。
    TBCCR1=0;
    P4DIR|=BIT1;
    P4SEL|=BIT1;
    MotorLeft(0,1);//停止
    MotorRight(0,1);
    delay_ms(50);//延迟
    Rangle(0);//夹住东西
    delay_ms(300);
    MotorLeft(100,0);//后退
    MotorRight(100,0);
    delay_ms(200);//延迟
    MotorLeft(0,0);
    MotorRight(0,0);
    while(1);//死循环,结束。
  }
}
#pragma vector=WDT_VECTOR
__interrupt void wdtch()
{
  static int xx=0;
  if(++xx==300)
  {
  //  P6OUT=0x01;
    MotorLeft(100,0);
    MotorRight(100,0);
    delay_ms(160);
    WDTCTL=WDTHOLD+WDTPW;
    IE1&=~WDTIE;
    xx=0;
    tag=0;
  }
}


  • 8
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
mbot机器⼈巡线程序_mBot机器⼈编程——⽤机器⼈的逻辑思 考问题 mBot机器⼈编程 ——⽤机器⼈的逻辑思考问题 ⽂/陈林 提到机器⼈,想必⼤家都不会陌⽣。但如果问到什么是机器⼈时,似乎⼼中的答案并不是那么的确切了,甚⾄不知道如何回答这个问题。如 果你也对什么是机器⼈这个问题感到⽆从回答的话,那就对了,因为国际上并未有⼀个准确的定义。 什么是机器⼈? 如果你尝试去百度,你会得到:机器⼈(Robot)是⼀种能够半⾃主或全⾃主⼯作的智能机器。⽽你查阅辞海时,⼜能得到:⼀种可以接受感 应到周围变化及输⼊的机器,通常具有某种程度的⼈造智慧。⽽维基百科⾥描述的是:机器⼈包括⼀切模拟⼈类⾏为或思想与模拟其他⽣物 的机械。因此,每次课我都会⿎励孩⼦们尝试为⾃⼰所理解的机器⼈下⼀个定义。这次我也收获到了很多不同的答案,有认为机器⼈是能独 ⽴完成某⼀具体事情的机械装置,有认为机器⼈是能协助⼈完成⼯作的机器,也有同学认为机器⼈就是拓展⼈类某⼀能⼒的机械。 你为什么学习机器⼈? 机器⼈已经逐渐⾛⼊了我们的⽣活,为⼈们带来了巨⼤的便利,我们⼏乎可以预⾔,机器终将取代我们绝⼤部分的⼯作,为⼈们的⽣活带来 巨⼤的便利,包括医疗、公共服务、家庭⽣活和教育等。对的,在教育中,机器⼈除了可以充当我们的AI⽼师,如"有道"提供的"AI"英 语教育等,还可以作为学习和⾛进机器⼈世界的⼀个教育载体。很少有⼀门学科能同时涵盖了数学、物理、计算机、机械⼯程等领域。因 此,学习机器⼈可以做到多学科的融合。 如何学习机器⼈? 说起机器⼈的历史,早在1959年,机器⼈之⽗约瑟夫·恩格尔伯格便制造了世界上第⼀台⽤于⼯业⽣产的可编程机器⼈。到如今,机器⼈ 已经可以做到如索菲亚那种对答如流,能做出超过60多种表情的机器⼈,⼜或者如同波⼠顿公司⽣产的能奔跑和空翻的敏捷机器⼈。机器 ⼈发展如此迅速,要想学习机器⼈,就需要知道最根本的底层逻辑。尽管拓展到智能硬件,我们依然可以这样说,绝⼤部分的智能机械实现 逻辑都是:接收信息 处理信息 输出控制指令。因此我们的课程中包含了⼤量的项⽬,并且每⼀个项⽬都是遵循这样的逻辑实现的。 ⽤mBot机器⼈来开启你的学习之旅! mBot是MakeBlock公司⽣产的⾯向⼴⼤青少年的教育机器⼈,它⽀持图形化编程和c语⾔代码编程。其机器⼈⼤脑主板集成了RGB彩灯、 红外接收模块、蜂鸣器、电源模块和红外发射模块等。且包含了直流电件、红外遥控、蓝⽛、超声波、灰度传感器等多种外设。⾮常适合我 们初学者作为第⼀个⼊门编程和机器⼈的教具。 我们都做了些什么项⽬? 机器⼈的组装 学习mBot机器⼈的第⼀步,就是组装你⾃⼰的机器⼈,从每⼀个模块的搭建到拧上第⼀个颗螺丝再到装上电池贴上标签。是的,每⼀步都 由你⾃⼰完成,让你的机器⼈赋予上特殊的意义。 轨迹⾏⾛ 组装好的你的机器⼈了!快来试试机器⼈能跑起来吗?⾛个正⽅形试试: 超声避障 超声波模块会发出40Khz的超声波,并在阈值时间内,等待返回波,当接收到返回波时,利⽤声⾳在空⽓中的传播速度便可以计算出障碍物 的距离,当距离过近时认定为有障碍,通过控制电机让机器⼈转开。对的,机器⼈编程中,程序的⼀⼤结构就是分⽀语句。对于机器⼈⽽ ⾔,有太多的不确定性了,需要通过假设的⽅法来将接收到的信息分情况处理。这也就是规则,当它掌握的规则越多,它就越智能。 机器⼈⾛迷宫 机器⼈⾛迷宫灵感来源于"电脑⿏"⾛迷宫竞赛,我们的机器⼈在超声波的帮助下,能够轻松分辨出前⽅是否有障碍物,这样也就⾜够⾛⼀ 个简单的迷宫了。同学们尝试了利⽤随机数实现在碰到墙壁时,随机左右转,防⽌陷⼊死循环。最后在多次尝试后,挑战成功! 循线机器⼈ 利⽤双灰度传感器,加上四条规则: 1. 左边看到⽩⾊右转(左偏了) 2. 右边看到⽩⾊左转 3. 两边都为⽩停⽌ 4. 两边都为⿊前进 是的,⼈类之所以聪明,就是掌握了⼤量的规则,事物间的规则等。当我们教会机器⼈⼀些简单的规则后,它也就变得智能了。 送餐机器⼈ 很明显,我们的机器⼈⼏乎具备了简易送餐机器⼈的全部功能,能够按照指定线路⾏⾛,能够实时检测障碍物,最后就只差记录站点了。对 的,如果掌握变量的使⽤,你就可以尝试综合已经学习过的知识点,完成⼀个送餐机器⼈制作。 写在最后 初学机器⼈,你可能会发现,我们只不过是在交给机器⼈⼀些具体的规则,⽆论是让他完成智能声光控,亦或者让其送个餐,⾃动打扫⼀下 卫⽣等等,都是在不断的教会它更多的规则,让它在遇到问题的能够处理。⽽如果它变得能够处理⼀些突发性的问题,或者说当它能够创造 规则的时候,也就是⼈所具备的能⼒!⽽让机器⼈具备或延伸⼈的智能,也就是到了⼈⼯智能的领域了!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值