您现在所在的是:

单片机论坛

回帖:2个,阅读:1122 [上一页] [1] [下一页]
912
sfmcu
文章数:44
年度积分:50
历史总积分:912
注册时间:2006/8/22
发站内信
08年优秀博客奖
发表于: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
16067
xilinxue
文章数:2441
年度积分:50
历史总积分:16067
注册时间:2007/12/27
发站内信
发表于:2010/3/21 7:50:34
#1楼
好东西。
17528
ahljj
文章数:3386
年度积分:240
历史总积分:17528
注册时间:2002/3/23
发站内信
发表于:2010/5/24 9:23:14
#2楼
学习了

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

109.2007