1.本设计采用STC89C51/52(与AT89S51/52、AT89C51/52通用,可任选)单片机作为主控制器
· 2.采用霍尔传感器非接触式测电机转速
· 3.LCD1602液晶显示当前的转速,转速单位为转/分(RPM)。和显示当前的pwm占空比0~100%。
· 4.电机的速度可以通过按键调整,也可以开始暂停,正转和反转。
注意:磁铁和霍尔元件最近距离在2mm左右,太近可能会在电机转动时碰到霍尔元件,太远霍尔元件可能会检测不到磁铁。
使用说明:
液晶屏第一行显示电机转速,第二行显示占空比,占空比数值越大,电机转速越快。
系统一共有6个按键,单片机附近的独立按键是系统的复位按键,按下单片机会复位。
下面一排是控制按键:
1键:加速键,可以短按,占空比加1,也可长按,占空比连续加;
2键:减速键,可以短按,占空比减1,也可长按,占空比连续减;
3键:正转切换键,按下后电机正转;
4键:反转切换键,按下后电机反转;
5键:开始暂停键,按一下开始,再按一下暂停。
1.本选题的理由及意义
现在电气传动的主要方向之一是电机调速系统采用微处理器实现数字化控制,近年来,随着科技的进步,直流电机得到了越来越广泛的应用,直流具有优良的调速特性,调速平滑,方便,调速范围广,过载能力强,能承受频繁的冲击负载,可实现频繁的无极快速起动、制动和反转,需要满足生产过程自动化系统各种不同的特殊要求,从而对直流电机提出了较高的要求,改变电枢回路电阻调速、改变电压调速等技术已远远不能满足现代科技的要求,并且随着现代化生产规模的不断扩大,各个行业对直流电机的需求愈益增大,并对其性能提出了更高的要求。为此,研究并制造高性能、高可靠性的直流电机控制系统有着十分重要的现实意义。
本题正是以此为出发点, 利用单片机来实现对电机转速的监测和控制。
2.需要重点研究的关键问题及解决问题的思路
关键问题一:如何选择合适的单片机
如何选择合适的单片机是本课题待解决的第一个问题。综合各方面因素考虑,本课题将采用AT89S52,利用AT89S52芯片进行低成本直流电动机控制系统的设计,能够简化系统构成、降低系统成本、增强系统性能、满足更多应用场合的需要。系统实现对电机的正转、反转、急停、加速、减速的控制。
关键问题二:如何选择合适的电机驱动
如何选择合适的电机驱动是本课题待解决的第二个问题。综合各方面因素考虑,本课题将采用三极管驱动电机
关键问题三:采用何种方法来改变占空比
如何选改变占空比是本课题待解决的第三个问题。改变占空比的方法通常有定宽调频法,调频调宽法,定频调宽法,由于前两种方法在调速时改变了控制脉冲的周期(或频率),当控制脉冲的频率与系统的固有频率接近时,将会引起震荡,因此采用定频调宽法来改变占空比。
关键问题四:软件编程及调试
软件编程及调试是本题待解决的第四个问题,也是最为重要关键的问题,关系着该系统能否实现其功能。
3.创新点及实践价值
PWM-脉冲宽度调制技术,通过对微处理器输出的一系列数字脉冲宽度进行调制,等效地获得模拟电路所需的波形,从而实现对模拟电路控制的一种有效技术。采用PWM技术可以避免传统调速系统模拟电路容易随时间飘移、产生一些不必要的热损耗、以及对噪声敏感等缺点,并且PWM调速系统低速特性好,动态抗干扰能力强的特点.由此来实现直流电机的启动、停止、加速、减速、正转、反转以及速度的动态显示,并且大幅度提高了转速显示的精确性。
4.完成本选题所需的工作条件(如资料、工具书、计算机设计绘图、实验、调研)及解决办法
工具:
(1)直流电机原理简述的相关资料
(2) PWM控制转速等的一些资料
(3) 模电、数电书籍
(4) 焊接工具一套
67-元件清单
制作出来的实物:
单片机直流电机控制转速仿真原理图如下
电路原理图如下:
PCB图如下:
部分源代码:
#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
}
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(num10)
{
delay(5); //消除抖动
if(num10)
{
if(m<=199)
m++;
displaym(); //设定占空比加一
}
}
if(num20)
{
delay(5);
if(num20)
{
if(m>=1)
m–;
displaym(); //设定占空比减一
}
}
if(num30)
{
delay(5);
if(num30)
{
zheng=1; //正传标志置1
fan=0; // 反转标志置0
}
}
if(num40)
{
delay(5);
if(num40)
{
zheng=0; //正传标志置0
fan=1; // 反转标志置1
}
}
if(num50)
{
delay(5);
if(num50)
{
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/200%10+0x30); //如果占空比百位不为0则显示百位否则显示空格
else
write_data(’ ');
if(m/200%100&&m/20%100)
write_data(’ ');
else
write_data(m/20%10+0x30); //如果占空比小于10 十位正常显示 否则显示空格
write_data(m/2%10+0x30); //显示个位
}
void main()
{
flag_1=0;
m=100; //占空比为100
zhuansu=0; //转速初值0
flag=0;
zheng=1; //初始化电机正转动
fan=0;
init(); //初始化
while(1)
{
keyscan(); //键盘扫描程序
}
}
void int1()interrupt 2 //外部中断1脉冲技术记录电机的转速 电机转一圈zhuansu加一
{
zhuansu++;
}
void int2()interrupt 3 //定时器0显示转速
{
TH0=0xdc;
TL0=0x00;//定时10ms
flag++;
if(flag==200) //计时到达2s
{
display(); //显示转速
zhuansu=0; //转速置0
flag=0;
}
}
void int3()interrupt 1 //产生PWM
{
TH1=0xff;
。。。。。。。。。。
…………限于本文篇幅有限 完整代码请从文章中下载附件…………
最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,
如果需要 完整代码或设计文件,请在下方留言或者私信我,看到后会第一时间回复。
谢谢!