循迹小车源程序,用汇编语言写。

循迹小车源程序,用汇编语言写。,第1张

程序和中断程序入口 *

**

*************************************

ORG 0000H程序执行起始地址

LJMP START 跳至START

ORG 0003H外中断0入口

LJMP INTEX0 跳至INTEX0中断服务程序

ORG 000BH定时器T0中断入口

RETI 中断返回

ORG 0013H外中断1入口

LJMP INTEX1 跳至INTEX1中断服务程序

ORG 001BH定时器T1中断入口

LJMP INTT1 跳至INTT1中断服务程序

ORG 0023H串口中断入口

RETI 中断返回

ORG 002BH定时器T2中断入口

RETI 中断返回

***************************

* *

*初始化程序 *

* *

****************************

CLEARMEMIO: MOVR0, #70H 清70H-76H显示单元

MOVR7, #07H 循环次数

ML0: MOV@R0, #00H 清0

INCR0 下一地址

DJNZ R7, ML0未完再循环

MOVTMOD,#10H T1为16位定时器

MOVR4,#14H1秒定时用(50毫秒20次)

MOVTL1,#0B0H 50毫秒定时用初值

MOVTH1,#3CH

MOV 20H,#00H 清0 *** 作

MOV 21H,#00H

MOV 22H,#00H

MOV 23H,#00H

MOV 24H,#00H

CLR 30H 清停车标志

SETB ET1 开T1中断

SETB EX1 开外中断1

SETB IT1 外中断1采用边沿触发

SETB IT0 外中断0优先级为1(最高)

SETB EX0 开外中断0

SETBEA 开总中断允许

SETBTR1 开启定时器T1

RET 子程序返回

*************************************

**

*主 程 序*

**

*************************************

START: LCALLCLEARMEMIO 上电初始化

SETB P1.6 选择7.5V输出

CLR P1.7 选择7.5V输出

SETB P3.7 前进状态

CLR P3.6 前进状态

CLR P1.0 电机供电开始

;MAIN:LCALLDISP LED显示一次

LJMP MAIN 转MAIN循环

NOP PC值出错处理

NOP

LJMP START 重新初始化

*************************************

**

*外中断0服务程序,用作跑道位置处理 *

*23H作跑道计数器 *

*************************************

INTEX0:PUSH ACC 堆栈保护

PUSH PSW

CLR EX0 关中断

LCALLDISP LED显示一次(延时抗干扰)

JB P3.2,IN0RET P3.2为1退出(干扰)

INC 23H 跑道计数器加1

MOV A,23H 数据入A

CJNE A,#06H,JUDGE1 不是第6道转JUDGE1

LCALLSTOP 是第6道,停车

LJMP IN0RET 转中断退出

JUDGE1:CJNE A,#03H,JUDGE2 不是第3道转JUDGE2

LCALLSTOPSLOW 是第3道,变慢车

LJMP IN0RET 转中断退出

JUDGE2:CJNE A,#04H,JUDGE3 不是第4道转JUDGE3

LCALLFAST 是第4道,变快车

LJMP IN0RET 转中断退出

JUDGE3:CJNE A,#05H,IN0RET 不是第5道转INORET退出

LCALLSTOPSLOW 是第5道,变慢车

IN0RET:CLR IE0 清外中断0中断标志

POP PSW 恢复现场

POP ACC

LCALLDL7MS 延时7毫秒(抗干扰)

SETB EX0 开外中断0

RETI 中断返回

************************************

* 慢车控制子程序 *

************************************

STOPSLOW: CLR P1.6 关7.5V电源

CPL P3.6 反向驱动(刹车)

CPL P3.7 反向驱动

LCALLDS50MS 刹车时间(可根据试车情况调整)

LCALLDS50MS

LCALLDS50MS

CPL P3.6 正向驱动

CPL P3.7 正向驱动

SETB P1.7 开4.3V电源

RET 返回

************************************

* 快车控制子程序*

************************************

FAST: CLR P1.7 关4.3V电源

SETB P1.6 开7.5V电源

RET 返回

************************************

* 停车控制程序 *

************************************

STOP: MOV 23H,#00H 跑道计数单元清0

CPL P3.6 反向驱动(刹车)

CPL P3.7 反向驱动(刹车)

LCALLDS50MS 刹车时间

LCALLDS50MS 刹车时间(可调整)

SETBP1.0 关电机电源

SETBPT1 定时器T1为高优先级

LCALLDS10S 停车10秒

CLR PT1 恢复T1为低优先级

