51单片机使用L298驱动(只用一个电机)JGB37-520编码器电机用pwm调节电机速度,并实现正反转,测量电机速度(编码器adc0832)并使用lcd显示转速代码
时间: 2023-06-20 22:10:22 浏览: 159
以下是基于51单片机使用L298驱动JGB37-520编码器电机的代码,可以实现PWM调节电机速度、正反转以及测量电机速度并用LCD显示转速。
```
#include <reg51.h>
#define FREQ_OSC 11059200UL
#define BAUDRATE 9600
#define MOTOR_PIN P1
#define ENCODER_PIN P2
#define LCD_PIN P0
sbit RS = P0^0;
sbit RW = P0^1;
sbit EN = P0^2;
unsigned int motor_speed;
unsigned int timer_count;
unsigned char direction;
//函数声明
void Init_Timer0(void);
void Init_ADC0832(void);
void Init_LCD(void);
void Write_Command(unsigned char cmd);
void Write_Data(unsigned char dat);
void Write_String(unsigned char code *s);
void main(void)
{
unsigned int pwm_value;
unsigned char i;
Init_Timer0();
Init_ADC0832();
Init_LCD();
while(1)
{
for(i = 0; i < 100; i++) //PWM占空比从0到100循环调节电机速度
{
pwm_value = i * 10;
MOTOR_PIN = 0x00; //电机停止
//设置PWM占空比
if(pwm_value > 0 && pwm_value < 1000)
{
TMOD |= 0x02; //使用定时器1作为PWM输出
TH1 = 0x00;
TL1 = 0x00;
TR1 = 1; //启动定时器1
MOTOR_PIN = 0x01; //电机正转
direction = 0x01; //记录电机方向
}
else if(pwm_value > 1000 && pwm_value < 2000)
{
TMOD |= 0x02; //使用定时器1作为PWM输出
TH1 = 0x00;
TL1 = 0x00;
TR1 = 1; //启动定时器1
MOTOR_PIN = 0x02; //电机反转
direction = 0x02; //记录电机方向
}
else
{
TR1 = 0; //关闭定时器1
}
TH0 = 0x00;
TL0 = pwm_value / 256; //设置定时器0初值
TR0 = 1; //启动定时器0
while(timer_count == 0); //等待定时器0计数完成
TR0 = 0; //关闭定时器0
timer_count = 0; //清零定时器计数
ADCF = 0; //启动ADC0832转换
while(ADCF == 0); //等待转换完成
motor_speed = ADRESH * 256 + ADRESL; //读取电机速度
Write_Command(0x80); //光标回到第一行第一列
Write_String("Speed: ");
Write_Data((motor_speed / 100) % 10 + '0'); //显示百位数字
Write_Data((motor_speed / 10) % 10 + '0'); //显示十位数字
Write_Data(motor_speed % 10 + '0'); //显示个位数字
Write_String(" RPM "); //显示单位
}
}
}
void Init_Timer0(void)
{
TMOD &= 0xF0; //清除定时器0模式位
TMOD |= 0x01; //设置定时器0为16位自动重载模式
TH0 = 0x00;
TL0 = 0x00; //设置定时器0初值
ET0 = 1; //使能定时器0中断
EA = 1; //使能总中断
}
void Init_ADC0832(void)
{
ADCON = 0x80; //选择ADC0832的AN0输入
ADCF = 0; //清除ADC转换完成标志
}
void Init_LCD(void)
{
Write_Command(0x38); //设置16*2显示模式
Write_Command(0x0C); //关闭光标
Write_Command(0x06); //设置光标移动方向
Write_Command(0x01); //清屏
}
void Write_Command(unsigned char cmd)
{
RW = 0;
RS = 0;
LCD_PIN = cmd;
EN = 1;
EN = 0;
if(cmd == 0x01 || cmd == 0x02 || cmd == 0x03 || cmd == 0x04 || cmd == 0x05 || cmd == 0x06 || cmd == 0x07)
{
timer_count = 1536; //命令执行时间为1.37ms
}
else
{
timer_count = 384; //命令执行时间为0.34ms
}
while(timer_count > 0);
}
void Write_Data(unsigned char dat)
{
RW = 0;
RS = 1;
LCD_PIN = dat;
EN = 1;
EN = 0;
timer_count = 384; //数据写入时间为0.34ms
while(timer_count > 0);
}
void Write_String(unsigned char code *s)
{
while(*s != '\0')
{
Write_Data(*s++);
}
}
void Timer0_ISR(void) interrupt 1
{
timer_count++; //定时器计数
}
```
阅读全文