原创 盛方跟我学做智能车第二节 基本行进控制

2010-2-22 10:55 2365 4 5 分类: MCU/ 嵌入式



第二节 小车前进、后退、转弯、变速实验


一、实验原理:


       电机驱动板的控制端与P0口相连,注意P0口必须接上拉电阻,1k比较合适。按照驱动板原理,只要控制与方向控制连接的I/O口,就能实现小车方向的控制,控制与使能端连接的I/O口,就能实现小车速度的控制。小车直线前进,每个轮的速度受使能端控制,当使能端输入相同占空比时,两轮速度相同,实现小车直线前进。直线后退,每个轮的速度控制与直线前进一样,改变两轮的运动方向,方向控制信号与直线前进相反即可。小车左转,方向控制保持和前进一样,左轮速度慢,右轮速度快,就可以让小车左转。小车右转,和左转原理一样,左轮速度快,右轮速度慢,就可以了。直线变速前进,方向不变,逐渐改变输出PWM的占空比。占空比逐渐增加,就是加速,占空比逐渐减小,就是减速。


二、实验任务:


1.  编写小车直线前进的程序,小车速度可调,改变小车速度。小车速度共25档,也就是说,PWM周期共分为25等份。调节速度就是控制高电平的占有时间即等份数。


2.  改变小车的运动方向,让小车后退,改变占空比,体验小车不同速度后退。


3.  控制小车左轮占空比小于右轮,下载程序,小车可以完成左转弯功能。改变左右轮占空比的差距,观察小车的转弯幅度也会随之变化。


4.  控制小车右轮占空比小于左轮,重复任务3的步骤,小车就可以右转弯了。接着重复任务3的实验内容。


5.  通过前面的4个任务,我们基本上已经具有控制小车完成基本工作的能力了,现在让我们来做点有挑战性的实验吧。题目,小车实现变速功能,每1-2秒小车速度变化一次。从速度零加速到最大速度,然后从最大速度逐渐减速到零,如此反复。速度共分为25档。


三、实验源程序:


任务1源程序:


/*******************************************************************


 


 公司名称:盛方单片机


 公司网址:www.sfmcu.com


 模块名称:001.c


     能:直行前进。           


     明:通过定时器0产生PWM调速。


 程序设计:tongwei     


 设计时间:2009.09.13       


  :


*********************************************************************/


#include < reg52.h >


 


#define uchar unsigned char


#define uint unsigned int


 


#define MOTOR_C P0                               //P0口作为电机的控制口。


#define PERCENT  3                                 //占空比常量定义。


#define SHELVES 25                                 //速度总档数。


 


sbit PWM_R = P0^7;                                 //右电机PWM输入口


sbit PWM_L = P0^2;                                 //左电机PWM输入口


 


#define BACK 0xC6                                   //后退


#define FORWARD 0xA5                           //前进


 


 


 


void timer_init( void );                 //定时器初始化函数。


void forward( void );                          //前进函数。


 


 /********************************************************************


  名:timer_init()


     能:初始化定时器0


     明:无


 入口参数:无


  值:无


     计:tongwei               期:2009.09.13


     改:                      期:


***********************************************************************/


void timer_init( void )


{


       TMOD = 0x02;                           //定时器0工作在方式2,定时值自动重载,启动仅受TR0的控制。


       TH0 = 256 - 200;                 //定时周期为 200us * SHELVES


       TL0 = 256 - 200;


 


       EA = 1;                                      //开总中断。


       ET0 = 1;                             //开定时器0中断。


       TR0 = 1;                             //启动定时器0


}


 


/********************************************************************


 


  名:forward()


     能:小车直行函数。


     明:无


 入口参数:无


  值:无 


     计:tongwei               期:2009.09.12


     改:                      期:


***********************************************************************/


void forward( void )


{


       timer_init();                         //定时器0初始化。


       MOTOR_C = FORWARD;                  //设置方向,前进


       while( 1 );                                 


}


 


/********************************************************************


 


  名:timer_zero()


     能:定时器0中断服务函数


     明:无


 入口参数:无


  值:无 


     计:tongwei               期:2009.09.12


     改:                      期:


***********************************************************************/


void timer_zero( void ) interrupt 1


