本设计以单片机AT89C51为核心,通过软件编程利用其定时器产生PWM信号从而实现对直流电机转速控制。硬件设计主要包括按键电路模块、电机驱动模块、测速模块和转速显示模块。其中采用独立式键盘通过按键将命令输入到单片机,改变PWM信号占空比,再将单片机输出的信号通过光电耦合器和由IGBT组成的H型桥式功率放大驱动电路,根据不同占空比的PWM信号达到电机启停、正反转和加减速控制。测速模块采用非接触式的霍尔传感器对直流电机的转速进行测量,将测得的转速传送到单片,再通过LCD显示出来。本论文主要介绍了直流电机调速系统的原理和方案设计,单片机如何产生PWM信号,H桥驱动电路设计,硬件电路图的设计与连接,实现功能的流程图和程序,系统的仿真和调试。
单片机程序源码:
#include
#define uchar unsigned char
#define uint unsigned int
void displaym();
sbit en=P2^5; //1602 6管脚
sbit rs=P2^7; //1602端口 4管脚
sbit rw=P2^6;//lcd1602控制端口 5管脚
sbit num1=P1^0; //占空比加1
sbit num2=P1^1; //占空比减一
sbit num3=P1^2; //正传
sbit num4=P1^3; //反转
sbit num5=P1^4; //开始停止切换
sbit out=P3^4; //PWM输出用于正传
sbit out1=P3^7; //PWM输出用于反转
uint zhuansu,flag,z1,z2,m,flag_1,zheng,fan,kai;
void delay(uint z)//延时1ms函数
{
uint x,y;
for(x=0;x
for(y=0;y<110;y++);
}
void write_com(uchar com)//向1602写一字节(控制指令)
{
rs=0;
P0=com;
delay(5);
en=0;
delay(10);
en=1;
}
void write_data(uchar date)//向1602写一字节(数据)
{
rs=1;
P0=date;
delay(5);
en=0;
delay(5);
en=1;
}
void init()//初始化函数
{
en=0;
rw=0;
write_com(0x01); //lcd初始化
write_com(0x38); //5X7显示
write_com(0x0c); //关闭光标
TMOD=0x01; //定时器方式1
TH0=0xdc;
TL0=0x00; //定时器装入初值
EA=1; //开总中断
ET0=1; //定时器0开中断
TR0=1;
EX1=1;
IT1=1; //定时器启动
TH1=0xfc;
TL1=0x66;//定时100us
ET1=1; //定时器1开中断
TR1=1;
write_com(0x80);
write_data('V');
write_data(':');
write_com(0x87); //第一行显示转速
write_data('r');
write_data('p');
write_data('m');
write_com(0xc0);
write_data('z');
write_data('h');
write_data('a');
write_data('n');
write_data('k');
write_data('o');
write_data('n');
write_data('g');
write_data('b');
write_data('i'); //在第二行显示zhankongbi:
write_data(':');
displaym();
}
void keyscan() //键盘扫描函数
{
if(num1==0)
{
delay(5); //消除抖动
if(num1==0)
{
if(m<=199)
m++;
displaym(); //设定占空比加一
}
}
if(num2==0)
{
delay(5);
if(num2==0)
{
if(m>=1)
m--;
displaym(); //设定占空比减一
}
}
if(num3==0)
{
delay(5);
if(num3==0)
{
zheng=1; //正传标志置1
fan=0; // 反转标志置0
}
}
if(num4==0)
{
delay(5);
if(num4==0)
{
zheng=0; //正传标志置0
fan=1; // 反转标志置1
}
}
if(num5==0)
{
delay(5);
if(num5==0)
{
while(num5==0) ;
kai=1-kai;
}
}
}
void display()
{
write_com(0x82);
zhuansu=zhuansu*30; //将两秒内的计数乘以30得到转每分
if(zhuansu/10000!=0)
write_data(zhuansu/10000+0x30); //如果转速的万位不为0 正常显示否则显示空格
else
write_data(' ');
if(zhuansu/1000==0)
write_data(' ');
else
write_data(zhuansu%10000%1000+0x30); //如果转速小于1000 千位为空格 否则正常显示
if(zhuansu/100==0)
write_data(' ');
else
write_data(zhuansu%10000%1000/100+0x30); //如果转速小于100 百位为空格 否则正常显示
if(zhuansu/10==0)
write_data(' ');
else
write_data(zhuansu%10000%1000%100/10+0x30); //如果转速小于10 十位为空格 否则正常显示
write_data(zhuansu%10000%1000%100%10+0x30);
write_com(0xd0); //如果没有这句,当中断内的显示函数执行完,就会在转速的位置显示占空比数据,导致乱码
}
void displaym()
{
write_com(0xcb);
if(m/200%10!=0)
write_data(m/
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』