基于单片机直流电机PWM调速系统设计
摘要
本文介绍了一种基于单片机直流电机PWM调速系统设计。该系统通过定时器和PWM信号控制直流电机的转速和方向,并通过按键实现对电机的加速、减速、正转和反转控制。系统还采用LCD1602显示屏实时显示PWM占空比和电机转速。本文详细描述了系统的硬件设计和软件实现。
仿真、代码等资料下载地址:
https://docs.qq.com/doc/p/ffc421513a628b30450ae742547c0b850456d7c8
系统总体设计
本系统由单片机、PWM控制电路、电机驱动电路、按键控制电路和LCD显示电路组成。单片机是系统的核心,负责生成PWM信号、处理按键输入、计算电机转速并将信息显示在LCD上。系统框图如图1所示。
图1 系统框图
硬件设计
电机驱动电路
电机驱动电路采用L298芯片,通过单片机输出的PWM信号控制电机的正转、反转、加速和减速。L298芯片能够根据PWM信号的占空比调节电机的转速。
按键控制电路
按键控制电路由四个按键组成,分别用于控制电机的加速、减速、正转和反转。按键通过单片机的I/O口接入,单片机通过检测按键状态来实现对电机的控制。
LCD显示电路
LCD显示电路采用LCD1602显示屏,通过单片机控制实时显示PWM占空比和电机转速。LCD1602显示屏能够清晰地显示电机的当前运行状态,使用户能够直观地了解系统的工作情况。
软件设计
主程序
主程序初始化后,进入主循环,不断检测按键状态并根据按键输入调整PWM信号的占空比,从而控制电机的转速和方向,同时更新LCD显示内容。
#include<reg52.h>
#include<math.h>
#include<string.h>
#include<absacc.h>
#include<lcd1602.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define LCD_DB P0
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_E =P2^2;
void delayms(unsigned char ms);
void LCD_init(void);
void LCD_write_command(uchar command);
void LCD_write_data(uchar dat);
void LCD_disp_char(uchar x,uchar y,uchar dat);
void delay_n40us(uint n);
unsigned char code self_table1[]={
0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,
0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00,
0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00,
0x01,0x0c,0x17,0x14,0x17,0x0c,0x01,0x00,
0x10,0x18,0x1c,0x1e,0x1f,0x1c,0x18,0x10};
void LCD_init(void)
{
delayms(400);
LCD_write_command(0x38);
delayms(10);
LCD_write_command(0x38);
delayms(10);
LCD_write_command(0x38);
LCD_write_command(0x0c);
LCD_write_command(0x06);
LCD_write_command(0x01);
delay_n40us(100);
}
void LCD_write_command(uchar dat)
{
LCD_DB=dat;
LCD_RS=0;
LCD_RW=0;
LCD_E=1;
LCD_E=0;
delay_n40us(1);
}
void LCD_write_data(uchar dat)
{
LCD_DB=dat;
LCD_RS=1;
LCD_RW=0;
LCD_E=1;
LCD_E=0;
delay_n40us(1);
}
void cursor_flash(uchar a,uchar b)
{
LCD_write_command(0x0f);
LCD_write_command(0x80+a*0x40+b);
}
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
LCD_write_data(dat);
}
void DisplayChar(uchar x,uchar y,uchar *s)
{
uchar address,i,lengh;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
lengh=strlen(s);
for(i=0;i<lengh;i++)
{
LCD_write_data(*s);
s++;
}
}
void delay_n40us(uint n)
{
uint i;
uchar j;
for(i=n;i>0;i--)
for(j=0;j<2;j++);
}
void delayms(unsigned char ms)
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}
void write_CGRAM()
{
uchar i;
LCD_write_command(0x40);
for(i=0;i<40;i++)
{
LCD_write_data(self_table1[i]);
}
}
#define Data_Bus P1
sbit PWM=P3^0;
bit PWM_flag=0;
unsigned char Time_flag=0;
unsigned char DSW_data=0x00;
unsigned char PWM_data=0;
unsigned int Speed_data=0;
unsigned char PWM_Precent[5]={0x30,0x30,'%'};
unsigned char MotorSpeed[5]={0x30,0x30,0x30};
void delay(uint);
void delay_ms(unsigned int ii);
void get_PWM(void);
void get_Speed(void);
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delay_ms(unsigned int ii)
{
unsigned int i,x;
for (x=0;x<ii;x++)
{
for (i=0;i<200;i++);
}
}
void Init_int0(void)
{
EX0=1;
IT0=1;
EA=1;
}
void Int0_server(void) interrupt 0
{
EA=0;
Speed_data++;
EA=1;
}
void Time0_Init()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
TR0=1;
EA=1;
}
void Time0_Int() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
Time_flag++;
if(Time_flag==20)
{
Time_flag=0;
get_Speed();
}
}
void init_timer1(void)
{
TMOD|=0x10;
TH1=0xFF;
TL1=0xFE;
ET1=1;
TR1=1;
EA=1;
}
void timer1_server(void) interrupt 3
{
if(PWM_flag)
{
TH1=(65536-PWM_data*200)/256;
TL1=(65536-PWM_data*200)%256;
PWM=1;
PWM_flag=~PWM_flag;
}
else
{
TH1=(45536+PWM_data*200)/256;
TL1=(45536+PWM_data*200)%256;
PWM=0;
PWM_flag=~PWM_flag;
}
}
void get_PWM(void)
{
DSW_data=Data_Bus;
if(DSW_data==0x00)
{
TR1=0;
PWM=0;
PWM_Precent[0]=0x30;
PWM_Precent[1]=0x30;
}
else
{
PWM_data=DSW_data*100/256;
PWM_Precent[0]=PWM_data/10+0x30;
PWM_Precent[1]=PWM_data%10+0x30;
TR1=1;
}
}
void get_Speed(void)
{
MotorSpeed[0]=Speed_data/100+0x30;
MotorSpeed[1]=Speed_data/10%10+0x30;
MotorSpeed[2]=Speed_data%10+0x30;
Speed_data=0;
}
void main()
{
...
}
中断服务程序
中断服务程序用于生成PWM信号,通过定时器中断实现PWM信号的占空比调节,从而控制电机的转速。每次定时器中断时,根据当前的脉宽值和方向标记调整电机的驱动信号。
结论
本系统通过单片机生成PWM信号,并通过按键控制电机的转速和方向,同时采用LCD1602显示屏实时显示PWM占空比和电机转速。系统设计简单,功能完善,适用于多种直流电机控制场景。