以下是一个基于51单片机的增量式光电编码器点击测速以及速度LCD显示程序示例
时间: 2023-07-28 11:10:39 浏览: 99
以下是一个基于51单片机的增量式光电编码器点击测速以及速度LCD显示程序示例:
```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 RS = P2^0; // LCD命令/数据选择引脚
sbit RW = P2^1; // LCD读/写选择引脚
sbit EN = P2^2; // LCD使能引脚
uchar speed_display[4] = {0}; // 转速显示数组
void delay(uint t)
{
uint i, j;
for (i = 0; i < t; i++)
{
for (j = 0; j < 120; j++);
}
}
void lcd_init()
{
RW = 0;
RS = 0;
EN = 0;
delay(15);
P0 = 0x38;
EN = 1;
delay(5);
EN = 0;
delay(1);
P0 = 0x38;
EN = 1;
delay(5);
EN = 0;
delay(1);
P0 = 0x38;
EN = 1;
delay(5);
EN = 0;
delay(1);
P0 = 0x08;
EN = 1;
delay(5);
EN = 0;
delay(1);
P0 = 0x01;
EN = 1;
delay(5);
EN = 0;
delay(1);
P0 = 0x06;
EN = 1;
delay(5);
EN = 0;
delay(1);
P0 = 0x0C;
EN = 1;
delay(5);
EN = 0;
delay(1);
}
void lcd_cmd(uchar cmd)
{
RW = 0;
RS = 0;
P0 = cmd;
EN = 1;
delay(5);
EN = 0;
delay(1);
}
void lcd_data(uchar dat)
{
RW = 0;
RS = 1;
P0 = dat;
EN = 1;
delay(5);
EN = 0;
delay(1);
}
void lcd_display_speed()
{
lcd_cmd(0x80); // 第一行第一列
lcd_data('S');
lcd_data('p');
lcd_data('e');
lcd_data('e');
lcd_data('d');
lcd_data(':');
lcd_data(' ');
lcd_data(speed_display[0] + '0');
lcd_data(speed_display[1] + '0');
lcd_data(speed_display[2] + '0');
lcd_data(speed_display[3] + '0');
lcd_data('r');
lcd_data('p');
lcd_data('m');
}
uchar time_count = 0; // 计时器计数器
uint encoder_count = 0; // 编码器计数器
uint speed = 0; // 转速
void main()
{
lcd_init(); // 初始化LCD显示屏
lcd_display_speed(); // 显示转速
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; // 获取个位数字
lcd_display_speed(); // 显示转速
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秒时,计算出转速并将转速显示在LCD显示屏上。其中,通过编码器A相和B相的电平状态判断编码器的正转或反转,计数器根据正反转状态进行加减操作。通过定时器0和计时器计数器实现5秒的计时功能,并通过LCD显示屏实现速度显示的功能。
阅读全文