0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于PIC微控制器的数字车速表和里程表电路

科技观察员 来源:circuitdigest 作者:阿斯文斯·拉吉 2023-01-25 15:06 次阅读

测量车辆或电机的速度/转速一直是我们尝试的迷人项目。因此,在本项目中,我们将使用工业就绪的PIC微控制器构建一个。我们将使用一块磁铁和一个霍尔传感器来测量速度。还有其他方法/传感器可以测量速度,但是,使用霍尔传感器很便宜,也可用于任何类型的电机/车辆。通过做这个项目,我们还将提高我们学习PIC16F877A的技能,因为该项目涉及中断和定时器的使用。在该项目结束时,您将能够计算任何旋转物体所覆盖的速度和距离,并将其显示在 16x2 LCD 屏幕上。让我们从这个带有PIC的数字车速表和里程表电路开始。

所需材料:

  1. PIC16F877A
  2. 7805 稳压器
  3. 霍尔效应传感器 (US1881/04E)
  4. 16*2液晶显示屏
  5. 一小块磁铁
  6. 连接线
  7. 电容器
  8. 面包板。
  9. 电源

计算速度和覆盖距离:

在我们实际开始构建电路之前,让我们了解如何使用霍尔传感器和磁铁来计算车轮的速度。

霍尔传感器是一种可以根据磁铁的极性检测磁铁存在的设备。我们将一小块磁铁贴在车轮上,并将霍尔传感器放置在其附近,以便每次车轮旋转时,霍尔传感器都会检测到它。然后,我们使用PIC微控制器上的定时器和中断来计算车轮完全旋转所需的时间。

用于车速表和里程表电路的霍尔传感器板

知道所花费的时间后,我们可以使用以下公式计算 RPM,其中 1000/时间将给我们 RPS,进一步将其乘以 60 将得到 RPM

rpm = (1000/timetaken) * 60;

其中(1000/时间)给出rps(每秒转数),乘以60将rps转换为rpm(每分钟转数)。

现在要计算车辆的速度,我们必须知道车轮的半径。在我们的项目中,我们使用了半径仅为3厘米的小玩具轮。但是, 我们假设车轮的半径为30厘米 (0.3米),以便我们可以可视化读数。

该值也乘以 0.37699,因为我们知道 速度 = (RPM(直径 * Pi)/ 60)。 公式简化为

v= radius_of_wheel * rpm * 0.37699;

一旦我们计算出速度,我们还可以使用类似的方法计算覆盖的距离。通过我们的霍尔和磁铁布置,我们知道轮子旋转了多少次。我们还知道车轮的半径,使用它我们可以找到车轮的周长,假设车轮的半径为 0.3m(R),周长 PiRR 的值将为 0.2827。这意味着每次霍尔传感器与磁体相遇时,车轮都会覆盖 0.2827 米的距离。

Distance_covered = distance_covered + circumference_of_the_circle

因为,现在我们知道这个项目将如何工作,让我们继续我们的电路图并开始构建它。

电路图和硬件设置:

1.png

这个车速表和里程表项目的电路图非常简单,可以构建在面包板上。如果您一直遵循PIC教程,那么您还可以重用我们用于学习PIC微控制器的硬件。在这里,我们使用了与PIC微控制器一起为LED闪烁构建的相同 性能板 ,如下所示:

用于PIC微控制器的PERF包教程

PIC16F877A MCU 的引脚连接如下表所示。

S.No: 引脚编号 引脚名称 已连接到
1 21 RD2 液晶显示器的 RS
2 22 RD3 液晶显示器的E
3 27 RD4 液晶屏D4
4 28 RD5 液晶屏D5
5 29 RD6 液晶屏D6
6 30 RD7 液晶屏D7
7 33 RB0/INT 3^RD^霍尔传感器引脚

构建项目后,如下图所示

使用PIC的数字车速表和里程表电路

如您所见,我用两个盒子将电机和一个霍尔传感器放置在附近的位置。您可以将磁铁固定在旋转物体上,并完好无损地靠近它的霍尔传感器,使其能够检测到磁铁。

注意: 霍尔传感器具有极性,因此请确保它正在检测哪个极并相应地放置它。

还要确保将上拉电阻与霍尔传感器的输出引脚一起使用。

模拟

