资料十分全面,源程序(加注释)、原理图、仿真图、焊接图,以及讲解视频 均可在附件中下载
• 1.本设计采用STC89C51/52(与AT89S51/52、AT89C51/52通用,可任选)单片机作为主控制器
• 2.采用霍尔传感器非接触式测电机转速
• 3.LCD1602液晶显示当前的转速,转速单位为转/分(RPM)。和显示当前的pwm占空比0~100%。
• 4.电机的速度可以通过按键调整,也可以开始暂停,正转和反转。
注意:磁铁和霍尔元件最近距离在2mm左右,太近可能会在电机转动时碰到霍尔元件,太远霍尔元件可能会检测不到磁铁。
使用说明:
液晶屏第一行显示电机转速,第二行显示占空比,占空比数值越大,电机转速越快。
系统一共有6个按键,单片机附近的独立按键是系统的复位按键,按下单片机会复位。
下面一排是控制按键:
1键:加速键,可以短按,占空比加1,也可长按,占空比连续加;
2键:减速键,可以短按,占空比减1,也可长按,占空比连续减;
3键:正转切换键,按下后电机正转;
4键:反转切换键,按下后电机反转;
5键:开始暂停键,按一下开始,再按一下暂停。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
void displaym();
void displayj();
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 beep=P2^4;
sbit out=P3^4; //PWM输出用于正传
sbit out1=P3^7; //PWM输出用于反转
uint zhuansu,flag,z1,z2,m,flag_1,zheng,fan,kai,j,su,qian,bai,shi,ge;
void delay(uint z)//延时1ms函数
{
uint x,y;
for(x=0;x<z;x++)
for(y=0;y<110;y++);
}
void write_com(uchar com)//向1602写一字节(控制指令)
{
rs=0;
P0=com;
delay(5);
en=1;
delay(10);
en=0;
}
void write_data(uchar date)//向1602写一字节(数据)
{
rs=1;
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
void init()//初始化函数
{
en=0;
rw=0;
write_com(0x38); //5X7显示
write_com(0x0c); //关闭光标
write_com(0x01); //lcd初始化
TMOD=0x11; //定时器方式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('m');
write_data('/');
write_data('m');
write_data('i');
write_data('n');
write_com(0xc0);
write_data('z');
write_data('k');
write_data('b');
write_data(':');
displaym();
write_com(0xc8);
write_data('s');
write_data('d');
write_data(':');
displayj();
}
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)
{
j=j+1;
displayj();
}
}
if(num4==0)
{
delay(5);
if(num4==0)
{
j=j-1;
displayj();
}
}
if(num5==0)
{
delay(5);
if(num5==0)
{
while(num5==0) ;
kai=1-kai;
}
}
}
void display()
{
write_com(0x82);
zhuansu=zhuansu*30; //将两秒内的计数乘以30得到转每分
su=zhuansu*0.01*2*3.14/2;
qian=(su/1000)%100;
write_data(qian+0x30);
bai=(su/100)%10;
write_data(bai+0x30);
shi=(su/10)%10;
write_data(shi+0x30);
write_data('.');
ge=su%10;
write_data(ge+0x30);
write_com(0xd0);
}
void displaym()
{
write_com(0xc4);
if(m/200%10!=0)
write_data(m/200%10+0x30); //如果占空比百位不为0则显示百位否则显示空格
else
write_data(' ');
if(m/200%10==0&&m/20%10==0)
write_data(' ');
else
write_data(m/20%10+0x30); //如果占空比小于10 十位正常显示 否则显示空格
write_data(m/2%10+0x30); //显示个位
}
void displayj()
{
write_com(0xcb);
if(j/100%10!=0)
write_data(m/100%10+0x30);
else
write_data(' ');
if(j/100%10==0&&j/10%10==0)
write_data(' ');
else
write_data(j/10%10+0x30);
write_data(j/1%10+0x30);
write_com(0xd0);
}
void main()
{
flag_1=0;
m=100; //占空比为100
zhuansu=0; //转速初值0
flag=0;
zheng=1; //初始化电机正转动
fan=0;
j=67;
init(); //初始化
while(1)
{
keyscan(); //键盘扫描程序
if(su>j*10)
{
kai=0;
beep=~beep;
delay(500);
kai=1;
m-50;
}
}
}
...............
..........限制于本页篇幅余下代码请到51黑中下载
51单片机测速.rar
(4.75 MB, 下载次数: 113)
|