码迷,mamicode.com
首页 > 其他好文 > 详细

自己动手做个智能小车(5)

时间:2014-07-15 08:56:19      阅读:371      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   strong   文件   

自己动手做个智能小车(5)

——用程序来控制轮子

PWM控制电路完工了,接下来得把电路接到单片机,由单片机进行控制了。回想电路图:

bubuko.com,布布扣

这个图中,输入有3根组,A,B,C,其中,A入口,我们可以当成PWM控制线,B,C为正反转、停止控制线,整个状态可以罗列为下面表格:

A控制

B控制

C控制

Q1

Q2

Q3

Q4

电机状态

X

0

0

0/导通

0/导通

0/截止

0/截止

刹车

PWM

1

0

1/截止

0/导通

PWM

0/截止

正转

PWM

0

1

0/导通

1/截止

0/截止

PWM

反转

0

1

1

1/截止

1/截止

0/截止

0/截止

惰行

1

1

1

1/截止

1/截止

1/导通

1/导通

刹车

?

为了方便代码管理,我们在工程中建一个car.c和car.h文件,专门编写控制小车的程序:

bubuko.com,布布扣

?

程序开始,引入相应头文件:

#include<reg52.h>

#include "common.h"

#include "car.h"

?

定义好PWM电路的接入引脚:

sbit Ctl_R1=P2^4; //右轮控制端1

sbit Ctl_R2=P2^5; //右轮控制端2

sbit PWM_R=P2^3; //右轮PWM

?

sbit Ctl_L1=P2^2; //左轮控制端1

sbit Ctl_L2=P2^1; //左轮控制端2

sbit PWM_L=P2^0; //左轮PWM

?

为了代码清楚,我们将car这个(对象),整成2个函数:

void InitCar()

{

}

?

void CarGo(int left,int right)

{

}

将两个函数的函数体写入到car.c中,将函数的定义,写入到car.h中。

两个函数分别意义为:InitCar为小车初使化,CarGo为小车控制,参数left、right分别代表左右轮,然后值为-100~100,当为0时,则停止,当为负数时,则反转,数值大小代表转动速度,值越大越快。

好了,测试工作总是逐步的,而不是一步到位,我们先来试一下基本的正反转及停,调速的后面再来。

void InitCar()

{

CarGo(0,0);

PWM_R = 1;

PWM_L = 1;

}

void CarGo(int left,int right)

{

if ( right >0)

{

Ctl_R1=0;

Ctl_R2=1;

}

else if (right ==0)

{

Ctl_R1=0;

Ctl_R2=0;

}

else if (right<0)

{

Ctl_R1=1;

Ctl_R2=0;

}

?

if ( left >0)

{

Ctl_L1=0;

Ctl_L2=1;

}

else if (left ==0)

{

Ctl_L1=0;

Ctl_L2=0;

}

else if (left<0)

{

Ctl_L1=1;

Ctl_L2=0;

}

}

好了,简单的程序,应该很容易能看懂,测试么,得写个main函数咯。

#include "car.h"

#include "common.h"

?

void main()

{

//小车初使化

InitCar();

CarGo(100,0);

Delay(2000);

CarGo(0,100);

Delay(2000);

CarGo(-100,0);

Delay(2000);

CarGo(0,-100);

Delay(2000);

CarGo(0,0);

}

经常会用到一些通用函数,如里面的delay之类的,所以我们又建一个common.c和common.h文件,将一些通用的方法写入,比如这里的:

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

* 函数功能:延时若干毫秒

* 入口参数:n

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

void Delay(unsigned int i)

{

unsigned int j;

for(;i>0;i--) //变量i由实际参数传入一个值,因此i不能赋初值

for(j=0;j<125;j++)

{;}

}

?

整个程序也容易看清的,每隔2秒后,可以看到电机会变换一个状态。将程序烧写到单片机中,运行,观察吧。

如果发现状态不对,那就得debug了。

?

一切调通后,就剩下PWM了,上一章中,我们知道速度通过占空比来实现的。

bubuko.com,布布扣

换句话说,我们要针对PWM引脚要连续的输出0和1变换值。所以这里我们得引入单片的计数器和中断。

TH0和TL0是计数器0的高8位和低8位计数器,计算办法:TL0=(65536-C)%256;TH0=(65536-C)/256,其中C为所要计数的次数即多长时间产生一次中断;TMOD是计数器工作模式选择,0X01表示选用模式1,它有16位计数器,最大计数脉冲为65536,最长时间为1ms*65536=65.536ms

#define V_TH0 0XFE

#define V_TL0 0XF6

#define V_TMOD 0X01

unsigned char ZKB1,ZKB2;

void InitCar()

{

CarGo(0,0);

?

/*定时器初始化 */

TMOD=V_TMOD;

TH0=V_TH0;

TL0=V_TL0;

TR0=1;

ET0=1;

EA=1;

?

ZKB1 = 0;

ZKB2 = 0;

}

?

?

/*中断函数 */

void timer0(void) interrupt 1 using 2

{

static uchar click=0; //中断次数计数器变量

TH0=V_TH0; //恢复定时器初始值

TL0=V_TL0;

++click;

if (click>=100)

click=0;

?

if (click<=ZKB1) //当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整

PWM_R=0;

else

PWM_R=1;

?

if (click<=ZKB2) //当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整

PWM_L=0;

else

PWM_L=1;

}

?

说明:iitcar中对定时器进行初使化。timer0函数中不对的计数,当click计值到ZKB1时,把PWM值反转一下。这个ZKB1在就是在CarGo中赋值的left,right值的绝对值。

OK,到此,这个Car.c文件,就可以收功了,后面只需要调用一下这里面的函数,就可以相应的来控制小车的电机了。

?

?

自己动手做个智能小车(5),布布扣,bubuko.com

自己动手做个智能小车(5)

标签:style   blog   http   color   strong   文件   

原文地址:http://www.cnblogs.com/zjfstudio/p/3841616.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!