一个基于51单片机的增量式光电编码器点击测速以及速度显示程序
时间: 2023-07-28 07:07:33 浏览: 172
以下是一个基于51单片机的增量式光电编码器点击测速以及速度显示程序示例:
```c
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit ENCODER_A = P3^2; // 编码器A相输入引脚
sbit ENCODER_B = P3^3; // 编码器B相输入引脚
sbit LED = P1^0; // 指示灯引脚
uchar time_count = 0; // 计时器计数器
uint encoder_count = 0; // 编码器计数器
uint speed = 0; // 转速
uchar speed_display[4] = {0}; // 转速显示数组
void main()
{
TMOD = 0x01; // 定时器0工作在模式1:16位定时器模式
TH0 = 0xFC; // 定时器初值设置为65536-50000=15536,即0.5秒
TL0 = 0x00;
ET0 = 1; // 开启定时器0中断
EA = 1; // 开启总中断
EX0 = 1; // 开启外部中断0
IT0 = 1; // 外部中断0触发方式为下降沿
while (1)
{
// 主程序空转
}
}
void timer0_isr() interrupt 1 // 定时器0中断服务程序
{
TH0 = 0xFC; // 定时器初值重置为15536
TL0 = 0x00;
time_count++; // 计时器计数器自增
if (time_count >= 10) // 如果计时器计数器达到10,即计时5秒
{
speed = encoder_count * 60 / 20; // 计算转速,单位rpm
speed_display[0] = speed / 1000; // 获取千位数字
speed_display[1] = (speed % 1000) / 100; // 获取百位数字
speed_display[2] = (speed % 100) / 10; // 获取十位数字
speed_display[3] = speed % 10; // 获取个位数字
LED = 1; // 指示灯亮
time_count = 0; // 计时器计数器清零
encoder_count = 0; // 编码器计数器清零
}
}
void encoder_isr() interrupt 0 // 外部中断0中断服务程序
{
if (ENCODER_B) // 判断编码器B相电平状态
{
if (ENCODER_A) // 判断编码器A相电平状态
{
encoder_count++; // 编码器正转
}
else
{
encoder_count--; // 编码器反转
}
}
else // 编码器B相电平反转
{
if (ENCODER_A) // 判断编码器A相电平状态
{
encoder_count--; // 编码器反转
}
else
{
encoder_count++; // 编码器正转
}
}
}
```
该程序通过定时器0和外部中断0接收编码器A相和B相的输入信号,并根据输入信号的变化计算出编码器的计数值。程序中设置了一个计时器计数器,计时器计数器每隔0.5秒自增1,当计时器计数器达到10,即计时5秒时,计算出转速并将转速显示在四个数码管上。其中,通过编码器A相和B相的电平状态判断编码器的正转或反转,计数器根据正反转状态进行加减操作。通过定时器0和计时器计数器实现5秒的计时功能,并通过指示灯和转速显示四个数码管实现速度显示的功能。
阅读全文