通过设计进一步掌握51单片机的应用,特别是在嵌入式系统中的应用。进一步学习51单片机在系统中的控制功能,能够合理设计单片机的外围电路,并使之与单片机构成整个系统。
制作方案
该小车采用蓝牙模块对单片机进行控制,单片机根据采集到的信号的不同状态判断小车当前状态,通过电机驱动芯片L298N发出控制命令,控制电机的工作状态以实现对小车姿态片机的外围电路,并使之与单片机构成整个系统的控制。本次设计的蓝牙小车可实现9种状态:前进、后退、左转、右转、加速、减速、左漂、右漂、停止。设计构思结构如图下所示。
单片机源程序如下:
/*****************************************************/
/********版权所有:电子科技协会--岚 **********/
/********** 蓝牙遥控变速小车 ************************/
// 接口连接:
// 电机接口(4电机两两相连 并为两组)
// P0.2和P0.3-----右电机
// P0.0和P0.1-----左电机
// P0.4-----------通道使能A
// P0.5-----------通道使能B
/*****************************************************/
#include <reg52.h> //调用reg52头文件
//宏定义
#define uchar unsigned char /*宏定义将unsigned char 用uchar代替,表示无符号字节型,char类型变量的大小通常为1个字节*/
#define uint unsigned int /*宏定义将unsigned int用uint代替,表示无符号整型,int类型变量的大小通常为4个字节*/
/////////////////////////////////////
uchar n='0',num0=0,num1=0; /*给n,num0,num1赋予初始值0*/
char zuo_pwm = 40,you_pwm = 40; /*使单片机的定时器功能来产生稳定的PWM(40Hz)脉冲波*/
/*定义P0.1,2,3,4口为控制驱动信号的I/O口*/
sbit zuo1=P0^0;
sbit zuo2=P0^1;
sbit you1=P0^2;
sbit you2=P0^3;
//定义P0.4,5口为通道使能A,B分别控制左右各两轮的速度
sbit ENA=P0^4;
sbit ENB=P0^5;
sbit d1=P1^0;
sbit d2=P1^1;
sbit d3=P1^2;
sbit d4=P1^3;
sbit x1=P1^7;
sbit dd=P1^6;
/* 函数功能:设置串口*/
void init() //单片机串口初始化函数
{
d1=1;d2=1;d3=1;d4=1;x1=0;dd=1;
TMOD=0x21; //定时器1工作模式
SCON=0x50;
//设置串口方式1且允许串口接收。
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x91; //设置定时初值
TH0 = 0xFF; //设置定时初值
TH1=0xfd; //设置初值为0xfd,波特率是9600bps
TL1=0xfd;
EA=1; //打开总中断
ET0=1; //打开定时器0中断允许
TR1=1; //定时器1开始计时
TR0=1; //定时器0开始计时
ES=1; //打开接收中断
}
/*********小车状态函数**********/
/********************************************************************
* 名称 : qianjin()
* 功能 : 左右电机启动,都是前进,整车表现为前进。
***********************************************************************/
void qian ()
{
zuo_pwm=20; //左轮调速为全速的50%
you_pwm=20; //右轮调速为全速的50%
zuo1=1;
zuo2=0;
you1=1;
you2=0;
}
/********************************************************************
* 名称 :jiansu ()
* 功能 : 左右电机启动,都是前进,整车表现为低速前进。
***********************************************************************/
void jiansu ()
{
zuo_pwm=10; //左轮调速为全速的20%
you_pwm=10; //左轮调速为全速的20%
zuo1=1;
zuo2=0;
you1=1;
you2=0;
}
/********************************************************************
* 名称 :jiasu ()
* 功能 : 左右电机启动,都是前进,整车表现为全速前进。
***********************************************************************/
void jiasu ()
{
zuo_pwm=40;//左轮调速为全速的100%
you_pwm=40;//左轮调速为全速的100%
zuo1=1;
zuo2=0;
you1=1;
you2=0;
}
/********************************************************************
* 名称 :hou ()
* 功能 : 左右电机启动,都是后退,整车表现为后退。
***********************************************************************/
void hou ()
{
zuo_pwm=30;//左轮调速为全速的75%
you_pwm=30;//左轮调速为全速的75%
zuo1=0;
zuo2=1;
you1=0;
you2=1;
}
/********************************************************************
* 名称 :zuozhuan()
* 功能 : 左右电机启动,左轮后退,右轮前进,整车表现为低速左转。
***********************************************************************/
void zuozhuan()
{
zuo_pwm = 13;//左轮调速为全速的20%
you_pwm = 13;//左轮调速为全速的32.5%
zuo1=0;
zuo2=1;
you1=1;
you2=0;
}
/********************************************************************
* 名称 :youzhuan()
* 功能 : 左右电机启动,左轮前进,右轮后退,整车表现为低速右转。
***********************************************************************/
void youzhuan()
{
zuo_pwm = 13;//左轮调速为全速的32.5%
you_pwm = 13;//右轮调速为全速的20%
zuo1=1;
zuo2=0;
you1=0;
you2=1;
}
/********************************************************************
* 名称 :youpiao()
* 功能 : 只有右电机启动,右轮后退,左轮不转,整车表现为右漂(由于速度慢表现不明显)。
***********************************************************************/
void youpiao()
{
zuo_pwm=35;//左轮调速为全速的87.5%
you_pwm=35;//左轮调速为全速的87.5%
zuo1=0;
zuo2=0;
you1=0;
you2=1;
}
/********************************************************************
* 名称 :zuopiao()
* 功能 : 只有左电机启动,右轮不转,左轮后退,整车表现为左漂(由于速度慢表现不明显)。
***********************************************************************/
void zuopiao()
{
zuo_pwm=35; //左轮调速为全速的87.5%
you_pwm=35; //左轮调速为全速的87.5%
zuo1=0;
zuo2=1;
you1=0;
you2=0;
}
/********************************************************************
* 名称 :stop ()
* 功能 : 左右电机都不启动,左右轮都不转,整车表现为停止。
***********************************************************************/
void stop ()
{
zuo1=0;
zuo2=0;
you1=0;
you2=0;
}
/*主函数*/
void main ()
{
init (); //初始化
while (1) //循环函数
{
switch (n) //蓝牙控制,switch(表达式),case(常量表达式 )
{
case '2':qian ();d1=0;d2=0;d3=1;d4=1; break;//接收手机串口发送的指令2 执行前进函数 控制小车前进 执行后退出switch
case '3':jiansu ();d1=0;d2=0;d3=0;d4=0; break;//接收手机串口发送的指令3 执行减速函数 控制小车低速 执行后退出switch
case '4':jiasu ();d1=0;d2=0;d3=1;d4=1; break;//接收手机串口发送的指令4 执行加速函数 控制小车全速 执行后退出switch
case '5':hou ();d1=1;d2=1;d3=0;d4=0; break;//接收手机串口发送的指令5 执行后退函数 控制小车后退 执行后退出switch
case '6':zuozhuan ();d1=1;d2=0;d3=1;d4=0;break;//接收手机串口发送的指令6 执行左转函数 控制小车左转 执行后退出switch
case '7':youzhuan ();d1=0;d2=1;d3=0;d4=1;break;//接收手机串口发送的指令7 执行右转函数 控制小车右转 执行后退出switch
case '8':zuopiao();d1=0;d2=0;d3=0;d4=0; break;//接收手机串口发送的指令8 执行左漂函数 控制小车左漂 执行后退出switch
case '9':youpiao();d1=0;d2=0;d3=0;d4=0; break;//接收手机串口发送的指令9 执行右漂函数 控制小车右漂 执行后退出switch
case '0':stop();d1=0;d2=0;d3=0;d4=0;x1=0;break;//接收手机串口发送的指令0 执行停止函数 控制小车停止 执行后退出switch
case '1':x1=1;d1=1;d2=1;d3=0;d4=0; break;
case 'A':x1=0;d1=1;d2=1;d3=1;d4=1; break;
case 'B':dd=0;d1=0;d2=0;d3=0;d4=0; break;
case 'C':dd=1;d1=1;d2=1;d3=1;d4=1; break;
default:break; //未接收到指令直接退出switch
}
}
}
/* 函数功能:设置串口*/
void UART_SER()interrupt 4 //串行口中断函数
{
if (RI)//判断是接收中断产生
{
RI=0; //读标志位清零
n=SBUF;//读入缓冲区的值
TI=1; //TI=1时,执行下面的程序
SBUF=n;//将内容返回到手机端,可在手机查看发送的内容
}
if (TI) //如果是发送标志位,写标志位清零
TI=0;
}
//定时器0中断函数
void Timer1Interrupt(void) interrupt 1 //指明是定时器中断0
{
TL0 = 0x91; //设置定时初值
TH0 = 0xFF; //设置定时初值
num0++; //PWM调占空比
num1++;
if(num0 <= zuo_pwm) //判num0是否小于等于zuo_pwm,
{ ENA=1; } //若是通道使能A打开
else ENA = 0; //若否通道使能B关闭
if(num0 == 40) //判断num0是否达到40
{
ENA = ~ENA; //若是通道使能A状态取反
num0 = 0; //将num0的值归为0
}
if(num1 <= you_pwm) //判num1是否小于等于you_pwm,
{
ENB = 1; //若是通道使能B打开
}
else ENB = 0; //若否通道使能B关闭
if(num1 == 40) //判断num1是否达到40
{
ENB = ~ENB; //若是通道使能B状态取反
num1 = 0; //将num1的值归为0
}
}
完整的Word格式文档51黑下载地址:
蓝牙遥控小车.docx
(1.16 MB, 下载次数: 42)
|