{


       static uchar temp = 0;                                //中断次数计数,


       EA = 0;                                                           //关总中断,屏蔽其他中断。


       if(temp < PERCENT)                                       //高电平保持时间。


       {


              PWM_L = 1;                                             //PWM高电平,11000110B


              PWM_R = 1;


              temp ++;                                          //实现计数


       }


       else


       {


              if(temp < SHELVES)                                 //低电平保持时间。


              {


                     PWM_L = 0;                                      //PWM低电平,01000010B


                     PWM_R = 0;


                     temp ++;                                   //实现计数


              }


              else                                                   //一个PWM周期结束,计数清零。


              {


                     temp = 0;


              }


       }


       EA = 1;                                                           //开总中断。


}


/********************************************************************


  名:main()


     能:主函数


     明:无


 入口参数:无


  值:无 


     计:tongwei               期:2009.09.12


     改:                      期:


***********************************************************************/


void main()


{


       forward();


}


 


任务2源程序:


/*******************************************************************


 


 公司名称:盛方单片机


 公司网址:www.sfmcu.com


 模块名称:002.c


     能:直行后退。           


     明:通过定时器0产生PWM调速。


 程序设计:tongwei     


 设计时间:2009.09.13        


  :


*********************************************************************/


#include < reg52.h >


 


#define uchar unsigned char


#define uint unsigned int


 


#define MOTOR_C P0                               //P0口作为电机的控制口。


#define PERCENT  3                                 //占空比常量定义。


#define SHELVES 25                                 //速度总档数。


 


sbit PWM_R = P0^7;                                 //右电机PWM输入口


sbit PWM_L = P0^2;                                 //左电机PWM输入口


 


#define BACK 0xC6                                   //后退


#define FORWARD 0xA5                           //前进


 


 


 


void timer_init( void );                 //定时器初始化函数。


void back( void );                               //后退函数。


 


 /********************************************************************


 


  名:timer_init()


     能:初始化定时器0


     明:无


 入口参数:无


  值:无 


     计:tongwei               期:2009.09.13


     改:                      期:


***********************************************************************/


void timer_init( void )


{


       TMOD = 0x02;                           //定时器0工作在方式2,定时值自动重载,启动仅受TR0的控制。


       TH0 = 256 - 200;                 //定时周期为 200us * SHELVES


       TL0 = 256 - 200;


 


       EA = 1;                                      //开总中断。


       ET0 = 1;                             //开定时器0中断。


       TR0 = 1;                             //启动定时器0


}


 


/********************************************************************


 


  名:back()


     能:小车直行函数。


     明:无


 入口参数:无


  值:无 


     计:tongwei               期:2009.09.13


     改:                      期:


***********************************************************************/


void back( void )


{


       timer_init();                         //定时器0初始化


       MOTOR_C = BACK;                          //设置方向,后退


       while( 1 );


}


 


/********************************************************************


 


  名:timer_zero()


     能:定时器0中断服务函数


     明:无


 入口参数:无


  值:无 


     计:tongwei               期:2009.09.12


     改:                      期:


***********************************************************************/


void timer_zero( void ) interrupt 1


{


       static uchar temp = 0;                                //中断次数计数,


 


       EA = 0;                                                           //关总中断,屏蔽其他中断。


 


       if(temp < PERCENT)                                       //高电平保持时间。


       {


             


              PWM_L = 1;                                             //PWM高电平,11000110B


              PWM_R = 1;


              temp ++;                                          //实现计数


       }


 


       else


       {


              if(temp < SHELVES)                                 //低电平保持时间。


              {


                    


                     PWM_L = 0;                                      //PWM低电平,01000010B


                     PWM_R = 0;


                     temp ++;                                   //实现计数


 


              }


 


 


              else                                                   //一个PWM周期结束,计数清零。


              {


                     temp = 0;


              }


       }


 


       EA = 1;                                                           //开总中断。


}


 

ip.gif 120.6.147.237 返回列表  返回顶部  




帅哥在线 admin

1101.gif

头衔:鱼
职务:总管理员
等级:⑤潮汐猎人
发帖:939
积分:-2574
在线:164小时
注册:2004-7-21

1 楼 发表于:2010-2-12 11:46:39  引用 编辑 删除 屏蔽 清除 消链


/******************************************************************** 

 

 函 数 名:main()

 功    能:主函数

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.12

 修    改:                  日    期: 

***********************************************************************/

void main()

{

       back();

}

 

 