SETB P1.6 开7.5V电源(高速)

CLR P1.7 关4.3V

CLR P1.0 电机电源开

CPL 30H 停车点位置判断标志取反

JB 30H,STREN 为1(中途停车)转STREN

LCALLCLR00 是终点,调复0程序

STREN:RET 返回

智能小车程序

#include "reg52.h"

#define det_Dist 2.55 //单个脉冲对应的小车行走距离,其值为车轮周长/4

#define RD 9 //小车对角轴长度

#define PI 3.1415926

#define ANG_90 90

#define ANG_90_T 102

#define ANG_180 189

/*============================全局变量定义区============================*/

sbit P10=P1^0//控制继电器的开闭

sbit P11=P1^1//控制金属接近开关

sbit P12=P1^2//控制颜色传感器的开闭

sbit P07=P0^7//控制声光信号的开启

sbit P26=P2^6//接收颜色传感器的信号,白为0,黑为1

sbit P24=P2^4//左

sbit P25=P2^5//右 接收左右光传感器的信号,有光为0

unsigned char mType=0//设置运动的方式,0 向前 1 向左 2 向后 3 向右

unsigned char Direction=0//小车的即时朝向 0 朝上 1 朝左 2 朝下 3 朝右

unsigned sX=50unsigned char sY=0//小车的相对右下角的坐标 CM(sX,sY)

unsigned char StartTask=0//获得铁片后开始执行返回卸货任务,StartTask置一

unsigned char Inter_EX0=0// 完成一个完整的任务期间只能有一次外部中断

// Inter_EX0记录外部中断0的中断状态

// 0 动作最近的前一次未中断过,

// 1 动作最近的前一次中断过

unsigned char cntIorn=0//铁片数

unsigned char bkAim=2//回程目的地,0为A仓库,1为B仓库,2为停车场,

//(在MAIN中接受铁片颜色判断传感器的信号来赋值)

unsigned char Light_Flag=0//进入光引导区的标志(1)

unsigned int cntTime_5Min=0//时间周期数,用于 T0 精确定时

unsigned int cntTime_Plues=0//霍尔开关产生的脉冲数

/*============================全局变量定义区============================*/

/*------------------------------------------------*/

/*-----------------通用延迟程序-------------------*/

/*------------------------------------------------*/

void delay(unsigned int time) // time*0.5ms延时

{

unsigned int i,j

for(j=0j<timej++)

{

for(i=0i<60i++)

{}

}

}

/*-----------------------------------------------*/

/*-------------------显示控制模块----------------*/

/*-----------------------------------------------*/

/*数码管显示,显示铁片的数目(设接在P0,共阴)*/

void Display(unsigned char n)

{

char Numb[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x37,0x77}

P0=Numb[n]

}

/*-----------------------------------------------*/

/*-------------------传感器模块------------------*/

/*-----------------------------------------------*/

/*光源检测程序: */

/*用于纠正小车运行路线的正确性*/

unsigned char LightSeek()

{ void Display(unsigned char)

bit l,r

l=P24

r=P25

if(l==0&&r==1)

{

//Display(1)

return (3)//偏左,向右开

}

if(r==0&&l==1)

{

//Display(3)

return(1)//偏右,向左开

}

if((l==1&&r==1)||(l==0&&r==0))

{//Display(9)

return(0)//没有偏离,前进

}

}

/*铁片检测程序: */

/*判断铁片的颜色,设定bkAim,0为A仓库,1为B仓库,2为停车场*/

void IornColor()

{

delay(4000)

bkAim=(int)(P26)

Display((int)(P26)+2)

}

/*-----------------------------------------------*/

/*------------------运动控制模块-----------------*/

/*-----------------------------------------------*/

/*====基本动作层:完成基本运动动作的程序集====*/

/*运动调整程序: */

/*对小车的运动进行微调*/

void ctrMotor_Adjust(unsigned char t)

{

if(t==0)

{

P2=P2&240|11//用来解决两电机不对称的问题

delay(6)

}

if(t==3)

{

P2=P2&250//向左走

delay(1)

}

if(t==1)

{

P2=(P2&245)

delay(1)//向右走

}

P2=((P2&240)|15)

delay(10)

}

/*直走程序:*/

/*控制小车运动距离,dist为运动距离(cm),type为运动方式(0 2)*/

/*只改变小车sX 和 sY的值而不改变Direction的值. */

void ctrMotor_Dist(float dist,unsigned char type)

