基于51单片机霍尔转速测量温度电机保护PWM调速设计proteus仿真原理图PCB

功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示温度,PWM档位值和当前转速
2.可通过按键控制电机启动,停止,正转,反转,加速,减速
3.温度超过50℃蜂鸣器报警,且电机停止转动
4.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:

在这里插入图片描述

PCB :
在这里插入图片描述

主程序:

#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include "18b20.h"
#include "lcd1602.h"
#include "delay.h"

sbit L9110H_IN1  = P1^0; //引脚定义
sbit L9110H_IN2  = P1^1;
sbit BUZZER      = P2^2;

sbit KEY_UP      = P3^5; //按键引脚定义
sbit KEY_DOWN    = P3^7;
sbit KEY_FORWORD = P3^6;
sbit KEY_BACK    = P3^4;
sbit KEY_START   = P1^6;
sbit KEY_STOP    = P1^7;

sbit LED_RED   = P2^1;
sbit LED_GREEN = P2^0;

bit ReadTempFlag; //定义读时间标志

int temp;             //温度读取
float temperature;    //实际温度
char dis0[16]; //定义显示区域临时存储数组

unsigned char levelValue = 5;      //占空比调整
bit startFlag = 0; //启停标志
bit motorFlag = 1; //正反转标志
bit readRateFlag = 0;  //读取速度标志

unsigned int rate;                  //速度值
unsigned long pulseNum;         //脉冲计数

void Timer0_Init(void); //函数声明
void KeyProcess(void); //按键处理

void main(void)
{
    L9110H_IN1 = 1;
    L9110H_IN2 = 1;

    Timer0_Init();
    EX1 = 1; //外部中断1开
    IT1 = 1; //边沿触发
    EA = 1;  //全局中断开

    LCD_Init();  //初始化液晶
    DelayMs(20); //延时有助于稳定
    LCD_Clear(); //清屏
    LCD_DispStr(0, 0, "Now:            ");
    LCD_DispOneChar(8, 0, 0xdf); //写入温度右上角点
    LCD_DispOneChar(9, 0, 'C');  //写入字符C
    LCD_DispStr(0, 1, "L:   Rate:   r/s");

    LED_RED = 1;
    LED_GREEN = 0;
    while (1) //主循环
    {

        if (ReadTempFlag == 1)
        {
            EA = 0;
            while(!DS18B20_GetTemp(&temp)); //读取温度
            temperature = (float)temp * 0.0625;                    //温度转换
            sprintf(dis0, "Now:%4.1f", temperature); //打印温度值
            LCD_DispStr(0, 0, dis0);
            LCD_DispOneChar(8, 0, 0xdf);        //写入温度右上角点
            LCD_DispOneChar(9, 0, 'C');         //写入字符C
            EA = 1;

            if (startFlag == 1)
            {
                LCD_DispStr(10, 0, " Start");
            }
            else
            {
                LCD_DispStr(10, 0, " Stop ");
            }

            sprintf(dis0, "L:%02d ", (int)levelValue); //打印等级
            LCD_DispStr(0, 1, dis0);

            if (temperature > 50) //高于报警温度
            {
                startFlag = 0; //电机停止
                BUZZER = 0; //打开蜂鸣器
            }
            else
            {
                BUZZER = 1; //关闭蜂鸣器
            }

            ReadTempFlag = 0;
        }
        
        if (readRateFlag == 1)
        {
            readRateFlag = 0;
            rate = pulseNum; 
            sprintf(dis0, "Rate:%03dr/s", rate); //打印速度
            LCD_DispStr(5, 1, dis0);
            EX1 = 1;
            pulseNum = 0;
        } 

        KeyProcess();
    }
}

void KeyProcess(void)
{
    if (!KEY_UP) //加速
    {
        DelayMs(20);
        if(!KEY_UP)
        {
            if (levelValue <= 9)
                levelValue++;
        }
        while(!KEY_UP);
    }

    if (!KEY_DOWN) //减速
    {
        DelayMs(20);
        if(!KEY_DOWN)
        {
            if (levelValue > 1)
                levelValue--;
        }
        while(!KEY_DOWN);
    }

    if (!KEY_FORWORD) //正转
    {
        DelayMs(20);
        if(!KEY_FORWORD)
        {
            if (startFlag == 1)
            {
                startFlag = 0;
                DelayMs(150);
                startFlag = 1;
            }
            motorFlag = 1;
            LED_RED = 1;
            LED_GREEN = 0;
        }
        while(!KEY_FORWORD);
    }

    if (!KEY_BACK) //反转
    {
        DelayMs(20);
        if(!KEY_BACK)
        {
            if (startFlag == 1)
            {
                startFlag = 0;
                DelayMs(150);
                startFlag = 1;
            }
            motorFlag = 0;
            LED_RED = 0;
            LED_GREEN = 1;
        }
        while(!KEY_BACK);
    }

    if (!KEY_START) //启动
    {
        DelayMs(20);
        if(!KEY_START)
        {
            startFlag = 1;
        }
        while(!KEY_START);
    }

    if (!KEY_STOP) //停止
    {
        DelayMs(20);
        if(!KEY_STOP)
        {
            startFlag = 0;
        }
        while(!KEY_STOP);
    }
}

void Timer0_Init(void)
{
    TMOD |= 0x01;                //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
	TL0 = 0x33;		//设置定时初始值
	TH0 = 0xFE;		//设置定时初始值 500us
    PT0 = 1; //设置高优先级
    EA = 1;  //总中断打开
    ET0 = 1; //定时器中断打开
    TR0 = 1; //定时器开关打开
}

void Timer0_isr(void) interrupt 1
{

    static unsigned char IN1Count = 0;
    static unsigned int numCount = 0;

	TL0 = 0x33;		//设置定时初始值
	TH0 = 0xFE;		//设置定时初始值 500us

    if (startFlag == 1)
    {
        IN1Count++;
        if (IN1Count < levelValue+15) //占空比调节,+15是为了让电机处于可启动的占空比以上
        {
            if (motorFlag == 1) //正转
            {
                L9110H_IN1 = 1;
                L9110H_IN2 = 0;
            }
            if (motorFlag == 0) //反转
            {
                L9110H_IN1 = 0;
                L9110H_IN2 = 1;
            }
        }
        else if ((IN1Count >= levelValue+15) && (IN1Count <= 11+15)) //关闭时间段
        {
            L9110H_IN1 = 1;
            L9110H_IN2 = 1; //关闭
        }
        else
        {
            IN1Count = 0; //一个周期结束
        }
    }
    else
    {
        L9110H_IN1 = 1;
        L9110H_IN2 = 1; //关闭
    }


    numCount++;

    if (numCount > 2000)
    {
        EX1 = 0;
        readRateFlag = 1;
        numCount = 0;
    }

    if (numCount % 1000 == 0)
    {
        ReadTempFlag = 1;
    }

}

/*------------------------------------------------
                外部中断程序
------------------------------------------------*/
void ISR_Key(void) interrupt 2
{
    pulseNum++;
}

仿真演示视频:
https://www.bilibili.com/video/BV1aM411k7rf/

实物演示视频:
https://www.bilibili.com/video/BV1c24y1m7PY/

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值