51单片机使用L298驱动JGB37-520编码器电机用pwm调节电机速度,并实现正反转,测量电机速度(编码器adc0832)并使用lcd显示转速代码
时间: 2023-06-24 13:05:56 浏览: 155
基于51单片机的PWM电机转速控制
以下是使用C语言在51单片机上驱动L298驱动JGB37-520编码器电机,并通过PWM调节电机速度并实现正反转的代码。这里假设使用的是ADC0809,其他型号的ADC也可以根据相应的数据手册进行修改。
```c
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit ENA = P2^0; // L298使能端口
sbit ENB = P2^1;
sbit IN1 = P2^2; // L298输入端口
sbit IN2 = P2^3;
sbit IN3 = P2^4;
sbit IN4 = P2^5;
sbit EOC = P3^4; // ADC0832结束转换标志
sbit CLK = P3^5; // ADC0832时钟
sbit DIO = P3^6; // ADC0832数据
sbit RS = P1^0; // LCD1602端口定义
sbit RW = P1^1;
sbit EN = P1^2;
sbit K1 = P1^3; // 按键端口
sbit K2 = P1^4;
sbit K3 = P1^5;
sbit K4 = P1^6;
sbit K5 = P1^7;
float speed = 0; // 转速值
void delay(uint t) // 延时函数
{
uint i, j;
for(i = 0; i < t; i++)
for(j = 0; j < 110; j++);
}
void LCD_Write_Com(uchar com) // 写入指令函数
{
RS = 0;
RW = 0;
P0 = com;
EN = 1;
delay(5);
EN = 0;
}
void LCD_Write_Data(uchar dat) // 写入数据函数
{
RS = 1;
RW = 0;
P0 = dat;
EN = 1;
delay(5);
EN = 0;
}
void LCD_Init() // 初始化LCD1602函数
{
LCD_Write_Com(0x38);
LCD_Write_Com(0x0c);
LCD_Write_Com(0x06);
LCD_Write_Com(0x01);
}
void ADC0832_Init() // 初始化ADC0832函数
{
CLK = 0;
DIO = 1;
delay(10);
}
uchar ADC0832_Read(uchar ch) // 读取ADC0832函数
{
uchar i, dat = 0;
CLK = 0;
DIO = 1;
delay(1);
CLK = 1;
delay(1);
CLK = 0;
delay(1);
DIO = 0;
delay(1);
CLK = 1;
delay(1);
CLK = 0;
delay(1);
DIO = ch;
delay(1);
CLK = 1;
delay(1);
CLK = 0;
delay(1);
for(i = 0; i < 8; i++)
{
CLK = 1;
delay(1);
CLK = 0;
delay(1);
dat <<= 1;
dat |= DIO;
}
return dat;
}
void Motor_Control(uchar LSpeed, uchar RSpeed) // 电机控制函数
{
ENA = 1;
ENB = 1;
if(LSpeed > 0) // 左电机正转
{
IN1 = 1;
IN2 = 0;
}
else if(LSpeed < 0) // 左电机反转
{
IN1 = 0;
IN2 = 1;
}
else // 左电机停止
{
IN1 = 0;
IN2 = 0;
}
if(RSpeed > 0) // 右电机正转
{
IN3 = 1;
IN4 = 0;
}
else if(RSpeed < 0) // 右电机反转
{
IN3 = 0;
IN4 = 1;
}
else // 右电机停止
{
IN3 = 0;
IN4 = 0;
}
}
void main()
{
uchar ch, LSpeed, RSpeed, LDir, RDir, i;
ADC0832_Init(); // 初始化ADC0832
LCD_Init(); // 初始化LCD1602
Motor_Control(0, 0); // 初始化电机
while(1)
{
ch = ADC0832_Read(0); // 读取ADC0832
speed = (float)ch / 255 * 2000; // 计算转速值
LCD_Write_Com(0x80); // 显示转速值
LCD_Write_Data('S');
LCD_Write_Data('p');
LCD_Write_Data('e');
LCD_Write_Data('e');
LCD_Write_Data('d');
LCD_Write_Data(':');
LCD_Write_Data((int)speed/1000 + '0');
LCD_Write_Data(((int)speed%1000)/100 + '0');
LCD_Write_Data(((int)speed%100)/10 + '0');
LCD_Write_Data('.');
LCD_Write_Data(((int)(speed*10)%10) + '0');
if(K1 == 0) // K1按下,电机正转
{
LSpeed = 100;
RSpeed = 100;
LDir = 1;
RDir = 1;
}
else if(K2 == 0) // K2按下,电机反转
{
LSpeed = -100;
RSpeed = -100;
LDir = 0;
RDir = 0;
}
else if(K3 == 0) // K3按下,电机左转
{
LSpeed = -100;
RSpeed = 100;
LDir = 0;
RDir = 1;
}
else if(K4 == 0) // K4按下,电机右转
{
LSpeed = 100;
RSpeed = -100;
LDir = 1;
RDir = 0;
}
else // K5按下或未按键,电机停止
{
LSpeed = 0;
RSpeed = 0;
LDir = 0;
RDir = 0;
}
if(LDir != RDir) // 电机旋转方向不同,取最小转速
{
if(abs(LSpeed) < abs(RSpeed))
RSpeed = abs(LSpeed) * RSpeed / LSpeed;
else
LSpeed = abs(RSpeed) * LSpeed / RSpeed;
}
Motor_Control(LSpeed, RSpeed); // 控制电机
}
}
```
这里使用了ADC0832来读取编码器电机的速度,通过PWM控制电机的速度。同时,通过LCD1602显示电机的转速。此外,还实现了K1-K4按键来控制电机的正反转和左右转向,K5按键用来停止电机。
阅读全文