找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1542|回复: 12
收起左侧

求助:网上找来的单片机程序,想添加控制继电器功能

[复制链接]
ID:816562 发表于 2023-2-12 19:47 | 显示全部楼层 |阅读模式
    网上找来的程序,基于51单片机的倒计时装置,定时时间到后蜂鸣器鸣叫,倒计时结束,想添加一个控制继电器功能,就是计时开始继电器吸合,计时结束继电器释放,不知道怎么加,请各位大佬帮帮忙,在此谢过了!
    以下是源码:
//======================================================================
//
//        Copyright (C) 2020 Jobcrazy   
//        All rights reserved
//
//======================================================================

#include <reg52.h>

//Button registers
sbit Step1m = P3^6;  //按键3,+1分钟
sbit Step10m = P3^5;  //按键2,+10分钟
sbit Step1h = P3^4;  //按键1,+1小时
sbit StepStart = P3^7;  //按键4,开始计时

//Beep register
sbit Beep = P1^6;  //蜂鸣器

//Relay
sbit Relay = P1^7;  //继电器


//Time Led Dot register
sbit TIME_DOT = P1^5;  //数码管":"

//Time Led Segment register
sbit ShuMa_Duan_0 = P1^0;  //数码管1
sbit ShuMa_Duan_1 = P1^1;  //数码管2
sbit ShuMa_Duan_2 = P1^2;  //数码管3
sbit ShuMa_Duan_3 = P1^3;  //数码管4

//Initial settings
#define DEFAULT_HOUR 00
#define DEFAULT_MINUTE 00
#define DEFAULT_SECOND 00
volatile int Hour = DEFAULT_HOUR;
volatile int Minute = DEFAULT_MINUTE;
volatile int Second = DEFAULT_SECOND;

//Led Number Definitions
code unsigned char ShuMa_Data[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92,0x82,0xF8,0x80,0x90};

//Led Number Indexes
volatile int Shi_Left = 0;
volatile int Ge_Left = 0;
volatile int Shi_Right = 0;
volatile int Ge_Right = 0;

//Delay 1 minisecond
void Delay_1ms( int i )
{      
    for( ; i > 0; --i )
    {
        int j = 0;
        for( ; j < 110; ++j )
        {
                        
        }
    }
}

//Timer Settings
void Init_Timer()
{
    TMOD = 0x11; //Using timer 0 and timer 1
    TH0  = 0xB8;
    TL0  = 0x00;  //Timer0 = 20ms

    TH1  = 0xB8;
    TL1  = 0x00;  //Timer1 = 20ms

    TR0  = 0x01;  //Enable Timer 0
    TR1  = 0x00;
}

//Enable Timer
void Init_Interrupt()
{
    ET0 = 1;
    ET1 = 1;
    EA = 1;
}

//Show Number on the Timer Led
void  ShuMa(unsigned char ShuMa_Wei, unsigned char ShuMa_Index)
{
    P2 = ShuMa_Data[ShuMa_Index];

    if( ShuMa_Wei == 0 )
    {
        ShuMa_Duan_0 = 0;
        ShuMa_Duan_1 = 1;
        ShuMa_Duan_2 = 1;
        ShuMa_Duan_3 = 1;        
    }
    else if( ShuMa_Wei == 1 )
    {
        ShuMa_Duan_0 = 1;
        ShuMa_Duan_1 = 0;
        ShuMa_Duan_2 = 1;
        ShuMa_Duan_3 = 1;
    }
    else if( ShuMa_Wei == 2 )
    {
        ShuMa_Duan_0 = 1;
        ShuMa_Duan_1 = 1;
        ShuMa_Duan_2 = 0;
        ShuMa_Duan_3 = 1;
    }
    else if( ShuMa_Wei == 3 )
    {
        ShuMa_Duan_0 = 1;
        ShuMa_Duan_1 = 1;
        ShuMa_Duan_2 = 1;
        ShuMa_Duan_3 = 0;
    }

    //We must delay 1ms here, or else the Led will not show a correct number
    Delay_1ms(1);
}