该项目的模拟是使用 Proteus 完成的。由于该项目涉及移动物体,因此无法使用仿真来演示整个项目,但可以验证LCD的工作。只需将十六进制文件加载到模拟中并对其进行模拟即可。您将能够注意到液晶屏工作,如下所示。

使用PIC模拟的速度表和里程表电路

为了检查车速表和里程表是否正常工作,我已将霍尔传感器更换为逻辑状态设备。在仿真过程中,您可以单击逻辑状态按钮来触发中断,并检查所覆盖的速度和距离是否如上所示得到更新。

对 PIC16F877A 进行编程

如前所述,我们将借助PIC16F877A微控制器中的定时器和中断来计算车轮完全旋转所需的时间。我们已经在之前的教程中学习了如何使用计时器。我在本文末尾给出了该项目的完整代码。此外,我在下面解释了几行重要内容。

以下代码行将端口 D 初始化为用于 LCD 接口的输出引脚,将 RB0 初始化为输入引脚,以将其用作外部引脚。此外,我们还使用OPTION_REG启用了内部上拉电阻,并将64设置为预售。然后,我们启用全局和外设中断以启用定时器和外部中断。要将RB0定义为外部中断位,应将INTE设为高电平。溢出值设置为 100,以便每 1 毫秒触发计时器中断标志 TMR0IF。这将有助于运行毫秒计时器以确定以毫秒为单位所花费的时间:

TRISD = 0x00; //PORTD declared as output for interfacing LCD
    TRISB0 = 1;        //DEfine the RB0 pin as input to use as interrupt pin
    OPTION_REG = 0b00000101;  // Timer0 64 as prescalar // Also Enables PULL UPs
    TMR0=100;       // Load the time value for 1ms; delayValue can be between 0-256 only
    TMR0IE=1;       //Enable timer interrupt bit in PIE1 register
    GIE=1;          //Enable Global Interrupt
    PEIE=1;         //Enable the Peripheral Interrupt
    INTE = 1;          //Enable RB0 as external Interrupt pin

每次检测到中断时,都会执行以下函数。我们可以根据自己的意愿命名函数,所以我将其命名为 speed_isr()。 该程序处理两个中断,一个是定时器中断,另一个是外部中断。每当发生定时器中断时,标志 TMR0IF 都会变高,为了清除和重置中断,我们必须通过定义 TMR0IF=0 使其变低,如下面的代码所示。

void interrupt speed_isr()
{
        if(TMR0IF==1) // Timer has overflown
    { 
        TMR0IF=0;       // Clear timer interrupt flag
        milli_sec++;
    }

        if (INTF==1)
        {
           rpm = (1000/milli_sec) * 60;
           speed = 0.3 * rpm * 0.37699; // (Assuming the wheel radius to be 30cm)
           INTF = 0;          // clear the interrupt flag
            milli_sec=0; 
            distance= distance+028.2;
        }
}

同样,当发生外部中断时,标志 INTF 将变为高电平,这也应通过定义 INTF=0 来清除。计时器中断跟踪所花费的时间,外部中断确定车轮何时完成一次完整旋转。有了这些数据,在每次外部中断期间计算车轮覆盖的速度和距离。

计算出速度和距离后,可以使用我们的LCD功能简单地显示在LCD屏幕上。如果您不熟悉 LCD,请参阅我们的 LCD 与 PIC16F877A MCU 接口教程

工作说明:

准备好硬件和软件后,只需将代码上传到PIC16F877A即可。如果您是PIC的新手,那么您应该阅读一些有关如何将程序上传到PIC16F877A微控制器的教程。

我使用可变锅来调整电机的速度以进行演示。您也可以使用相同的查找实时应用程序。如果一切按预期工作,那么您应该能够以公里/小时为单位获得速度和以米为单位的距离,如下面的视频所示。

液晶车速表和里程表电路