{unsigned char t=0

mType=type

P2=((P2&240)|15)

cntTime_Plues=(int)(dist/det_Dist)

while(cntTime_Plues)

{

if(Inter_EX0==1&&StartTask==0)

{

cntTime_Plues=0

break

}

if(Light_Flag==1) t=LightSeek()

if(type==0) //向前走

{

P2=P2&249

delay(40)

ctrMotor_Adjust(t)

}

if(type==2) //向后退

{

P2=P2&246

delay(50)

ctrMotor_Adjust(t)

}

P2=((P2&240)|15)

if(mType==2) delay(60)//刹车制动 0.5ms

else delay(75)

}

}

/*拐弯程序: */

/*控制小车运动角度,type为运动方式(1 3) */

/*只改变小车Direction的值而不改变sX 和 sY的值*/

void ctrMotor_Ang(unsigned char ang,unsigned char type,unsigned char dir)

{

unsigned char i=0

mType=type

P2=((P2&240)|15)

cntTime_Plues=(int)((PI*RD*90/(180*det_Dist)*1.2)*ang/90)

while(cntTime_Plues)

{

if(Inter_EX0==1&&StartTask==0)

{

cntTime_Plues=0

break

}

if(type==1) //向左走

{

P2=P2&250

delay(100)

ctrMotor_Adjust(0)

}

if(type==3) //向右走

{

P2=P2&245

delay(100)

ctrMotor_Adjust(0)

}

P2=((P2&240)|15)

delay(50)//刹车制动 0.5ms

}

if(!(Inter_EX0==1&&StartTask==0))

{

Direction=dir

}

}

/*====基本路线层:描述小车基本运动路线的程序集====*/

/*当小车到达仓库或停车场时,放下铁片或停车(0,1为仓库,2为停车场)*/

void rchPlace()

{unsigned int time,b,s,g

time=(int)(cntTime_5Min*0.065535)//只有一个数码管时,轮流显示全过程秒数 个 十 百

b=time%100

s=(time-b*100)%100

g=(time-b*100-s*10)%10

if(bkAim==2)

{

//到达停车场了,停车

EA=0

P2=((P2&240)|15)

while(1)

{

Display(10)//N

delay(2000)

Display(cntIorn)

delay(2000)

Display(11)//A

delay(2000)

Display(b)

delay(2000)

Display(s)

delay(2000)

Display(g)

delay(2000)

}

}

else

{

if(Inter_EX0==1&&StartTask==1)P10=0//到达仓库,卸下铁片

}

}

/*无任务模式: */

/*设置小车的固定运动路线,未发现铁片时的运动路线*/

void BasicRoute()

{ //Light_Flag=1

ctrMotor_Dist(153,0)

//Light_Flag=0

ctrMotor_Ang(ANG_90,1,1)

ctrMotor_Dist(100-sX,0)

ctrMotor_Dist(125,2)

ctrMotor_Dist(73,0)

ctrMotor_Ang(ANG_90,1,2)

//Light_Flag=1

ctrMotor_Dist(153,0)

//Light_Flag=0

ctrMotor_Ang(ANG_180,1,0)

rchPlace()

}

/*任务模式: */

/*设置小车的发现铁片后的运动路线*/

void TaskRoute()

{

//基本运行路线表,记载拐弯 0 向前 1 左拐 2 向后 3 右拐,正读去A区反读去B区

StartTask=1

ctrMotor_Ang(ANG_90_T,1,2)

if(bkAim==1)//仓库A

{

ctrMotor_Dist(10,0)

P2=((P2&240)|15)

delay(60)

ctrMotor_Ang(ANG_90_T,1,3)

ctrMotor_Dist(100-sX,2)

ctrMotor_Ang(ANG_90_T,1,2)

Light_Flag=1

ctrMotor_Dist(153,2)

Light_Flag=0

// ctrMotor_Ang(208,1,0)

}

else if(bkAim==0) //仓库B

{

ctrMotor_Dist(10,0)

P2=((P2&240)|15)

delay(60)

ctrMotor_Ang(ANG_90_T,1,3)

ctrMotor_Dist(100-sX,0)

ctrMotor_Ang(ANG_90_T,1,0)

Light_Flag=1

ctrMotor_Dist(153,2)

Light_Flag=0

//ctrMotor_Ang(208,1,0)

}

delay(5000)

rchPlace()

}

/*---------------------------------------------*/

/*-------------------主程序段------------------*/

/*---------------------------------------------*/

void main()

