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

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

——用程序来控制轮子

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

这个图中,输入有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文件,专门编写控制小车的程序:

 

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

#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了。

  1. 如果发现某个状态不对,可以把程序单独调这个状态,然后跟据上面的表格,从单片机输出,到场效管引脚,用万用表一步步量,就可以看到哪步上有问题。
  2. 如果发现正反转不对,反了。那就简单,可以把 CarGo 函数控制0和1的地方反写一下即可。

 

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

换句话说,我们要针对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文件,就可以收功了,后面只需要调用一下这里面的函数,就可以相应的来控制小车的电机了。

 

 

转载于:https://www.cnblogs.com/zjfstudio/p/3841616.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值