任务3源程序:

/*******************************************************************

 

 公司名称:盛方单片机

 公司网址:www.sfmcu.com

 模块名称:003.c

 功    能:小车左转弯。            

 说    明:通过定时器0产生PWM调速。

 程序设计:tongwei      

 设计时间:2009.09.13        

 版 本 号: 

*********************************************************************/

#include < reg52.h >

 

#define uchar unsigned char

#define uint unsigned int

 

#define MOTOR_C P0                               //P0口作为电机的控制口。

#define SHELVES 25                                 //速度总档数。

 

sbit PWM_R = P0^7;                                 //右电机PWM输入口

sbit PWM_L = P0^2;                                 //左电机PWM输入口

 

#define BACK 0xC6                                   //后退

#define FORWARD 0xA5                           //前进

 

void timer_init( void );                 //定时器初始化函数。

void left( void );                                 //左转弯函数。

 

uchar percent_l = 0;                           //左轮占空比

uchar percent_r = 0;                           //右轮占空比

 

/******************************************************************** 

 

 函 数 名:timer_init()

 功    能:初始化定时器0

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.13

 修    改:                  日    期: 

***********************************************************************/

void timer_init( void )

{

       TMOD = 0x02;                           //定时器0工作在方式2,定时值自动重载,启动仅受TR0的控制。

       TH0 = 256 - 200;                 //定时周期为 200us * SHELVES

       TL0 = 256 - 200;

 

       EA = 1;                                      //开总中断。

       ET0 = 1;                             //开定时器0中断。

       TR0 = 1;                             //启动定时器0。

}

 

/******************************************************************** 

 

 函 数 名:left()

 功    能:小车左转

 说    明:通过控制左右轮不同的占空比,实现左右转。

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.13

 修    改:                  日    期: 

***********************************************************************/

void left( void )

{

       timer_init();                         //初始化定时器0。

       MOTOR_C = FORWARD;                  //方向向前

       percent_r = 8;                      //右轮速度快。

       percent_l = 5;                      //左轮速度慢。

       while( 1 );

}

 

/******************************************************************** 

 

 函 数 名:timer_zero()

 功    能:定时器0中断服务函数

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.12

 修    改:                  日    期: 

***********************************************************************/

void timer_zero( void ) interrupt 1

{

       static uchar temp = 0;                                //中断次数计数,

 

       EA = 0;                                                           //关总中断,屏蔽其他中断。

 

       if(temp < SHELVES)                                        //高电平保持时间。

       {                   

              if(temp < percent_l)

              {

                     PWM_L = 1;                                      //左电机高电平

              }

              else

              {

                     PWM_L = 0;                                      //左电机低电平

              }

 

              if(temp < percent_r)

              {

                     PWM_R = 1;                                     //右电机高电平

              }

              else

              {                  

                     PWM_R = 0;                                     //右电机低电平

              }

 

              temp ++;                                          //实现计数

       }

       else                                                          //一个PWM周期结束,计数清零。

       {

              temp = 0;

       }            

 

       EA = 1;                                                           //开总中断。

}

 

/******************************************************************** 

 

 函 数 名:main()

 功    能:主函数

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.12

 修    改:                  日    期: 

***********************************************************************/

void main()

{

       left();

}

 

 

任务4源程序:

/*******************************************************************

 

 公司名称:盛方单片机

 公司网址:www.sfmcu.com

 模块名称:004.c

 功    能:小车右转弯。            

 说    明:通过定时器0产生PWM调速。

 程序设计:tongwei      

 设计时间:2009.09.13        

 版 本 号: 

*********************************************************************/

#include < reg52.h >

 

#define uchar unsigned char

#define uint unsigned int

 

#define MOTOR_C P0                               //P0口作为电机的控制口。

#define SHELVES 25                                 //速度总档数。

 

sbit PWM_R = P0^7;                                 //右电机PWM输入口

sbit PWM_L = P0^2;                                 //左电机PWM输入口

 

#define BACK 0xC6                                   //后退

#define FORWARD 0xA5                           //前进

 

void timer_init( void );                 //定时器初始化函数。

void right( void );                               //右转弯函数。

 

uchar percent_l = 0;                           //左轮占空比

uchar percent_r = 0;                           //右轮占空比

 

