51单片机使用L298驱动JGB37-520编码器电机用pwm调节电机速度,并实现正反转,测量电机速度并使用lcd显示转速代码
时间: 2023-06-26 21:03:18 浏览: 832
下面是51单片机使用L298驱动JGB37-520编码器电机用pwm调节电机速度,并实现正反转,测量电机速度并使用lcd显示转速的代码:
```c
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
// 电机控制端口定义
sbit ENA = P1^0;
sbit ENB = P1^1;
sbit IN1 = P1^2;
sbit IN2 = P1^3;
sbit IN3 = P1^4;
sbit IN4 = P1^5;
// LCD1602控制端口定义
sbit RS = P0^0;
sbit RW = P0^1;
sbit EN = P0^2;
#define LCD_DataPort P2
// 编码器引脚定义
sbit ENCODER_A = P3^6;
sbit ENCODER_B = P3^7;
// 定义全局变量
uchar speed = 0; // 当前速度
uchar direction = 1; // 当前方向,1为正转,0为反转
uint count = 0; // 编码器计数器
uint lastCount = 0; // 上一次计数器的值
uint rotationSpeed = 0; // 转速
// LCD1602底层函数
void delay(uint n)
{
while (n--);
}
void writeCommand(uchar command)
{
RS = 0;
RW = 0;
LCD_DataPort = command;
EN = 1;
_nop_();
_nop_();
EN = 0;
delay(5);
}
void writeData(uchar data)
{
RS = 1;
RW = 0;
LCD_DataPort = data;
EN = 1;
_nop_();
_nop_();
EN = 0;
delay(5);
}
void initLCD()
{
writeCommand(0x38); // 8位数据接口,5x7点阵,两行显示
writeCommand(0x0C); // 显示开,无光标,不闪烁
writeCommand(0x06); // 光标右移,字符不移动
writeCommand(0x01); // 清屏
}
// 编码器中断函数
void encoderInterrupt() interrupt 0
{
if (ENCODER_A != ENCODER_B)
{
count++;
}
else
{
count--;
}
}
// PWM输出函数
void pwmOutput(uchar dutyCycle)
{
if (dutyCycle > 100)
{
dutyCycle = 100;
}
TH0 = 256 - 110 * dutyCycle / 100;
TL0 = TH0;
TR0 = 1;
}
// 主函数
void main()
{
initLCD();
// 初始化定时器0
TMOD |= 0x01; // 16位定时器
TH0 = 0xFC; // 50us定时
TL0 = TH0;
ET0 = 1; // 开启定时器0中断
// 初始化编码器中断
IT0 = 1; // 下降沿触发
EX0 = 1; // 开启INT0中断
// 初始化电机控制端口
ENA = 1;
ENB = 1;
IN1 = 0;
IN2 = 1;
IN3 = 0;
IN4 = 1;
// 主循环
while (1)
{
if (count != lastCount)
{
rotationSpeed = count - lastCount;
lastCount = count;
}
if (rotationSpeed < 0)
{
rotationSpeed = -rotationSpeed;
}
speed = rotationSpeed * 60 / 11;
if (speed > 255)
{
speed = 255;
}
pwmOutput(speed);
if (direction)
{
IN1 = 0;
IN2 = 1;
IN3 = 0;
IN4 = 1;
}
else
{
IN1 = 1;
IN2 = 0;
IN3 = 1;
IN4 = 0;
}
writeCommand(0x80); // 第一行
writeData('S');
writeData('p');
writeData('e');
writeData('e');
writeData('d');
writeData(':');
writeData(speed / 100 + '0');
writeData(speed % 100 / 10 + '0');
writeData(speed % 10 + '0');
writeData(' ');
writeData(' ');
writeData(' ');
writeCommand(0xC0); // 第二行
writeData('D');
writeData('i');
writeData('r');
writeData(':');
writeData(direction ? '+' : '-');
writeData(' ');
writeData(' ');
writeData(' ');
writeData(' ');
writeData(' ');
writeData(' ');
delay(100);
}
}
```
需要注意的是,本代码使用了编码器中断来实时测量电机转速,因此需要将编码器的A相和B相分别连接到单片机的P3.6和P3.7引脚,并在主函数中开启INT0中断。同时,需要根据实际情况修改计算转速的系数。
阅读全文