/*
Speedometer and Odometer for PIC16F877A
* Code by: B.Aswinth Raj
* Dated: 27-07-2017
* More details at: www.CircuitDigest.com
*/
#define _XTAL_FREQ 20000000
#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
#define D7 RD7
#include
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
int speed =0;
int milli_sec=0;
int rpm=0;
int c1,c2,c3;
int d1,d2,d3;
int distance;
//LCD Functions Developed by Circuit Digest.
void Lcd_SetBit(char data_bit) //Based on the Hex value Set the Bits of the Data Lines
{
if(data_bit& 1)
D4 = 1;
else
D4 = 0;
if(data_bit& 2)
D5 = 1;
else
D5 = 0;
if(data_bit& 4)
D6 = 1;
else
D6 = 0;
if(data_bit& 8)
D7 = 1;
else
D7 = 0;
}
void Lcd_Cmd(char a)
{
RS = 0;
Lcd_SetBit(a); //Incoming Hex value
EN = 1;
__delay_ms(4);
EN = 0;
}
void Lcd_Clear()
{
Lcd_Cmd(0); //Clear the LCD
Lcd_Cmd(1); //Move the curser to first position
}
void Lcd_Set_Cursor(char a, char b)
{
char temp,z,y;
if(a== 1)
{
temp = 0x80 + b - 1; //80H is used to move the curser
z = temp>>4; //Lower 8-bits
y = temp & 0x0F; //Upper 8-bits
Lcd_Cmd(z); //Set Row
Lcd_Cmd(y); //Set Column
}
else if(a== 2)
{
temp = 0xC0 + b - 1;
z = temp>>4; //Lower 8-bits
y = temp & 0x0F; //Upper 8-bits
Lcd_Cmd(z); //Set Row
Lcd_Cmd(y); //Set Column
}
}
void Lcd_Start()
{
Lcd_SetBit(0x00);
for(int i=1065244; i<=0; i--) NOP();
Lcd_Cmd(0x03);
__delay_ms(5);
Lcd_Cmd(0x03);
__delay_ms(11);
Lcd_Cmd(0x03);
Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD
Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD
Lcd_Cmd(0x08); //Select Row 1
Lcd_Cmd(0x00); //Clear Row 1 Display
Lcd_Cmd(0x0C); //Select Row 2
Lcd_Cmd(0x00); //Clear Row 2 Display
Lcd_Cmd(0x06);
}
void Lcd_Print_Char(char data) //Send 8-bits through 4-bit mode
{
char Lower_Nibble,Upper_Nibble;
Lower_Nibble = data&0x0F;
Upper_Nibble = data&0xF0;
RS = 1; // => RS = 1
Lcd_SetBit(Upper_Nibble>>4); //Send upper half by shifting by 4
EN = 1;
for(int i=2130483; i<=0; i--) NOP();
EN = 0;
Lcd_SetBit(Lower_Nibble); //Send Lower half
EN = 1;
for(int i=2130483; i<=0; i--) NOP();
EN = 0;
}
void Lcd_Print_String(char *a)
{
int i;
for(i=0;a[i]!='\\0';i++)
Lcd_Print_Char(a[i]); //Split the string using pointers and call the Char function
}
/*****End of LCD Functions*****/
/****Interrupt function ****/
void interrupt speed_isr()
{
if(TMR0IF==1) // Timer has overflown
{
TMR0IF=0; // Clear timer interrupt flag
milli_sec++;
}
if (INTF==1)
{
rpm = (1000/milli_sec) * 60;
speed = 0.3 * rpm * 0.37699; // (Assuming the wheel radius to be 30cm)
INTF = 0; // clear the interrupt flag
milli_sec=0;
distance= distance+028.2;
}
}
/****End of Interrupt Function****/
int main()
{
TRISD = 0x00; //PORTD declared as output for interfacing LCD
TRISB0 = 1; //DEfine the RB0 pin as input to use as interrupt pin
OPTION_REG = 0b00000101; // Timer0 with external freq and 64 as prescalar // Also Enables PULL UPs
TMR0=100; // Load the time value for 1ms; delayValue can be between 0-256 only
TMR0IE=1; //Enable timer interrupt bit in PIE1 register
GIE=1; //Enable Global Interrupt
PEIE=1; //Enable the Peripheral Interrupt
INTE = 1; //Enable RB0 as external Interrupt pin
Lcd_Start();
while(1)
{
c1 = (speed/100)%10;
c2 = (speed/10)%10;
c3 = (speed/1)%10;
d1 = (distance/100)%10;
d2 = (distance/10)%10;
d3 = (distance/1)%10;
if (milli_sec>1000)
{
speed=0;
}
Lcd_Set_Cursor(1,1);
Lcd_Print_String("Speed(km/hr): ");
Lcd_Print_Char(c1+'0');
Lcd_Print_Char(c2+'0');
Lcd_Print_Char(c3+'0');
Lcd_Set_Cursor(2,1);
Lcd_Print_String("Dist_Cov(m): ");
Lcd_Print_Char(d1+'0');
Lcd_Print_Char(d2+'0');
Lcd_Print_Char(d3+'0');
}
return 0;
}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PIC微控制器
    +关注

    关注

    0

    文章

    17

    浏览量

    7354
  • 车速表
    +关注

    关注

    0

    文章

    14

    浏览量

    8263
  • 里程表
    +关注

    关注

    1

    文章

    15

    浏览量

    9812
