C51编写单片机小车程序

大邪神 2012-06-24 12:25:51
走迷宫的单片机小车

硬件:3个光电开关分别置于车头前、左、右3个方向。
3轮小车,使用两个直流电机分别控制小车前两轮,后轮为万向轮;转弯通过一个电机工作,另一电机停止实现。

功能:前进时遇到障碍物转弯。


主要问题是光电开关的对电机的控制函数不会写
...全文
553 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
大邪神 2012-06-29
  • 打赏
  • 举报
回复
我最后编成这个样子,光电开关输出0为有障碍物,输出1为通路。以下程序能成功走出特定迷宫(通用性比较差,因为老师最后检查看的是离开迷宫的速度,智能要求不高)



#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define t 1
#define tr 120
#define tl 125
uchar code seg_data[ ] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//0~9的段码表,0x00为熄灭符

sfr P4 = 0xE8;
sbit IN1 =P1^0;
sbit IN2=P1^1;
sbit IN3=P1^4;
sbit IN4=P1^5;
sbit LED1=P2^6;
sbit LED2=P2^7;
sbit LightF=P3^2;
sbit LightL=P4^6;
sbit LightR=P3^7;
sbit BEEP=P4^4;

/********以下是延时函数********/
void Delay_ms(uint xms) //延时程序,xms是形式参数
{
uint i, j;
for(i=xms;i>0;i--) // i=xms,即延时xms, xms由实际参数传入一个值
for(j=115;j>0;j--); //此处分号不可少
}
/********以下是显示函数********/
void display()
{
P0=seg_data[0]; //显示毫秒十位
P2=0xfe; //开个位显示(开第1只数码管)
Delay_ms(t); //延时10ms
P0=seg_data[1]; //显示毫秒百位
P2=0xfd; //开十位显示(开第2只数码管)
Delay_ms(t); //延时10ms
P0=seg_data[2]; //显示秒个位
P2=0xfb; //开百位显示(开第3只数码管)
Delay_ms(t); //延时10ms
P0=seg_data[3]; //显示秒十位
P2=0xf7; //开个位显示(开第4只数码管)
Delay_ms(t); //延时10ms
P0=seg_data[4]; //显示分个位
P2=0xef; //开十位显示(开第5只数码管)
Delay_ms(t); //延时10ms
P0=seg_data[5]; //显示分十位
P2=0xdf; //开个位显示(开第6只数码管)
Delay_ms(t); //延时10ms
P2=0xff;
}
/********以下是电机控制函数*********/
void stop()
{
IN1=0;
IN2=0;
IN3=0;
IN4=0;
Delay_ms(10);
}

void qianjin()
{
IN1=0;
IN2=1;
IN3=1;
IN4=0;
}

void leftturn(uint ms)
{
LED2=0;
IN1=0;
IN2=1;
IN3=0;
IN4=1;
Delay_ms(ms);
}

void rightturn(uint ms)
{
LED1=0;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
Delay_ms(ms);
}

/********以下是蜂鸣器函数********/
void beep()
{
BEEP=0;
Delay_ms(50);
BEEP=1;
Delay_ms(50);
}
//****************主程序******************//
void main()
{ P0=0xff;
P2=0xff;
P1=0xff;
P4=0xff;
while(1)
{
display();
if (LightL==1)
{
qianjin();
Delay_ms(130);
stop();
leftturn(tl);
stop();
qianjin();
Delay_ms(200);
}

else if(LightR==1)
{
qianjin();
Delay_ms(160);
stop();
rightturn(tr);
stop();
qianjin();
Delay_ms(200);
}

else if(LightF==1)
{
qianjin();
if(LightR==1)
{
qianjin();
Delay_ms(50);
stop();
rightturn(tr);
stop();
qianjin();
Delay_ms(200);
}
if(LightL==1)
{
qianjin();
Delay_ms(50);
stop();
leftturn(tl);
stop();
qianjin();
Delay_ms(200);}

}


else if(LightR==0&&LightL==0&&LightF==0)
{
stop();
beep();
rightturn(280);
stop();
qianjin();
Delay_ms(50);
}
}
}

备注一下,我是北京邮电大学的学生
AnYidan 2012-06-24
  • 打赏
  • 举报
回复
车头遇障碍检测左右的通路,决定两个电机应该如何工作,哪一个停止,哪一个运行

如果左右也无通路,退回并检测左右是否有通路

1。小车长时间走直路比较困难,要求两个电机完全运行一致
2。看看走迷宫的算法,
大邪神 2012-06-24
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
对了,不支持倒车的话如果左前右都有障碍也可以不用停下来,还是停一轮运行另一轮使之转向180度掉头
[/Quote]

你就当“左前右都有障碍”不会发生。。。还有一点,Detect函数怎样写?我不知道接上光电开关之后怎样让其发挥效果
江南一书生 2012-06-24
  • 打赏
  • 举报
回复
对了,不支持倒车的话如果左前右都有障碍也可以不用停下来,还是停一轮运行另一轮使之转向180度掉头
江南一书生 2012-06-24
  • 打赏
  • 举报
回复
三个光电器件分别检测左中右是否有障碍。
伪代码:
while(1)
{
if(DetectBlock(FRONT))//前向有障碍
{
if(!DetectBlock(LEFT))//左边无障碍
{
//向左转
StopWheel(LEFT);
DriveWheel(RIGHT);
Wait();//根据电机转速延时一定时间使转向90度
}
else if(!DetectBlock(RIGHT))//右边无障碍
{
//向右转
StopWheel(RIGHT);
DriveWheel(LEFT);
Wait();//根据电机转速延时一定时间使转向90度
}
else//左右都有障碍 :(
{
//不支持倒车的话只好停下来
StopWheel(LEFT);
StopWheel(RIGHT);
}
}
else//前向无障碍
{
//继续前进
DriveWheel(LEFT);
DriveWheel(RIGHT);
}
}
大邪神 2012-06-24
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
车头遇障碍检测左右的通路,决定两个电机应该如何工作,哪一个停止,哪一个运行

[/Quote]


这也是我的想法,不用考虑后退问题,(如果考虑后退,电机运行的一致性就比较重要,所以同样地,电机是否一致也不考虑)

我只是代码不会写。。。。

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