1849【毕设课设】基于单片机直流电机PWM调速系统设计

基于单片机直流电机PWM调速系统设计

摘要

本文介绍了一种基于单片机直流电机PWM调速系统设计。该系统通过定时器和PWM信号控制直流电机的转速和方向,并通过按键实现对电机的加速、减速、正转和反转控制。系统还采用LCD1602显示屏实时显示PWM占空比和电机转速。本文详细描述了系统的硬件设计和软件实现。
在这里插入图片描述
在这里插入图片描述

仿真、代码等资料下载地址:
https://docs.qq.com/doc/p/ffc421513a628b30450ae742547c0b850456d7c8

系统总体设计

本系统由单片机、PWM控制电路、电机驱动电路、按键控制电路和LCD显示电路组成。单片机是系统的核心,负责生成PWM信号、处理按键输入、计算电机转速并将信息显示在LCD上。系统框图如图1所示。

图1 系统框图

单片机
PWM控制电路
电机驱动电路
按键控制电路
LCD显示电路
电机
按键
LCD显示

硬件设计

电机驱动电路

电机驱动电路采用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占空比和电机转速。系统设计简单,功能完善,适用于多种直流电机控制场景。

  • 17
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值