发表于:2010/3/5 20:22:52
#0楼
一、 实验简介:
本程序通过将以前所编写的分立程序通过有机结合,编制成一个大的应用系统。小车在完成自动防撞,防悬崖等动作外,还可以通过红外遥控器进行远程遥控。如果你对电脑编程很有趣兴的话,当然也可以通过电脑对串口进行编程。以方便通过电脑来进行对小车控制。在正常的运特过程中,还可以通过声控(拍手声)来对小车进行控制,每一种控制小车都会完成相应的功能。为了更清晰的看到小车运行过程状态,特将p1端口中的8个指示灯作为运行状态指示灯。以用来观察小车运行中的每一步。
二、 实验原理图
[URL=http://www.sfmcu.com/bbs/upfile/2010_2/201021510362620574.jpg]
[/URL]
三、 实现代码:
//===============================================================//
// 开发日期: 2009/01/30 编写综合功能演示子程序的最初代码确 //
// 修改日期: //
// 程序作者: guojun 益芯技术部 //
// 程序备注: 此程序仅为表现本机功能而演示用,当用作实际工程时请慎用. //
// 特别声明: 此程序可作研究之用,但引用,转载,使用请注明出处. //
//===============================================================//
#include //包含51相关的头文件
typedef unsigned char uchar; //重定义char数据类型
typedef unsigned int uint; //重定义int数据类型
#define showport p2 //定义数码管显示端口
uchar code ledshowdata[]={0x03,0x9f,0x25,0x0d,0x99, //定义数码管显示数据
0x49,0x41,0x1f,0x01,0x19}; //0,1,2,3,4,5,6,7,8,9
static unsigned int recvdata; //定义接收红外数据变量
static unsigned char countdata; //定义红外个数计数变量
static unsigned char adddata; //定义自增变量
static unsigned int ledflash; //定义闪动频率计数变量
unsigned char hearddata; //定义接收到数据的高位变量
bit runflag=0; //定义运行标志位
/***********完成基本数据变量定义**************/
sbit s1state=p1^0; //定义s1状态标志位
sbit s2state=p1^1; //定义s2状态标志位
sbit b1state=p1^2; //定义b1状态标志位
sbit irstate=p1^3; //定义ir状态标志位
sbit runstopstate=p1^4; //定义运行停止标志位
sbit fontirstate=p1^5; //定义fontir状态标志位
sbit leftirstate=p1^6; //定义leftir状态标志位
sbit rightirstate=p1^7; //定义rightirstate状态标志位
/*************完成状态指示灯定义*************/
sbit s1=p3^2; //定义s1按键端口
sbit s2=p3^4; //定义s2按键端口
/*************完成按键端口的定义*************/
sbit leftled=p2^0; //定义前方左侧指示灯端口
sbit rightled=p0^7; //定义前方右侧指示灯端口
/*************完成前方指示灯端口定义*********/
sbit leftir=p3^5; //定义前方左侧红外探头
sbit rightir=p3^6; //定义前主右侧红外探头
sbit fontir=p3^7; //定义正前方红外探头
/*************完成红外探头端口定义***********/
sbit m1a=p0^0; //定义电机1正向端口
sbit m1b=p0^1; //定义电机1反向端口
sbit m2a=p0^2; //定义电机2正向端口
sbit m2b=p0^3; //定义电机2反向端口
/*************完成电机端口定义***************/
sbit b1=p0^4; //定义话筒传感器端口
sbit rl1=p0^5; //定义光敏电阻端口
sbit sb1=p0^6; //定义蜂鸣端口
/*********完成话筒,光敏电阻,蜂鸣器.端口定义**/
sbit ir1=p3^3; //定义红外接收端口
/*********完成红外接收端口的定义*************/
void delay() //定义延时子程序
{ uint delaytime=30000; //定义延时时间变量
while(delaytime--); //开始进行延时循环
return; //子程序返回
}
void controlcar(uchar cartype) //定义小车控制子程序
{
m1a=0; //将电机1正向电平置低
m1b=0; //将电机1反向电平置低
m2a=0; //将电机2正向电平置低
m2b=0; //将电机2反向电平置低
leftled=1; //关闭前方左侧指示灯
rightled=1; //关闭前方右侧指示灯
delay(); //将此状态延时一段时间
switch(cartype) //判断小车控制指令类型
{ case 1: //前进 //判断是否是前进
{ m1a=1; //将电机1正向端口置高
m2a=1; //将电机2正向端口置高
break; //退出判断
}
case 2: //后退 //判断是否是后退
{ m1b=1; //将电机1反向端口置高
m2b=1; //将电机2反向端口置高
leftled=0; //将前方左侧指示灯置低(亮)
rightled=0; //将前方右侧指示灯置低(亮)
break; //退出判断
}
case 3: //左转 //判断是否是左转
{ m1b=1; //将电机1反向端口置高
m2a=1; //将电机2正向端口置高
leftled=0; //将前方左侧指示灯置低(亮)
break; //退出判断
}
case 4: //右转 //判断是否是右转
{ m1a=1; //将电机1正向端口置高
m2b=1; //将电机2反向端口置高
rightled=0; //将前方右侧指示灯置低(亮)
break; //退出判断
}
default: //默认情况下的判断
{
break; //直接退出判断
}
}
}
void timer0_ir1() interrupt 1 using 3 //定义红外定时器子程序
{
th0=0xff; //向定时器定时间寄存器填入高八位值
tl0=0x19; //向定时器定时间寄存器填入低八位值
adddata++; //自增变量加1
}
void int1_ir1() interrupt 2 //定义红外接收中断子程序
{
tr1=0; //将定时/计数器1关闭
irstate=!irstate; //将红外接收指示灯状态取反
if(4==adddata) //0 //判断接收到的数据是0
{
recvdata=recvdata | 0; //判断到0就将当前位写0
recvdata=recvdata
while(1) //程序主循环
{
while(ledflash--) //闪灯总延时
{
if(ir1==0) //判断延时期间是否有红外信号输入
{exeflag=1; //将可执行标志位置1
}
if(s1==0) //判断是否有s1按下
{
controlcar(8); //将小车置于停止状态
runflag==1; //改变小车运行状态标志位
s1state=!s1state; //改变s1按键标志位
goto nextrun; //跳转到nextrun标签
}
if(s2==0) //判断是否有s2按下
{
controlcar(1); //将小车置于前进状态
runflag==0; //改变小车运行状态标志位
s2state=!s2state; //改变s2按键标志位
goto nextrun; //跳转到nextrun标签
}
fontirstate=fontir; //前方红外指示灯显示正前方红外探头状态
leftirstate=leftir; //左侧红外指示灯显示前方左侧红外探头状态
rightirstate=rightir; //右侧红外指示灯显示前主右侧红外探头状态
if(fontir==0 || leftir==1 || rightir==1) //判断正前方,前左侧,前右侧红外探头状态
{controlcar(2); //改变小车状态为后退
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
controlcar(3); //改变小车左转状态
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
delay(); //调用延时子程序
sb1=!sb1; //将蜂鸣器取反
controlcar(1); //改变小车为前进状态
sb1=1; //关闭蜂鸣器声音
}
if(b1==0) //判断是否有话筒信号输入
{ if(runflag==0) //判断小车当前的运行标志位
{ controlcar(8); //将小车置于停止状态
runflag=1; //改变小车运行标志位
}
else
{ controlcar(1); //将小车置于前进状态
runflag=0; //改变小车运行标志位
}
b1state=!b1state; //将话筒信号指示灯取反
}
}
nextrun: //跳转标签
if(runflag==0) //判断运行标志位
{
runstopstate=!runstopstate; //改变小车运行停止状态标志位
}
else
{
runstopstate=1; //将运行停止状态标志位置1
}
ledflash=1000; //运行闪动时间重设定
if(exeflag==0) //判断可执行标志位
{
ex1=1; //开启外部中断1
tr1=1; //开启定时/计数器1
}
exeflag=0; //可执行标志位置0
}
}
四、 运行效果:
程序运行效果:将小车置于一个桌面上(桌面请不要使用黑色)。打开电源的开关,小车开始前进运行,同时运行指示灯闪亮,这时如果前方有障碍物(或走到悬崖处),小车将会先进行后退一段时间,并有蜂鸣器报警,再向左转一段时间,最后开始向前运行、左转、后退、右转、可以通过前方指示灯来观察。这时你可以能过声控(如拍手声)来让小车停止和开启.同时你也可以用遥控来控制小车的运行。按“1”,小车将向前运行,按“2”小车将后退,按“3”小车将左转,按“4”小车将右转.按其它(0-9)键,小车数管码显示相应的数字符号。按电源键,小车将会停止运行。同也可以用电脑将小车发送数字信号。其数码管也将显示相应的数字(0-9)。并执行相应的功能。当然s1、s2也是起作用,分别用于控制小车的停止和开启。(注意:操作时应在小车前进时操作,后退、左转、右转等操作时,没有写相应的查询程序)
三、 实现代码:
#include //包含51相关的头文件
typedef unsigned char uchar; //重定义char数据类型
typedef unsigned int uint; //重定义int数据类型
#define showport p2 //定义数码管显示端口
uchar code ledshowdata[]={0x03,0x9f,0x25,0x0d,0x99, //定义数码管显示数据
0x49,0x41,0x1f,0x01,0x19}; //0,1,2,3,4,5,6,7,8,9
static unsigned int recvdata; //定义接收红外数据变量
static unsigned char countdata; //定义红外个数计数变量
static unsigned char adddata; //定义自增变量
static unsigned int ledflash; //定义闪动频率计数变量
unsigned char hearddata; //定义接收到数据的高位变量
bit runflag=0; //定义运行标志位
/***********完成基本数据变量定义**************/
sbit s1state=p1^0; //定义s1状态标志位
sbit s2state=p1^1; //定义s2状态标志位
sbit b1state=p1^2; //定义b1状态标志位
sbit irstate=p1^3; //定义ir状态标志位
sbit runstopstate=p1^4; //定义运行停止标志位
sbit fontirstate=p1^5; //定义fontir状态标志位
sbit leftirstate=p1^6; //定义leftir状态标志位
sbit rightirstate=p1^7; //定义rightirstate状态标志位
/*************完成状态指示灯定义*************/
sbit s1=p3^2; //定义s1按键端口
sbit s2=p3^4; //定义s2按键端口
/*************完成按键端口的定义*************/
sbit leftled=p2^0; //定义前方左侧指示灯端口
sbit rightled=p0^7; //定义前方右侧指示灯端口
/*************完成前方指示灯端口定义*********/
sbit leftir=p3^5; //定义前方左侧红外探头
sbit rightir=p3^6; //定义前主右侧红外探头
sbit fontir=p3^7; //定义正前方红外探头
/*************完成红外探头端口定义***********/
sbit m1a=p0^0; //定义电机1正向端口
sbit m1b=p0^1; //定义电机1反向端口
sbit m2a=p0^2; //定义电机2正向端口
sbit m2b=p0^3; //定义电机2反向端口
/*************完成电机端口定义***************/
sbit b1=p0^4; //定义话筒传感器端口
sbit rl1=p0^5; //定义光敏电阻端口
sbit sb1=p0^6; //定义蜂鸣端口
/*********完成话筒,光敏电阻,蜂鸣器.端口定义**/
sbit ir1=p3^3; //定义红外接收端口
/*********完成红外接收端口的定义*************/
void delay() //定义延时子程序
{ uint delaytime=30000; //定义延时时间变量
while(delaytime--); //开始进行延时循环
return; //子程序返回
}
void controlcar(uchar cartype) //定义小车控制子程序
{
m1a=0; //将电机1正向电平置低
m1b=0; //将电机1反向电平置低
m2a=0; //将电机2正向电平置低
m2b=0; //将电机2反向电平置低
leftled=1; //关闭前方左侧指示灯
rightled=1; //关闭前方右侧指示灯
delay(); //将此状态延时一段时间
switch(cartype) //判断小车控制指令类型
{ case 1: //前进 //判断是否是前进
{ m1a=1; //将电机1正向端口置高
m2a=1; //将电机2正向端口置高
break; //退出判断
}
case 2: //后退 //判断是否是后退
{ m1b=1; //将电机1反向端口置高
m2b=1; //将电机2反向端口置高
leftled=0; //将前方左侧指示灯置低(亮)
rightled=0; //将前方右侧指示灯置低(亮)
break; //退出判断
}
case 3: //左转 //判断是否是左转
{ m1b=1; //将电机1反向端口置高
m2a=1; //将电机2正向端口置高
leftled=0; //将前方左侧指示灯置低(亮)
break; //退出判断
}
case 4: //右转 //判断是否是右转
{ m1a=1; //将电机1正向端口置高
m2b=1; //将电机2反向端口置高
rightled=0; //将前方右侧指示灯置低(亮)
break; //退出判断
}
default: //默认情况下的判断
{
break; //直接退出判断
}
}
}
void timer0_ir1() interrupt 1 using 3 //定义红外定时器子程序
{
th0=0xff; //向定时器定时间寄存器填入高八位值
tl0=0x19; //向定时器定时间寄存器填入低八位值
adddata++; //自增变量加1
}
void int1_ir1() interrupt 2 //定义红外接收中断子程序
{
tr1=0; //将定时/计数器1关闭
irstate=!irstate; //将红外接收指示灯状态取反
if(4==adddata) //0 //判断接收到的数据是0
{
recvdata=recvdata | 0; //判断到0就将当前位写0
recvdata=recvdata
----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=111261&Name=sfmcu