//Convert the time to a displayable format
void CalcSecond()
{
    if( 0 < Hour )
    {
        Shi_Left = Hour / 10;
        Ge_Left = Hour % 10;

        Shi_Right = Minute / 10;
        Ge_Right =  Minute % 10;
    }
    else
    {
        Shi_Left = Minute / 10;
        Ge_Left = Minute % 10;

        Shi_Right = Second / 10;
        Ge_Right = Second % 10;
    }        
}

//Counter Timer
void Interrupt_Timer_0() interrupt 1
{
    static int Counter = 0;
    TH0 = 0xB8;
    TL0 = 0x00;

    ++Counter;

    if( 49 < Counter )
    {
        //Ths scope will run 1 time per second
        Counter = 0;
        TIME_DOT = ~TIME_DOT;

        Second--;

        //Let's see how long time is left
        if( Second < 0 )
        {
            Second = 59;
            Minute -= 1;
        }

        if( Minute < 0 )
        {
            if( 0 < Hour )
            {
                Hour--;
                Minute = Second = 59;
            }
            else
            {
                Hour = Minute = Second = 0;
                TR0 = 0; //Disable counter timer
                TR1 = 1; //Enable Beep Timer
            }
        }

        CalcSecond();
    }         
}

//Beep timer
void Interrupt_Timer_1() interrupt 3
{
    static int n = 0, Counter = 0;
    TH1 = 0xB8;
    TL1 = 0x00;

    ++Counter;
        


    if( Counter < 10 )
    {
        Beep = 0;
    }
    else if( Counter < 30 )
    {
        Beep = 1;
    }
    else if( Counter > 49 )
    {
        Counter = 0;
        TIME_DOT = ~TIME_DOT;

        n++;

        if( n >= 5 )
        {
            Hour =         DEFAULT_HOUR;
            Minute = DEFAULT_MINUTE;
            Second = DEFAULT_SECOND;
            n = 0;

            //Disable two timers
            TR0 = 0;
            TR1 = 0;        
        }        
    }
}

//Covert time to be recognizable
void formatTime()
{
    if( Minute >= 60 )
    {
        Minute = 0;
        Hour = Hour + 1;        
    }

    if( Hour >= 99 )
    {
        Hour = 0;
        Minute = 0;
        Second = 0;
    }

    CalcSecond();        
}

void main()
{
    //To avoid long press
    int Pressed = 0;

    //Light Timer Dot
    TIME_DOT = 0;

    //Turn Off Beep
    Beep = 1;
        
                 

        
    //Make P3 output high-level signal
    P3 = 0xFF;

    CalcSecond();

    //Infinite loop
    while(1)
    {
        //Covert time to be recognizable
        formatTime();

        //Show time the led screen
        ShuMa( 0, Shi_Left );                        
        ShuMa( 1, Ge_Left );
        ShuMa( 2, Shi_Right );
        ShuMa( 3, Ge_Right );

        if( 0 == TR0 && 0 == TR1 ) //If timer is not running
        {
            if( 0 == Step1m && 0 == Pressed )
            {
                //If Step1m button is pressed down
                Pressed = 1;
                Minute = Minute + 1;
            }
            else if( 0 == Step10m && 0 == Pressed )
            {
                //If Step10m button is pressed down
                Pressed = 1;
                Minute = Minute + 10;
            }
            else if( 0 == Step1h && 0 == Pressed )
            {
                //If Step1h button is pressed down
                Pressed = 1;
                Hour = Hour + 1;        
            }
            else if( 0 == StepStart && 0 == Pressed )
            {
                //If StepStart button is pressed down
                Pressed = 1;
                if ( 0 != Hour || 0 != Minute || 0 != Second )
                {
                    Init_Timer();
                    Init_Interrupt();
                }                                
            }
            else
            {
                if( 1 == Step1m && 1 == Step10m && 1 == Step1h && 1 == StepStart )
                {
                    //If no button is pressed down
                    Pressed = 0;
                }        
            }
        }        

    }
}

