一、小车的拼装
如图所示:
黑色电池盒正负极和白色电池盒正负极连接,L9110s点击正负极与白色电池盒连接,上官一号正负极与白色电池盒连接,
注意:千万不要把电机的正负极接反,接电0.5秒就冒烟
二、让小车动起来
代码如下:
#include "reg52.h"
#include "intrins.h"
sbit RightCon1A = P3^2;//右轮
sbit RightCon1B = P3^3;
sbit LeftCon1A = P3^4;//左轮
sbit LeftCon1B = P3^5;
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void goForward(){//前进
LeftCon1A = 0;
LeftCon1B = 1;
RightCon1A = 0;
RightCon1B = 1;
}
void goLeft(){//左转
LeftCon1A = 0;
LeftCon1B = 0;
RightCon1A = 0;
RightCon1B = 1;
}
void goRight(){//右转
LeftCon1A = 0;
LeftCon1B = 1;
RightCon1A = 0;
RightCon1B = 0;
}
void goBack(){//后退
LeftCon1A = 1;
LeftCon1B = 0;
RightCon1A = 1;
RightCon1B = 0;
}
void main()
{
while(1){
goForward();
Delay1000ms();
Delay1000ms();
Delay1000ms();
Delay1000ms();
Delay1000ms();
goBack();
Delay1000ms();
Delay1000ms();
goLeft();
Delay1000ms();
Delay1000ms();
goRight();
Delay1000ms();
Delay1000ms();
}
}
三、实现串口控制小车
代码如下:
#include "reg52.h"
#include "motor.h"
#include <string.h>
#define SIZE 12
sfr AUXR = 0X8E;
char buffer[SIZE];
void UartInit(void){
AUXR = 0X8E;
SCON = 0X50;
EA = 1;
ES = 1;
TMOD &= 0X0F;
TMOD |= 0X20;
TH1 = 0XFD;
TL1 = 0XFD;
TR1 = 1;//启动定时器
}
//M1 前,M2后,M3 左,M4 右
void Uart_Handler() interrupt 4 //中断处理函数
{
static int i = 0;//静态变量,被初始化一次
char tmp;//定义一个临时的字符变量,用于接收信息
if(RI)//中断处理函数中,对于接收中断的响应
{
RI = 0;//清除接收中断标志位
tmp = SBUF; //让字符变量接收寄存器传递出来的信息(它是一个字节寻址的寄存器,字节地址为99H,通常用于存储一个字符的数据大小?)
//tmp只能接收一个字母,SBUF也是一个字节一个字节的输出数据和接收数据
if(tmp == 'M')//注意是M开头的
{
i = 0; //每次接收到信息都让i等于0,用于表示数组的第一位
}
buffer[i++] = tmp; //给buffer数组赋值,接下来把temp接收的数据都存到buffer数组中
if(buffer[0] == 'M'){
switch(buffer[1]){
case '1':
goForward();
break;
case '2':
goBack();
break;
case '3':
goLeft();
break;
case '4':
goRight();
break;
default:
stop();
break;
}
}
if(i==12){
memset(buffer,'\0',SIZE);//清空内容
i=0;//越界
}
}
if(TI);
}
代码控制小车完成之后,在开发板接上蓝牙模块,就可以实现蓝牙控制小车
四、PWM小车调速
代码如下:
#include "reg52.h"
#include "motor.h"
char speed;
char cnt = 0;
void Time0Init(){
//1、配置定时器0工作模式位16位计时
TMOD = 0X01;
//2、给初值,定一个0.5ms出来
TL0 = 0X33;
TH0 = 0XFE;
//3、开始计时
TR0 = 1;
TF0 = 0;//赋初值
//4、打开定时器0终端
ET0 = 1;
//5、打开总终端
EA = 1;
}
void Time0Handler() interrupt 1//定时器0的中中断查询序列是1
{
cnt++;//统计爆表次数,cnt=1的时候,爆表了1次
//重新给初值
TL0 = 0X33;
TH0 = 0XFE;
//控制PWM波
if(cnt < speed){ //第一次cnt>10,第二次cnt20,第三次cnt>40,执行全速前进函数,剩下的执行停止函数
//前进
goForward();
}else{
//停止
stop();
}
if(cnt == 40){//爆表40次,总共经过了20ms
cnt = 0;//当100次表示1s,重新让cnt从1开始,计算下一次的1s
}
}
void main()
{
Time0Init();
UartInit();
Delay1000ms();
while(1){
speed = 10;//十份全速运行,三十份停止,所以慢,20ms是40份的500us=0.5ms,
//相当于在20ms里面,有0.5*10=5ms的时间是全速前进,而剩下的15ms的时间是在停止
Delay1000ms();
Delay1000ms();
speed = 20;
Delay1000ms();
Delay1000ms();
speed = 40;
Delay1000ms();
Delay1000ms();
}
}
五、PWM方式实现小车转向
原理: 左轮定时器0调速,右轮定时器1调速,那么左转就是右轮速度大于左轮!
代码如下:
//main.c
void main()
{
Time0Init(); Time1Init();
//UartInit();
while(1){
speedLeft = 10;//10份单位时间全速运行,30份停止,所以慢,20ms是40份的500us
speedRight = 40;
Delay1000ms();
Delay1000ms();
speedLeft = 40;
speedRight = 10;
Delay1000ms();
Delay1000ms();
}
}
//time.c
#include "motor.h"
#include "reg52.h"
char speedLeft;
char cntLeft = 0;
char speedRight;
char cntRight = 0;
void Time1Init()
{
//1. 配置定时器1工作模式位16位计时
TMOD &= 0x0F;
TMOD |= 0x1 << 4;
//2. 给初值,定一个0.5出来
TL1=0x33;
TH1=0xFE;
//3. 开始计时
TR1 = 1;
TF1 = 0;
//4. 打开定时器1中断
ET1 = 1;
//5. 打开总中断EA
EA = 1;
}
void Time0Init()
{
//1. 配置定时器0工作模式位16位计时
TMOD = 0x01;
//2. 给初值,定一个0.5出来
TL0=0x33;
TH0=0xFE;
//3. 开始计时
TR0 = 1;
TF0 = 0;
//4. 打开定时器0中断
ET0 = 1;
//5. 打开总中断EA
EA = 1;
}
void Time1Handler() interrupt 3
{
cntRight++; //统计爆表的次数. cnt=1的时候,报表了1
//重新给初值
TL1=0x33;
TH1=0xFE;
//控制PWM波
if(cntRight < speedRight){
//右前进
goForwardRight();
}else{
//停止
stopRight();
}
if(cntRight == 40){//爆表40次,经过了20ms
cntRight = 0; //当100次表示1s,重新让cnt从0开始,计算下一次的1s
}
}
void Time0Handler() interrupt 1
{
cntLeft++; //统计爆表的次数. cnt=1的时候,报表了1
//重新给初值
TL0=0x33;
TH0=0xFE;
//控制PWM波
if(cntLeft < speedLeft){
//左前进
goForwardLeft();
}else{
//停止
stopLeft();
}
if(cntLeft == 40){//爆表40次,经过了20ms
cntLeft = 0; //当100次表示1s,重新让cnt从0开始,计算下一次的1s
}
}