本是学校的一门课程设计内容,分享出来吧,也许会对以后的学妹学弟有帮助呢?
设计思路
直流电机PWM控制系统的主要功能包括:直流电机的加减速、电机的正反转以及电机的启停,并且可以调整电机的转速,还可以方便的读出电机转速的大小,能够很方便的实现电机的智能控制。该直流电机系统由以下电路模块组成:
组成模块
振荡器和时钟电路:这部分电路主要由80C51单片机和一些电容、晶振组成。
设计输入部分:这一模块主要是利用6个独立的按键来实现。
设计控制部分:主要由80C51单片机的外部中断扩展电路组成。
设计显示部分:由LCD1602液晶显示模块组成;
直流电机PWM控制实现部分:主要由一些二极管、电机和L298直流电机驱动模块组成。
设计输入部分:这一模块主要是利用6个独立的按键来实现。
设计控制部分:主要由80C51单片机的外部中断扩展电路组成。
设计显示部分:由LCD1602液晶显示模块组成;
直流电机PWM控制实现部分:主要由一些二极管、电机和L298直流电机驱动模块组成。
基本原理
当按键扫描到有输入信号时,通过80C51单片机产生脉宽可调的脉冲信号并输入到L298驱动芯片来控制直流电机工作,从而实现电机的调速功能。再通过分析电机运转发出的脉冲周期计算出电机的速度,送给LCD1602显示。
总体设计框图
方案说明:直流电机PWM调速系统以AT89C51单片机为控制核心,由命令输入模块、LCD显示模块及电机驱动模块组成。单片机在程序控制下,定时不断给直流电机驱动芯片发送PWM波形,L298完成电机正,反转控制;同时单片机不停的将从电机发出的脉冲处理后,送到LCD显示模块去显示转速。整个系统的组成原理图如下图所示。
系统原理图
程序设计
整个程序由主程序以及9个子程序外加两个中断服务子程序组成。这9个子程序分别是:按键扫描、定时器初始化、LCD初始化、按键消抖、欢迎界面延时、LCD写数据、LCD写命令、LCD速度显示、LCD欢迎界面显示。
按键扫描:用来判断按钮是否被按下,从而实现相关功能。
void BtnSca()
{
if ( start == 0 || btnforward == 0 )
{
backward = 0;
forward = 1;
Flag = 1;
TR0 = 1;
} else if ( stop == 0 )
{
backward = 1;
forward = 1;
Flag = 0;
TR0 = 0;
} else if ( btnbackward == 0 && Flag == 1 )
{
backward = 1;
forward = 0;
Flag = 0;
/* TR0=1; */
}
if ( speedup == 0 )
{
BtnDelay( 10 );
/* 消抖 */
if ( speedup == 0 )
{
Hcount++;
if ( Hcount >= Lcount )
{
Hcount = 16;
}
}
while ( !speedup )
;
/* 等待键松开 */
}
if ( speeddown == 0 )
{
BtnDelay( 10 );
/* 消抖 */
if ( speeddown == 0 )
{
Hcount--;
if ( Hcount <= 0 )
{
Hcount = 0;
}
}
while ( !speeddown );
/* 等待键松开 */
}
}
定时器初始化:初始化定时器用,设定相关参数
/****************定时器初始化*****************/
void TInit()
{
TMOD = 0x11; /* 设置定时器T工作于方式 */
TH0 = setTHTL / 256;
TL0 = setTHTL % 256;
ET0 = 1; /* 开定时器中断 */
EA = 1; /* 开总中断 */
TH1 = (65536 - 50000) / 256; /* TH1装初值为65536-50000=15536,即定时50000us,相当于50毫秒。 */
TL1 = (65536 - 50000) % 256; /* TL1装初值为65536-50000=15536 */
EX1 = 1; /* 开外部中断1允许 */
IT1 = 1; /* 设置外部中断0下降触发中断 */
ET1 = 1; /* 打开定时器1中断允许 */
TR1 = 1; /* 开定时器1 */
}
LCD初始化:初始化LCD1602面板
void lcd_init()
{
writecmd( 0x38 ); /* 设置16*2显示模式 */
writecmd( 0x0c ); /* 开显示 */
writecmd( 0x01 ); /* 清屏 */
writecmd( 0x06 ); /* 地址指针+1 */
}
按键消抖:用来消除按键的抖动,防止输入错误信号
/****************延时消抖**********************/
void BtnDelay( i )
{
for ( j = i; j > 0; j-- )
for ( k = 125; k > 0; k-- )
;
}
欢迎界面延时:起到显示欢迎界面时长的作用,延时到达就擦除
/****************首屏欢迎延时****************/
void delay( void )
{
unsigned char a, b, c;
for ( c = 167; c > 0; c-- )
for ( b = 171; b > 0; b-- )
for ( a = 1; a > 0; a-- )
;
}
LCD写数据:写数据到LCD1602
/* 写数据 */
void writedat( unsigned char wd )
{
busy();
RS = 1;
RW = 0;
P2 = wd;
EN = 1;
EN = 0;
}
LCD写命令:通过1602的一些端口操作1602相关设置
/* 写命令 */
void writecmd( unsigned char wr )
{
busy();
RS = 0;
RW = 0;
P2 = wr;
EN = 1;
EN = 0;
}
LCD速度显示:通传入参数,将参数显示在1602上
/* 显示函数 */
void display( unsigned int rate )
{
unsigned char wan, qian, bai, shi, ge;
wan = rate / 10000;
qian = rate / 1000 % 10;
bai = rate / 100 % 10;
shi = rate / 10 % 10;
ge = rate % 10;
v = 0;
writecmd( 0x80 | 0x00 );
while ( dis3[v] != '\0' )
{
writedat( dis3[v] );
v++;
}
;
writecmd( 0x80 | 0x40 ); /* 显示地址 */
writedat( '0' + wan ); /* 将字符常量v写入LCD */
writedat( '0' + qian );
writedat( '0' + bai );
writedat( '0' + shi );
writedat( '0' + ge );
v = 0;
while ( dis4[v] != '\0' )
{
writedat( dis4[v] );
v++;
}
;
}
LCD欢迎界面显示:通传入参数,将参数显示在1602上
/****************首屏欢迎词****************/
void displayWelcome()
{
writecmd( 0x80 | 0x00 ); /* 显示地址 */
while ( dis1[v] != '\0' )
{
writedat( dis1[v] );
v++;
}
v = 0;
writecmd( 0x80 | 0x40 ); /* 显示地址 */
while ( dis2[v] != '\0' )
{
writedat( dis2[v] );
v++;
}
}
附件下载
包括Proteus仿真以及Keil5的工程文件。
蓝奏云下载
楼主大大,蓝奏云连接失效了
已更新
很强,但不懂