Timer-master.zip

46.24 KB, 下载次数: 6

回复

使用道具 举报

ID:996773 发表于 2023-2-13 09:14 | 显示全部楼层
搞汇编的我真心看不懂这c语言,天书一样,倒计时是很简单的程序,用c写怎么这么长?对于汇编来说,只要在蜂鸣器不工作的时候加一条clr p0.1或者0.2任意端口拉低就可以用这个口驱动继电器了
回复

使用道具 举报

ID:161164 发表于 2023-2-13 09:30 | 显示全部楼层
  1. //...
  2. sbit Relay = Px^y;
  3. void main()
  4. {
  5. //...
  6. while(1)
  7. {
  8. //...
  9. Relay = !TR0;
  10. }
  11. }
复制代码
回复

使用道具 举报

ID:816562 发表于 2023-2-13 19:16 来自手机 | 显示全部楼层
lkc8210 发表于 2023-2-13 09:30

万分感谢,我通过您的代码问题已经解决!
IMG_20230213_191446.jpg
IMG_20230213_191358.jpg
回复

使用道具 举报

ID:492633 发表于 2023-2-13 21:17 来自手机 | 显示全部楼层
蜂鸣器是0启动1关闭,那你可以用npn型三极管直接驱动继电器,当蜂鸣器不响时继电器导通,蜂鸣器响时继电器关闭
回复

使用道具 举报

ID:579397 发表于 2023-2-13 23:05 | 显示全部楼层
if ( 0 != Hour || 0 != Minute || 0 != Second )
                {
                    Init_Timer();
                    Init_Interrupt();
Relay=~Relay;
                }                              
            }
            else
            {
Relay=~Relay;
                if( 1 == Step1m && 1 == Step10m && 1 == Step1h && 1 == StepStart )
                {
                    //If no button is pressed down
                    Pressed = 0;
                }      
回复

使用道具 举报

ID:579397 发表于 2023-2-13 23:08 | 显示全部楼层
a74772b01999c5b485d9e88084d4845.jpg
3b20fd908c0b7e069403e1238f080a5.jpg
我也做了一个,用18650电池的
回复

使用道具 举报

ID:579397 发表于 2023-2-13 23:08 | 显示全部楼层
kingzr00 发表于 2023-2-13 19:16
万分感谢,我通过您的代码问题已经解决!

数码管没有消隐
回复

使用道具 举报

ID:816562 发表于 2023-2-14 00:54 来自手机 | 显示全部楼层
3wjkdhus 发表于 2023-2-13 21:17
蜂鸣器是0启动1关闭,那你可以用npn型三极管直接驱动继电器,当蜂鸣器不响时继电器导通,蜂鸣器响时继电器 ...

感谢你提供的解决思路,蜂鸣器是计时结束时响5声,如果用蜂鸣器的引脚驱动继电器,当计时结束时就会重复开关5次,有可能对电气造成伤害,不过现在问题已经解决了!
回复

使用道具 举报

ID:816562 发表于 2023-2-14 00:55 来自手机 | 显示全部楼层
hi等你 发表于 2023-2-13 09:14
搞汇编的我真心看不懂这c语言,天书一样,倒计时是很简单的程序,用c写怎么这么长?对于汇编来说,只要在蜂 ...

感谢,问题已经解决了!
回复

使用道具 举报

ID:816562 发表于 2023-2-16 23:40 来自手机 | 显示全部楼层
已经组装好了,达到预期效果!
回复

使用道具 举报

ID:816562 发表于 2023-2-16 23:42 来自手机 | 显示全部楼层
完成效果
IMG_20230216_233836.jpg
IMG_20230216_233842.jpg
IMG_20230216_233853_BURST1.jpg
回复

使用道具 举报

ID:816562 发表于 2023-2-18 15:49 来自手机 | 显示全部楼层
405616736 发表于 2023-2-13 23:05
if ( 0 != Hour || 0 != Minute || 0 != Second )
                {
                    Init_Timer() ...

谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表