/******************************************************************** 

 

 函 数 名:timer_init()

 功    能:初始化定时器0

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.13

 修    改:                  日    期: 

***********************************************************************/

void timer_init( void )

{

       TMOD = 0x02;                           //定时器0工作在方式2,定时值自动重载,启动仅受TR0的控制。

       TH0 = 256 - 200;                 //定时周期为 200us * SHELVES

       TL0 = 256 - 200;

 

       EA = 1;                                      //开总中断。

       ET0 = 1;                             //开定时器0中断。

       TR0 = 1;                             //启动定时器0。

}

 

/******************************************************************** 

 

 函 数 名:right()

 功    能:小车右转

 说    明:通过控制左右轮不同的占空比,实现左右转。

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.13

 修    改:                  日    期: 

***********************************************************************/

void right( void )

{

       timer_init();                         //初始化定时器0。

       MOTOR_C = FORWARD;    //方向向前

       percent_r = 5;                      //右轮速度慢。

       percent_l = 8;                      //左轮速度快。

       while( 1 );

}

 

/******************************************************************** 

 

 函 数 名:timer_zero()

 功    能:定时器0中断服务函数

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.12

 修    改:                  日    期: 

***********************************************************************/

void timer_zero( void ) interrupt 1

{

       static uchar temp = 0;                                //中断次数计数,

 

       EA = 0;                                                           //关总中断,屏蔽其他中断。

 

       if(temp < SHELVES)                                        //高电平保持时间。

       {                   

              if(temp < percent_l)

              {

                     PWM_L = 1;                                      //左电机高电平

              }

              else

              {

                     PWM_L = 0;                                      //左电机低电平

              }

 

              if(temp < percent_r)

              {

                     PWM_R = 1;                                     //右电机高电平

              }

              else

              {                  

                     PWM_R = 0;                                     //右电机低电平

              }

 

              temp ++;                                          //实现计数

       }

       else                                                          //一个PWM周期结束,计数清零。

       {

              temp = 0;

       }            

 

       EA = 1;                                                           //开总中断。

}

 

/******************************************************************** 

 

 函 数 名:main()

 功    能:主函数

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.12

 修    改:                  日    期: 

***********************************************************************/

void main()

{

       right();

}

 

 

 

任务5源程序:

/*******************************************************************

 

 公司名称:盛方单片机

 公司网址:www.sfmcu.com

 模块名称:005.c

 功    能:变速前进。            

 说    明:通过定时器0产生PWM调速。

 程序设计:tongwei      

 设计时间:2009.09.13        

 版 本 号: 

*********************************************************************/

#include < reg52.h >

 

#define uchar unsigned char

#define uint unsigned int

 

#define MOTOR_C P0                               //P0口作为电机的控制口。

#define SHELVES 25                                 //速度总档数。

 

#define BACK 0xC6                                   //后退

#define FORWARD 0xA5                           //前进

 

sbit PWM_R = P0^7;                                 //右电机PWM输入口

sbit PWM_L = P0^2;                                 //左电机PWM输入口

 

void timer_init( void );                 //定时器初始化函数。

void right( void );                               //右转弯函数。

 

uchar percent_l = 0;                           //左轮占空比

uchar percent_r = 0;                           //右轮占空比

uint run_time = 0;                               //计时变量

 

 /******************************************************************** 

 

 函 数 名:timer_init()

 功    能:初始化定时器0

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.13

 修    改:                  日    期: 

***********************************************************************/

void timer_init( void )

{

       TMOD = 0x02;                           //定时器0工作在方式2,定时值自动重载,启动仅受TR0的控制。

       TH0 = 256 - 200;                 //定时周期为 200us * SHELVES

       TL0 = 256 - 200;

 

       EA = 1;                                      //开总中断。

       ET0 = 1;                             //开定时器0中断。

       TR0 = 1;                             //启动定时器0。

}

 

/******************************************************************** 

 

 函 数 名:forward()

 功    能:小车直行函数。

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.12

 修    改:                  日    期: 

***********************************************************************/

void change_spe( void )