{

delay(4000)

P2=0xff//初始化端口

P07=0

P1=0

TMOD=0x01//初始化定时器0/1 及其中断

TL0=0

TH0=0

TR0=1

ET0=1

ET1=1

IT0=1//初始化外部中断

EX0=1

IT1=1

EX1=1

EA=1

P11=1

while(1)

{

Display(cntIorn)

bkAim=2

BasicRoute()

if(Inter_EX0==1)

{

TaskRoute()//按获得铁片后的路线运动

IE0=0

EX0=1

}

Inter_EX0=0

}

}

/*----------------------------------------------------*/

/*----------------------中断程序段--------------------*/

/*----------------------------------------------------*/

/*定时器0中断程序: */

/*当时间过了5分钟,则就地停车并进入休眠状态*/

void tmOver(void) interrupt 1

{

cntTime_5Min++

TL0=0

TH0=0

if(cntTime_5Min>=4520)

{

Display(5)

P2=((P2&240)|15)

EA=0//停车程序

P07=1

delay(4000)

PCON=0X00

while(1)

}

}

/*外部中断0中断程序: */

/*发现铁片,发出声光信号并将铁片吸起,发光二极管和蜂鸣器*/

/*并联在一起(设接在P07). 0为A仓库,1为B仓库,2为停车场*/

void fndIorn(void) interrupt 0

{

unsigned char i

P10=1

P2=((P2&240)|15)//停车

P07=1

delay(1000)//刹车制动 0.5ms

P07=0

Inter_EX0=1

cntIorn++

Display(cntIorn)

for(i=0i<40i++)

{

P2=P2&249

delay(2)

P2=((P2&240)|15)

delay(2)

}

P2=P2&249

delay(100)

P2=((P2&240)|15)//停车

IornColor()//判断铁片黑白,设置bkAim

for(i=0i<95i++)

{

P2=P2&249

delay(3)

P2=((P2&240)|15)

delay(2)

}

P2=((P2&240)|15)//停车

delay(4000)//把铁片吸起来

EX0=0

}

/*外部中断1中断程序:*/

/*对霍尔开关的脉冲记数,对小车的位置进行记录,以便对小车进行定位*/

void stpMove(void) interrupt 2

{

cntTime_Plues--

if(Direction==0) //向上

{

if(mType==0) sY+=det_Dist

else if(mType==2)

sY-=det_Dist

}

else if(Direction==1) //向左

{

if(mType==0) sX+=det_Dist

else if(mType==2)

sX-=det_Dist

}

else if(Direction==2) //向下

{

if(mType==0) sY-=det_Dist

else if(mType==2)

sY+=det_Dist

}

else if(Direction==3) //向右

{

if(mType==0) sX-=det_Dist

else if(mType==2)

sX+=det_Dist

}

#define P_IOA_Data (volatile unsigned int *)0x7000

#define P_IOA_Dir (volatile unsigned int *)0x7002

#define P_IOA_Attrib (volatile unsigned int *)0x7003

unsigned int scan()//检测黑线函数定声明

unsigned int num=0

void delay()

void init_1()//输入初始化

{

[P_IOA_Dir]=0x00f0

[P_IOA_Attrib]=0x00f0

[P_IOA_Data]=0x000f

}

//void init_2()//输出初始化

//{

//[P_IOA_Dir]=1

//[P_IOA_Attrib]=1

//[P_IOA_Data]=0

//}

void main()

{

while(1)

{

void init_1()

num=scan()

//void init_2()

switch(num)

{

case 1:

{

while(1)

{

[P_IOA_Data]=0x9f

delay(500)

// if([P_IOA_Data]==1)//传感器返回1,则终止转弯,下同

break

}

}

case 2:

{

while(1)

{

[P_IOA_Data]=0x9f

delay(500)

break

}

}

case 4:

{

while(1)

{

[P_IOA_Data]=0x6f

delay(500)

break

}

}

case 5:

{

while(1)

{

[P_IOA_Data]=0x6f

delay(500)

break

}

}

case 0:

{

while(1)

{

[P_IOA_Data]=0x5f

delay(500)

break

}

}

}

[P_IOA_Data]=0x5f//直走

delay(500)

}

}

void delay(uint z)

{

uint x,y

for(x=zx>0x--)

for(y=110y>0y--)

}

unsigned int scan()

{

if(P_IOA_Data==0xfe)

{

num=1

return num

}

if(line_2==0xfd)

{

num=2

return num

}

if(line_4==0xfb)

{

num=4

return num

}

if(line_5==0xf7)

{

num=5

return num

}

return 0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/10965682.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-12
下一篇 2023-05-12

发表评论

登录后才能评论

评论列表(0条)

保存