第二节 小车前进、后退、转弯、变速实验
电机驱动板的控制端与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; //开总中断。
}
用户1709946 2012-12-7 17:27
用户400850 2011-4-12 15:15
用户50170 2010-2-24 13:44