前言
当你看到无人机升天、平衡车的落地以及超声波避障等技术的应用,想必已经勾起了你的兴趣!然而这又与STM32技术紧密相关,如果此时你已经决心要加入到STM32的学习当中,想要快速入门那必定少不了51单片机的固基,本章就是对51知识的实际运用!
一、硬件配置
小车车体
芯片STC89C52
L2
L298N电机驱动模块
HC-05蓝牙模块
驱动电源
二、相关接线
1.L298N驱动模块
①OUT1~OUT4:输出端,用于连接电机,注意:“如果用到PWM调速,OUT1和OUT2由使能端ENA控制,OUT3和OUT4由使能端ENB控制。”
②12V:为电源的输入端
③GND:实现L298N与CPU共地(接地)
⑤5V:输出电源的输出端,用于给CPU供电
⑥IN1~IN4:电机控制的输入端,便于CPU对电机的控制
⑦ENA、ENB:使能端口,用于PWM调速
2、HC-05蓝牙模块
①GND: 实现与CPU共地
②VCC:连接CPU的电源引脚,实现蓝牙的通电
③RXD: 信息接收(连接CPU上的TXD)
③TXD: 信息接收(连接CPU上的RXD)
3、接线图解
三、PWM调速
调速的关键在于:“调节占空比”。关键是怎么调节呢?此时,我们会用到定时器,定时器的作用是设定一个周期,只要我们调节在一个周期内,高电平与低电平的占比就可以实现调速。
占空比:就是高电平在一个周期所占的比例。
代码如下:
void time0_uart() interrupt 1
{
TH0=0XFF;
TL0=0X9C;
if(tempt==200)
{
ENA=0;
ENB=0;
tempt=0; //ÖØÐÂÇåÁã
}
if(tempt>pwm_ena)
{
ENA=1;
}
if(tempt<=pwm_ena)
{
ENA=0;
}
if(tempt>pwm_enb)
{
ENB=1;
}
if(tempt<=pwm_enb)
{
ENB=0;
}
tempt++;
}
四、完整代码
定时器初始化 (Time_init()):
void Time0_init() //定时器初始化
{
TMOD|=0X01; //选择定时器0,工作方式1
TH0=0XFF; //给定时器赋初值,定时0.3ms
TL0=0X9C;
ET0=1; //打开定时器0 中断允许
EA=1; //´打开总中断
TR0=1; //打开定时器
}
串口中断初始化(URAT_init()):
void Uart_init()
{
TMOD |=0X20; //设置计数器工作方式2
SCON=0X50; //设置串口为工作方式1
PCON=0X80; //波特率加倍
TH1=0XFA; //波特率9600
TL1=0XFA; //计数器初值设置
TR1=1; //打开计数器
ES=1; //打开接收中断
EA=1; //打开总中断
}
完整代码如下:
#include <REG51.H>
sbit IN1=P1^0;
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;
sbit ENA=P1^4;
sbit ENB=P1^5;
unsigned int pwm_ena=0; //应用于pwm调速
unsigned int pwm_enb=0;
unsigned int tempt=0; //pwm调速的计数值
//void Time0_init() //定时器初始化
//{
// TMOD|=0X01; //选择为定时器0模式,工作方式1,
// TH0=0XFF; //给定时器赋初值,定时0.3ms
// TL0=0X9C;
// ET0=1; //打开定时器0中断允许
// EA=1; //打开总中断
// TR0=1; //打开定时器
//}
void forward(void) //小车前进
{
IN1=1;
IN2=0;
IN3=1;
IN4=0;
pwm_ena=120; //占空比40%
pwm_enb=120;
}
void back(void) //小车后退
{
IN1=0;
IN2=1;
IN3=0;
IN4=1;
pwm_ena=120; //占空比40%
pwm_enb=120;
}
void turn_right(void) //小车右转
{
IN1=1;
IN2=0;
IN3=0;
IN4=1;
pwm_ena=150; //占空比25%
pwm_enb=150;
}
void turn_left(void) //小车左转
{
IN1=0;
IN2=1;
IN3=1;
IN4=0;
pwm_ena=150; //占空比25%
pwm_enb=150;
}
void stop(void) //小车停止
{
IN1=1;
IN2=1;
IN3=1;
IN4=1;
}
//void uart_init()
//{
// TMOD |=0X20; //设置计数器工作方式2
// SCON=0X50; //设置工作方式1
// PCON=0X80; //波特率加倍
//
// TH1=0XFA; //波特率9600
// TL1=0XFA; //计数器初值设置
// TR1=1; //打开计数器
// ES=1; //打开接收中断
// EA=1; //打开总中断
//}
void main()
{
Time0_init();
uart_init();
while(1)
{
}
}
void time0_uart() interrupt 1
{
TH0=0XFF;
TL0=0X9C;
if(tempt==200)
{
ENA=0;
ENB=0;
tempt=0; //ÖØÐÂÇåÁã
}
if(tempt>pwm_ena)
{
ENA=1;
}
if(tempt<=pwm_ena)
{
ENA=0;
}
if(tempt>pwm_enb)
{
ENB=1;
}
if(tempt<=pwm_enb)
{
ENB=0;
}
tempt++;
}
void uart() interrupt 4
{
unsigned char S;
if(RI==1)
{
stop();
S=SBUF;
switch(S)
{
case ('1'):
forward();break;
case ('2'):
back();break;
case ('3'):
turn_right();break;
case ('4'):
turn_left();break;
case ('0'):
stop();break;
}
RI=0;
}
}
之所以会有注释那部分,主要在于:“我应用了模块化编程” ,还需注意的是定时器,我定时为0.3ms,建议:“如果刚刚开始调速,可能会出现一顿一顿的情况,此时你可以,将定时器的计时周期时间减小,然后慢慢调节,直至消除一顿一顿的现象”
总结
以上是我学习并实践后,对51小车制作的讲解,本章只是简单的介绍了PWM调速,而且PWM调速也是学习51后要进行掌握的,以上只是提供一个参考的程序,具体该如何的调速以及代码的编程还需要借鉴者的自身感悟还有知识的掌握程度等等,希望我的文章可以给正在开发的你带来些许灵感,踏上51的毕业之路!