基于51单片机的编码器(速度,方向)
基于51单片机的编码器程序设计
编码器与电机轴连接起来,电机转动带动编码器转动,将电机旋转量变成脉冲输出。
实现转速和旋转方向的测量,通过LCD显示出来。
说明:仿真里面没有机械式的编码器,但是有一个电机自带编码器,所有编码器这类仿真通常都是用这个带编码的电机实现的。
#include "reg51.h"
#include "lcd1602.h"
#define uchar unsigned char
#define uint unsigned int
uchar time=0;//系统变量
uint freq1=1,freq2=0;//频率
uint speed=0;//速度
uchar sec=0;
uchar fang=0;//方向
uchar disp1[]="sudu:000r/min";
uchar start=0;
//主函数
void main()
{
init_1602();
//设置INT0
IT0=1;//跳变沿出发方式(下降沿)
EX0=1;//打开INT0的中断允许。
//设置INT1
IT1=1;//跳变沿出发方式(下降沿)
TMOD=0X11;
TH0=0X3C;
TL0=0XB0;
TH1=0;
TL1=0;
ET1=1;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
while(1)
{
}
}
//定时器0中断
void Timer0() interrupt 1
{
if(time<20)//1s
time++;
else
{
time=0;
freq1=freq2;//统计频率
freq2=0;
//speed=freq1/60;//计算速度,公式可自定义
speed=freq1;
//显示速度
disp1[5]=speed/100+0x30;
disp1[6]=speed%100/10+0x30;
disp1[7]=speed%10+0x30;
write_string(1,0,disp1);
if(fang==1)//显示方向
write_string(2,5,"left ");
else
write_string(2,5,"right");
start=1;
}
TH0=0X3C;
TL0=0XB0;
}
//定时器1中断
void Timer1() interrupt 3
{
sec++;
TH1=0;
TL1=0;
}
//外部中断0的中断函数
void Int0() interrupt 0
{
freq2++;
sec=0;
TH1=0;
TL1=0;
if(start==1)
{
start=0;
TR1=1;
EX1=1;EX0=0;
TR0=0;
}
}
//外部中断1的中断函数
void Int1() interrupt 2
{
unsigned long i=0;
TR1=0;//关闭中断
i=TH1*256+TL1;
if(i>100)//BUG中断0触发后会强制触发一次中断1,时间52us
{
i=i+sec*65536;
TH1=0;TL1=0;
if(freq1>0) //计算方向
{
if(i>500000/freq1)
fang=0;
else
fang=1;
}
EX0=1;EX1=0;TR0=1;
}
else
TR1=1;
}