标题:
可用VB控制的单片机遥控小车
[打印本页]
作者:
starmachine
时间:
2018-12-22 15:50
标题:
可用VB控制的单片机遥控小车
之前做的一个循迹小车,最后变成了一个遥控小车,可以采用电脑VB编写的画面控制,也可以采用在淘宝上买购买的串口触摸屏控制。小车已经被我拆了给我女做了一辆遥控小车。
附件中是程序代码。
VB控制智能小车.zip
(8.44 KB, 下载次数: 26)
2018-12-22 15:39 上传
点击文件名下载附件
vb编写的电脑控制小车,需要配合无线串口才可以使用。
下载积分: 黑币 -5
智能小车遥控器.zip
(1.07 MB, 下载次数: 13)
2018-12-22 15:40 上传
点击文件名下载附件
这个是串口触摸屏
下载积分: 黑币 -5
智能小车C51.zip
(127.21 KB, 下载次数: 13)
2018-12-22 15:41 上传
点击文件名下载附件
STC89C52单片机写的程序
下载积分: 黑币 -5
YL-40 AD模块使用说明.pdf
(204.13 KB, 下载次数: 12)
2018-12-22 15:46 上传
点击文件名下载附件
模拟量模块用来调速用的。
下载积分: 黑币 -5
串口HMI入门指南.pdf
(814.13 KB, 下载次数: 14)
2018-12-22 15:50 上传
点击文件名下载附件
串口触摸屏
下载积分: 黑币 -5
单片机源程序如下:
/**************************************
#define N 1 //可一次接收数据量
中断0 外部中断
中断1 定时器/计数器0中断
中断2 外部中断1
中断3 定时器/计数器1中断
中断4 串口中断
中断5 定时器/计数器2中断
中断6 外部中断2(仅STC增强型8051系列单片机)
中断7 外部中断3(仅STC增强型8051系列单片机)
左转++ 右转--
**************************************/
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char // 0~255
#define uint unsigned int //0~65535
#define AddWr1 0x90 //AddWr1 地址 10010000
#define AddRd1 0x91 //AddRd1 地址 10010001
#define AddWr2 0x94 //AddWr2 地址 10010100
#define AddRd2 0x95 //AddRd2 地址 10010101
#define N 5 //可一次接收数据量
void rs232_init(); //定义串口通信函数
uchar flag,i; //删除无用变量
uchar table[N]; //接收缓存数组
uchar j=0; //接收计数器
/*********总线端口********/
sbit SCL1=P0^6; //串行时钟输入端
sbit SDA1=P0^7; //串行数据输入端
/*********功能端口********/
sbit XJB=P0^5; //循迹开关
/*********遥控端口********/
sbit F=P1^0;//前进
sbit SCB=P1^2;//刹车/后退
sbit L=P1^3;//左转
sbit R=P1^1;//右转
/*********循迹端口********/
sbit QL=P3^6;//前左雷达
sbit QR=P3^5;//前右雷达
sbit QM=P3^4;//前中雷达
sbit XJL1=P3^7;//循迹L1
sbit XJR1=P3^2;//循迹R1
sbit XJL2=P1^6;//循迹L2
sbit XJR2=P1^5;//循迹R2
/*********驱动端口********/
sbit ZFL=P0^0;//正反转L
sbit SCL=P0^1;//刹车L
sbit ZFR=P0^2;//正反转R
sbit SCR =P0^3;//刹车R
/*********转向端口********/
sbit ZX=P2^7; //转向端口
sbit SN=P2^6; //定义使能端口
sbit OUT=P2^2; //定义OUT输出端口
sbit HOME=P3^3; //方向回正标志
signed int a=0,a1,a2;//当前位置,设定位置1,设定位置2 有符号 + -
char code a3[]={0,67,111,222,333,444,556,667,778,889,1111,2000,
-67,-111,-222,-333,-444,-556,-667,-778,-889,-1111,-2000};//位置数组
uchar code jy[]={0x00,0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
0x01,0x02,0x05,0x0b,0x0f,0xf0,0xf1,0xf2,0xf3};
uchar b;//差补值
uchar c=0;//回正标志位
uchar dir1;//方向判断开始标志
uchar scb1;//刹车完成标志
uchar snButton=0;//使能开关:0,自动;1,使能关闭
uchar d1=0,d2=0,d=0;//左边速度
uchar e1=0,e=0;//右边速度
uchar forward=0,back=0; //前进后退标志位
uint t1=0,t2=0,t3=0,t4=0,t5=0,t6=0,t7=0,t8=0,t9,t10,t11,t12;//定时器
uchar z1,z2,z3,z4,z5,z6,z7,z8,z9,z10,z11,z12;
uchar table2;//串口数据储存
uchar jy1,jy2;//校验数据大小
uchar autoN=0; //自动续航
/*********************************
t1 方向使能保时
t2 前进锁定保时
t3 后退锁定保时
t4 备用
t5 前进刹车保时
t6 后退刹车保时
t7
t8
t9
t10
t11
*********************************/
/********自动巡航状态*************/
uchar l0,l1,l2,l3;//L雷达
uchar m0,m1,m2,m3;//M雷达
uchar r0,r1,r2,r3;//R雷达
uchar lm0,lm1,lm2,lm3;//LM雷达
uchar mr0,mr1,mr2,mr3;//MR雷达
uchar lr0,lr1,lr2,lr3;//LR雷达
uchar lmr0,lmr1,lmr2,lmr3;//LMR雷达
uchar gear;//档位
uchar speed;//速度
uchar s1,s2,s3;//档位标志位
uchar FS,BS;//前进刹车标志,后退刹车标志
/*********延时4-5us********/
void delay1()
{;;}
/*********延时 ********/
void delay_1ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=speed;y>0;y--);
}
/*********开始信号********/
void start() //开始信号
{
SDA1=1; //先把数据置1,再把时钟置1,后把数据置0. 以保证在时钟为1时,数据由高变低。
delay1();
SCL1=1; //时钟信号为1
delay1();
SDA1=0; //数据在时钟高电平时1-0则为开始信号。
delay1();
}
/********* 停止信号 ********/
void stop() //停止信号
{
SDA1=0; //先把数据置0,再把时钟置1,后把数据置1. 以保证在时钟为1时,数据由低变高。
delay1();
SCL1=1; //时钟信号为1
delay1();
SDA1=1; //数据在时钟高电平时0-1则为停止信号。
delay1();
}
/*********应答 ********/
void respons()//应答 相当于一个智能的延时函数
{
uchar i;
SCL1=1;//scl高电平期间接收信号
delay1();
while((SDA1==1)&&(i<220))
i++;
SCL1=0;
delay1();
}
/********* 初始化 ********/
//void init() //初始化
//{
//SDA1=1;
//delay1();
//SCL1=1;
//delay1();
//}
/*********用移位溢出的方式逐位输出数据********/
void write_byte(uchar date) //写一字节数据
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1; //左移一位 移出的一位在 CY 中
SCL1=0;
delay1();
SDA1=CY;
delay1();
SCL1=1;//此时读取总线数据
delay1();
}
SCL1=0;
delay1();
SDA1=1;
delay1();
}
/*********L速度模拟量模块驱动 ********/
void write_add(uchar address,uchar date)
{
start();
write_byte(AddWr1); //10010000
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
/********R速度模拟量模块驱动 ********/
void write_add1(uchar address,uchar date)
{
start(); //调用中断
write_byte(AddWr2); //10010100
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
/***********初始化串口通信参数设定************/
void rs232_init() //初始化串口通信参数设定
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SM0=0;//
SM1=1;// SM0 SM1 0 1 工作方式1 10位异步收发,波特率可变(T1溢出率/n,n=32或16)
REN=1;//先设定号工作方式,在打开允许接收
EA=1;
ES=1;
}
/***************************************************************************
(1)SM0 SM1:串行口工作方式选择位。
SM0 SM1 0 0 工作方式0 同步移位寄存器输入/输出,波特率固定为fosc/12
SM0 SM1 0 1 工作方式1 10位异步收发,波特率可变(T1溢出率/n,n=32或16)
SM0 SM1 1 0 工作方式2 11位异步收发,波特率固定为fosc/n,n=64或32)
SM0 SM1 1 1 工作方式3 11位异步收发,波特率可变(T1溢出率/n,n=32或16)
(2)SM2:多机通信控制器位。在方式0中,SM2必须设成0。在方式1中,当处于接收状态时,若
SM2=1,则只有接收到有效的停止位“1”时,RI才能被激活成“1”(产生中断请求)。在方式2和方式
3中,若SM2=0,串行口以单机发送或接收方式工作,TI和RI以正常方式被激活并产生中断请求;若
SM2=1,RB8=1时,RI被激活并产生中断请求。
(3)REN:串行接受允许控制位。该位由软件置位或复位。当REN=1,允许接收;当REN=0,禁止接收。
(4)TB0:方式2和方式3中要发送的第9位数据。该位由软件置位或复位。在方式2和方式3时,
TB8是发送的第9位数据。在多机通信中,以TB8位的状态表示主机发送的是地址还是数据 :
TB8=1表示地址,TB8=0表示数据。TB8还可用作奇偶校验位。
(5)RB8:接收数据第9位。在方式2和方式3时,RB8存放接收到的第9位数据。RB8也可用作奇偶校验位。
在方式1中,若SM2=0,则RB8是接收到的停止位。在方式0中,该位未用。
(6)TI:发送中断标志位。TI=1,表示已结束一帧数据发送,可由软件查询TI位标志,也可以向CPU申请
中断。
注意:TI在任何工作方式下都必须由软件清0。
(7)RI:接收中断标志位。RI=1,表示一帧数据接收结束。可由软件查询RI位标志,也可以向CPU申请中断。
注意:RI在任何工作方式下也都必须由软件清0。
在AT89C51中,串行发送中断TI和接收中断RI的中断入口地址是同是0023H,因此在中断程序中
必须由软件查询TI和RI的状态才能确定究竟是接收还是发送中断,进而作出相应的处理。单片机复位时,
SCON所有位均清0。
*****************************************************************************/
/***********左转弯控制***************/
void Lpulse()//左转脉冲输出计数
{
if(a<2000)//左转极限
{
ZX=0;
if(a1>a)
{
a++;
OUT=~OUT;
}
}
}
/***********右转弯控制***************/
void Rpulse()//右转脉冲输出计数
{
if(a>-2000)//右转极限
{
ZX=1;
if(a1<a)
{
a--;
OUT=~OUT;
}
}
}
/****************差速驱动***************************/
void speed1()//
{
if(a>0)
{
if(a<2000)
{
d=speed -a/b; //a偏角数,b差速倍率
e=speed;
}
else
{
d=speed;
e=speed;
}
}
if(a<0)
{
if(a>-2000)
{
d=speed;
e=speed +a/b;
}
else
{
if(speed<150)
{
d=speed+20;
e=0;
}
else
{
d=speed;
e=0;
}
}
}
if(a==0)
{
d=speed;
e=speed;
}
}
/*************串口通信数据归零************************/
void table1()
{
table[0]=0;
}
/*****************转向方向运算*****************************/
/*****************前进刹车驱动*****************************/
/*****************后退刹车驱动*****************************/
/***************主程序******************/
void main()
{
TMOD=0X11;//定时器0采用工作方式1
TH0=(65536-200)/256;
TL0=(65536-200)%256;//初值,定时
TH2=(65536-50000)/256;//初值,定时1ms
TL2=(65536-50000)%256;//
T2CON=0;
EA=1; //总中断打开
ET0=1; //定时器0中断打开
ET2=1; //定时器2中断打开
TR0=1;//启动定时器0
TR2=1;
rs232_init(); //调用串口通信参数设定函数
speed=90;
b=22;
jy1=1;
while(1)
{
/*****************指令校验***************************/
if(table[0]!=0)
{
for(jy1=0;jy1<43;jy1++)
{
if(jy[jy1]==table[0])
{
jy2=1;
}
}
if(jy2==1&&jy1==42)//如果串口数据在列表中,校验成功,复位标志位jy2.
{
table[0]=table[0];
SCL=1;
SCR=1;
}
if(jy2==0&&jy1==42&&table[0]!=0) //如果校验失败,启动刹车
{
table1();
F=1;
SCB=1;
forward=0;
back=0;
t2=0;
t3=0;
a1=0;
dir1=1;
speed=90;//刹车启动后设为一档
b=22;//差速系数
SCL=0;
SCR=0;
}
}
/**************转弯方向判断********************/
if(dir1==1)
{
c=0;
if(a1==a)
{
L=1;
R=1;
dir1=0;
table1();
}
if(a1>a) //启动左转
{
L=0;
R=1;
}
if(a1<a) //启动右转
{
L=1;
R=0;
}
}
/***************串口通信*************************/
if(flag==1)
{
ES=0;
for(j=0;j<N;j++) //回传接收数组
{
SBUF=table[j]; //把接收到的数据重新赋值给串口缓存寄存器
while(!TI);
TI=0;
}
j=0; //清零接收计数器
ES=1;
flag=0;
}
if(table[0]==0x01)//前进
{
F=0;
SCB=1;
t3=0;
back=0;
if(forward==1)//当前进锁定后,再次按下后退自动回正
{
c=1;//回正
}
}
if(table[0]==0x02)//后退
{
F=1;
SCB=0;
t2=0;
forward=0;
if(back==1) //当后退锁定后,再次按下后退自动回正
{
c=1;
}
}
if(table[0]==0x0f)//刹车
{
F=1;
SCB=1;
t2=0;
t3=0;
a1=0;
dir1=1;
speed=90;//刹车启动后设为一档
b=22;//差速系数
}
if(table[0]==0xa0)//L3
{
a1=67;
dir1=1;//方向判断
}
if(table[0]==0xa1)//L5
{
a1=111;
dir1=1;//方向判断
}
if(table[0]==0xa2)//L10
{
a1=222;
dir1=1;//方向判断
}
if(table[0]==0xa3)//L15
{
a1=333;
dir1=1;//方向判断
}
if(table[0]==0xa4)//L20
{
a1=444;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xa5)//L25
{
a1=556;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xa6)//L30
{
a1=667;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xa7)//L35
{
a1=778;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xa8)//L40
{
a1=889;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xa9)//L45
{
a1=1000;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xaa)//L50
{
a1=1111;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xab)//L55
{
a1=1222;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xac)//L60
{
a1=1333;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xab)//L70
{
a1=1556;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xae)//L80
{
a1=1778;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xaf)//L90
{
a1=2000;//设定角度
dir1=1;//方向判断
}
if(table[0]==0x05)//L微调
{
a=a+20;
a1=0;
dir1=1;
table1();
}
if(table[0]==0x0b)//R微调
{
a=a-20;
a1=0;
dir1=1;
table1();
}
if(table[0]==0x08)//回正
{
a1=0;
dir1=1;
}
if(table[0]==0xb0)//R3
{
a1=-67;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xb1)//R3
{
a1=-111;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xb2)//R10
{
a1=-222;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xb3)//R15
{
a1=-333;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xb4)//R20
{
a1=-444;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xb5)//R25
{
a1=-556;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xb6)//R30
{
a1=-667;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xb7)//R35
{
a1=-778;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xb8)//R40
{
a1=-889;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xb9)//R45
{
a1=-1000;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xba)//R50
{
a1=-1111;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xbb)//R55
{
a1=-1222;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xbc)//R60
{
a1=-1333;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xbd)//R70
{
a1=-1556;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xbe)//R80
{
a1=-1778;//设定角度
dir1=1;//方向判断
}
if(table[0]==0xbf)//R90
{
a1=-2000;//设定角度
dir1=1;//方向判断
}
if(table[0]==0x12)//1档
{
speed=90;
b=22;
}
if(table[0]==0x13)//2档
{
speed=120;
b=17;
}
if(table[0]==0x14)//3档
{
speed=150;
b=13;
}
if(table[0]==0xf0)//自动开始
{
autoN=1;
}
if(table[0]==0xf1)//自动关闭
{
autoN=0;
}
if(table[0]==0xf2)//使能手动关闭
{
snButton=1;
}
if(table[0]==0xf3)//使能自动
{
snButton=0;
}
/*************************************************/
/*****************************************************/
write_add(0x40,d1); //调用函数write_add(ox40,a) 在前面函数声明中,只是声明了变量并未作赋值
write_add1(0x40,e1); //调用函数write_add(ox40,a) 在前面函数声明中,只是声明了变量并未作赋值
d1=d;//左边速度
e1=e;//右边速度
/**************************************************/
if(autoN==1)
{
scb1=0;//刹车完成标志rst
if(QL==0&&QR==1)
{
a1=-1200;//设定角度
dir1=1;//方向判断
}
if(QR==0&&QL==1)
{
a1=1200;//设定角度
dir1=1;//方向判断
}
if(QR==0&&QL==0)
{
F=1;
SCB=1;
forward=0;
back=0;
t2=0;
t3=0;
a1=0;
dir1=1;
speed=90;//刹车启动后设为一档
b=22;//差速系数
}
if(QM==0)
{
F=1;
SCB=0;
t2=0;
forward=0;
if(back==1) //当后退锁定后,再次按下后退自动回正
{
c=1;
}
if(QL==0&&QR==1)
{
a1=-1200;//设定角度
dir1=1;//方向判断
delay_1ms(400);
}
if(QR==0&&QL==1)
{
a1=1200;//设定角度
dir1=1;//方向判断
delay_1ms(400);
}
delay_1ms(800);
}
else
{
F=0;
SCB=1;
t3=0;
back=0;
if(forward==1)//当前进锁定后,再次按下后退自动回正
{
c=1;//回正
}
}
if(QL==1&&QR==1&&a!=0)
{
a1=0;
dir1=1;
}
}
/****************************************************/
if(F==0||t2>10)
{
t3=0;//后退自锁解除
if((back==0&&XJB==1)||t2<10)//按下F按钮10以内启动点动模式
{
t3=0; //按压后退开关延时自锁取消
speed1();//差速自动控制
if(t2>10)//当前进按钮按下10以上时前进标志位置位
{
forward=1; //前进标志位置位
}
else //如果没有超过10,则不启动前进标志位
{
forward=0;
}
SCL=1;
SCR=1; //关闭刹车
if(a==0)
{
ZFL=1;
ZFR=1;
}
if(a>0)
{
if(a<2000)
{
ZFL=1;
ZFR=1;
}
else
{
ZFL=0;
ZFR=1;
}
}
if(a<0)
{
if(a>-2000)
{
ZFL=1;
ZFR=1;
}
}
}
}
/************倒车**********************/
if(SCB==0||t3>10)
{
t2=0; //按压前进开关延时自锁取消
if(forward==0)
{
speed1();//差速自动控制
if(t3>10)
{
back=1; //后退标志位置位
}
else
{
back=0;
}
forward=0; //前进标志位复位
SCL=1;
SCR=1;
t4=0;
if(a==0)
{
ZFL=0;
ZFR=0;
}
if(a>0)
{
if(a<2000)
{
ZFL=0;
ZFR=0;
}
else
{
ZFL=1;
ZFR=0;
}
}
if(a<0)
{
if(a>-2000)
{
ZFL=0;
ZFR=0;
}
else
{
ZFL=0;
ZFR=0;
}
}
}
}
if(F==1&&SCB==1&&t4<20) //当全部按钮释放,前进后退自锁取消时复位参数
{
t2=0;//前进自锁延时 复位
t3=0;//后退自锁延时 复位
d=0;//速度归零
e=0;//
d1=0;
e1=0;
if(back==1)
{
ZFL=1;
ZFR=1;
forward=0;
back=0;
}
if(forward==1)
{
ZFL=0;
ZFR=0;
forward=0;
back=0;
}
SCL=0;
SCR=0;
}
else
{
if(t4>20)
{
SCL=1;
SCR=1;
ZFL=1;
ZFR=1;
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
作者:
admin
时间:
2018-12-25 02:39
好资料,51黑有你更精彩!!!
作者:
徐铖
时间:
2019-1-1 11:48
好资料,51有你更精彩!!!
作者:
steve0033
时间:
2019-12-19 09:08
感谢楼主分享
作者:
wang1234567.
时间:
2021-1-29 11:19
vb的源代码有吗
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1