直流电机控制系统,通过按键对直流电机进行控制;可以调节直流电机的速度等级,旋转方向,并将其显示在LCD1602液晶显示屏上;简单的直流电机控制可以应用在遥控车上,还可安装在自制小风扇等多种小型电器上,但此设计中直流电机控制不是很准确,在一些精密直流电机控制上使用效果较差。
二、模块介绍及原理说明单片机最小系统:
单片机最小系统完成系统运行的最基本电路,单片机最小系统可配合其他模块或自行搭建电路完成各种实验功能,单片机最小系统接口设计灵活,电路简洁,可完成基本的驱动任务。单片机最小系统包括晶振电路、复位电路。复位电路我使用按键复位,方便系统的重启。
LCD1602显示屏:
LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成。
字符型液晶显示模块是一种专门用于显示字母、数字和符号等的点阵式LCD。一般的LCD1602字符型液晶显示器能够显示英文字母、阿拉伯数字、日文片假名和一般性符号。
电机驱动:
NPN三极管Q7、Q9控制电机正转,当Q7、Q9导通后,OUT控制Q1、Q3三极管导通与关闭的时间来调节直流电机的速度。同理NPN三极管Q5、Q8控制电机正转,当Q5、Q8导通后,OUT控制Q2、Q4三极管导通与关闭的时间来调节直流电机的速度。
三、硬件连接仿真连接
P1^0~P1^3为按键控制端口。P1^0控制电机正转;P1^1控制电机反转;P1^2加速;P1^3减速。
P0^7~P0^7为显示屏数据传输端口。P0^7~P0^7与显示屏D0~D7连接。
P2^2、P2^3、P2^4为显示屏控制端口。P2^2、P2^3、P2^4分别于RS、RW、E相连。
P2^0、P2^1电机正反转控制。
P2^5电机PWM控制。
四、程序说明主程序,用以调用不同的函数。控制速度的加减,电机的正反转,调用LCD1602显示函数。
void main (void) { int S=0; char displaytemp[16];//定义显示区域临时存储数组 PWM_ON=0; LCD_Init(); //初始化液晶屏Init_Timer0(); //初始化定时器0 LCD_Write_String(2,1,"V:"); //正转 while (1) //主循环 { if(key3==0)//第三个按键,速度等级增加 { DelayMs(10); //消抖 if(key3==0) { if(PWM_ON=12)S=12; } while(!key3); } else if(key4==0)//第四个按键,速度等级减小 { DelayMs(10); if(key4==0) { if(PWM_ON>0) PWM_ON--; S--; if(S<=0)S=0; } while(!key4); } if(key1==0)//第一个按键,正转 { DelayMs(10); if(key1==0) { m=1;n=0; LCD_Write_String(0,0,"T"); //正转显示T } while(!key1); } else if(key2==0)//第二个按键,反转 { DelayMs(10); if(key2==0) { m=0;n=1; LCD_Write_String(0,0,"N"); //反转显示N } while(!key2); } sprintf(displaytemp,"%3d",S); LCD_Write_String(4,1,displaytemp); //显示速度等级,一共分为十二个等级 } })>
定时器函数,用来控制PWM值占空比的输出。
void Timer0_isr(void) interrupt 1 { static unsigned char count; TH0=(65536-2000)/256; //重新赋值 2ms TL0=(65536-2000)%256; if (count==PWM_ON) { DCOUT = 0; //如果定时等于on的时间, //说明作用时间结束,输出低电平 } count++; if(count == CYCLE) //反之低电平时间结束后返回高电平 { count=0; if(PWM_ON!=0) //如果开启时间是0 保持原来状态 DCOUT = 1; } }
LCD1602显示函数
/*------------------------------------------------ 写入命令函数 ------------------------------------------------*/ void LCD_Write_Com(unsigned char com) { // while(LCD_Check_Busy()); //忙则等待 DelayMs(5); RS_CLR; RW_CLR; EN_SET; DataPort= com; _nop_(); EN_CLR; } /*------------------------------------------------ 写入数据函数 ------------------------------------------------*/ void LCD_Write_Data(unsigned char Data) { //while(LCD_Check_Busy()); //忙则等待 DelayMs(5); RS_SET; RW_CLR; EN_SET; DataPort= Data; _nop_(); EN_CLR; } /*------------------------------------------------ 清屏函数 ------------------------------------------------*/ //void LCD_Clear(void) //{ //LCD_Write_Com(0x01); //DelayMs(5); //} /*------------------------------------------------ 写入字符串函数 ------------------------------------------------*/ void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) { while (*s) { LCD_Write_Char(x,y,*s); s++; x++; } } /*------------------------------------------------ 写入字符函数 ------------------------------------------------*/ void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) { if (y == 0) { LCD_Write_Com(0x80 + x); } else { LCD_Write_Com(0xC0 + x); } LCD_Write_Data( Data); } /*------------------------------------------------ 初始化函数 ------------------------------------------------*/ void LCD_Init(void) { LCD_Write_Com(0x38); /*显示模式设置*/ DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); LCD_Write_Com(0x08); /*显示关闭*/ LCD_Write_Com(0x01); /*显示清屏*/ LCD_Write_Com(0x06); /*显示光标移动设置*/ DelayMs(5); LCD_Write_Com(0x0C); /*显示开及光标设置*/ }
延时函数,用于按键的消抖,以及程序的延时。
/*------------------------------------------------ uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时 长度如下 T=tx2+5 uS ------------------------------------------------*/ void DelayUs2x(unsigned char t) { while(--t); } /*------------------------------------------------ mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编 ------------------------------------------------*/ void DelayMs(unsigned char t) { while(t--) { //大致延时1mS DelayUs2x(245); DelayUs2x(245); } }