{

       uchar flog = 0;                            //加减速标志

       timer_init();                         //定时器0初始化。

       MOTOR_C = FORWARD;                  //设置方向,前进

       percent_l = 0;                      //左轮初速度为0;

       percent_r = 0;                      //右轮初速度为0

       while( 1 )

       {

              run_time = 0;                       //计时清零。

              while(run_time < 400);         //让小车以当前速度运行400*5ms

              switch( percent_l )

              {

                     case 0:                         //小车减速最低速度。

                            flog = 1;                //小车加速。

                            break;

                     case 25:                        //小车加速最高速度。

                            flog = 0;                //小车减速。

                            break;

                     default:

                            break;

 

              }

              if( flog )                              //加速,加速度为5。

              {

                     percent_l += 5;

                     percent_r += 5;

              }

              else                                     //减速,加速度为-5。

              {

                     percent_l -= 5;

                     percent_r -= 5;

              }

       }                                 

}

 

/******************************************************************** 

 

 函 数 名:timer_zero()

 功    能:定时器0中断服务函数

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.12

 修    改:                  日    期: 

***********************************************************************/

void timer_zero( void ) interrupt 1

{

       static uchar temp = 0;                                //中断次数计数,

 

       EA = 0;                                                           //关总中断,屏蔽其他中断。

 

       if(temp < SHELVES)                                        //高电平保持时间。

       {                   

              if(temp < percent_l)

              {

                     PWM_L = 1;                                      //左电机高电平

              }

              else

              {

                     PWM_L = 0;                                      //左电机低电平

              }

 

              if(temp < percent_r)

              {

                     PWM_R = 1;                                     //右电机高电平

              }

              else

              {                  

                     PWM_R = 0;                                     //右电机低电平

              }

 

              temp ++;                                          //实现计数

       }

       else                                                          

       {

              temp = 0;                                                 //一个PWM周期结束,计数清零。

              run_time++;                                              //计时加1。

       }            

 

       EA = 1;                                                           //开总中断。

}

 

/******************************************************************** 

 

 函 数 名:main()

 功    能:主函数

 说    明:无

 入口参数:无

 返 回 值:无  

 设    计:tongwei           日    期:2009.09.12

 修    改:                  日    期: 

***********************************************************************/

void main()

{

       change_spe();

}
PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1709946 2012-12-7 17:27

谢谢分享,学习了

用户400850 2011-4-12 15:15

谢谢分享,很实用哪!

用户50170 2010-2-24 13:44

写得很清楚,很适合我们初学者,好文,顶!
相关推荐阅读
用户267451 2010-03-10 21:31
Quartus II软件使用详细的步骤说明(3)
8.按照自己的想法,在新建的VHDL文件中编写VHDL程序。9.代码书写结束后,选择Processing>Start Compilation对编写的代码进行编译,直到编译通过。10.编译通过后,...
用户267451 2010-03-10 21:29
Quartus II软件使用详细的步骤说明(2)
5.按默认选项,点击【Next】出现新建工程以前所有的设定信息,如图2.1.6所示,点击Finish完成新建工程的建立,如图2.1.7所示。6.点击File>New,新建一个VHDL文件。如图2...
用户267451 2010-03-10 21:22
智能车 综合功能演示
一、 实验简介:本程序通过将以前所编写的分立程序通过有机结合,编制成一个大的应用系统。小车在完成自动防撞,防悬崖等动作外,还可以通过红外遥控器进行远程遥控。如果你对电脑编程很有趣兴的话,当然也可以通过...
用户267451 2010-03-04 11:58
智能车 串口通信程序演示
一、 实验简介:本程序通过数码管,LED指示灯的闪亮来表示当前串口通信的结果,串口通信使单片机与电脑之间通信的桥梁,通过对它的学习,可以很好的用电脑来进行单片机的控制,及对单片机数据的采集。因此串口通...
用户267451 2010-02-28 21:54
智能车 红外遥控器解码程序演示
一、 实验简介:本程序主要将现在比较常用M50462遥控器进行解码,将解码后的数据通过P2端口的数码管显示出来,为了更好的看到运行过程,特加了三个指示灯用来指示当前运行状态。P10闪亮,表示程序正在运...
用户267451 2010-02-28 21:52
智能车 红外反射与直流电机驱动演示
一、 实验简介:本程序通过前端,底端的红外发射头和接收头来判断小车的运行轨迹,当前与底端发生信号输入时,信号将被单片机接收,单片机来控制机器按照写好的程序开始运行。同时为达到好的效果,加入声音识别与蜂...
EE直播间
更多
我要评论
1
4
关闭 站长推荐上一条 /3 下一条