收藏 人收藏

    评论

    相关推荐

    汽车液晶里程表调整,(高手帮忙)!!!!

    我是一服务站维修工,今天把一辆车里程表数字搞大了,跪求高手帮忙!(雪铁龙c2)
    发表于 02-03 13:47

    奥迪100 2.2E里程表不计程时,车速无规律摆动的检修方法

    的具有一定频率的电信号变为有用方波电压信号,以控制车速电路和驱动里程表步进电机。速度出现无规律抖动是因为尽管传感
    发表于 02-25 11:42

    基于单片机的简易里程表

    ` 本帖最后由 jiuri1989 于 2012-3-30 16:24 编辑 这是一款简易的自行车里程表,核心部分是一块8051的单片机。电路图程序流程PCB热转印图,可以直接使用`
    发表于 03-30 16:21

    电动自行车速度与里程表设计

    电动自行车速度与里程表设计
    发表于 08-16 14:11

    电动车里程表

    ` 本帖最后由 gk320830 于 2015-3-4 23:31 编辑 发个电动车里程表的制作(包含程序)。`
    发表于 10-12 20:04

    纳智捷汽车里程表

    纳智捷汽车里程表Q.Q2622492007 电.话***汽车里程表主要分为两种:1.机械(目前主要在摩托车上有)2.液晶电子表(目前
    发表于 04-26 16:48

    谁有单片机液晶屏设计车速里程表、转速的的设计

    谁有单片机液晶屏设计车速里程表、转速的的设计,帮帮忙,有的给我发一份,非常感谢!QQ596916131
    发表于 05-13 08:54

    车速自动监测及里程表测控系统的设计制作

    车速自动监测及里程表测控系统的设计制作
    发表于 05-05 09:35

    什么是车速里程表信号装置?速比该怎么计算?

    车速里程表是由指示汽车行驶速度的车速和记录汽车所行驶过距离的里程计组成的。目前有机械式和电子式两种。
    发表于 09-25 08:21

    里程表传感坏了症状

      里程表传感又叫转速传感,一般安装在变速箱输出轴旁边,主要是用来检测电控汽车轮胎的转速,将检测到的信号输送到ECU,从而控制自动变速
    发表于 06-28 16:34

    汽车车速里程表工作原理是什么?

    转自: http://www.gzweix.com/article/sort0253/sort0487/info-287379.html新型汽车车速里程表信号采集与处理研究来源:汽车电器作者:佚名
    发表于 08-30 07:18

    如何利用51单片机实现智能电子里程表的设计

    电量与转速的函数关系实现转速测量,再通过计算,从而得出里程车速的信息,并由LED显示显示出来。并且该电子式里程表累积的里程
    发表于 11-22 08:06

    智能速度里程表设计方案

    智能速度里程表设计
    发表于 09-20 07:58

    车速里程表原理及速比的计算方法

    车速里程表与水温表一起,成为汽车用组合仪表上最重要的两个仪表。车速里程表有机械式和电子式两种,右图所示为磁感应式车速
    发表于 05-27 15:15 75次下载
    <b class='flag-5'>车速</b><b class='flag-5'>里程表</b>原理及速比的计算方法

    车速里程表信号装置及速比的计算分析

    车速里程表是由指示汽车行驶速度的车速表和记录汽车所行驶过距离的里程计组成的。目前有机械式和电子式两种。 一、车速
    发表于 11-21 15:20 1次下载
    <b class='flag-5'>车速</b><b class='flag-5'>里程表</b>信号装置及速比的计算分析