找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3769|回复: 2
打印 上一主题 下一主题
收起左侧

时间继电器 倒计时控制 定时通断开关模块程序包带原理图

  [复制链接]
跳转到指定楼层
楼主
#include <reg52.h>          //用52的头文件  里面加的引脚再定义  
#include "intrins.h"   //延时
sfr AUXR = 0x8e;
sfr P5 = 0xc8;                         //p5定义  是加的
sfr P5M0 = 0xc9;
sfr P5M1 = 0XCA;                 
sfr P3M0 = 0xb2;                //p3口设置强推完的定义
sfr P3M1 = 0Xb1;
sfr P1M0 = 0x92;                //p0口设置强推完的定义                   这样设置数码管就亮
sfr P1M1 = 0X91;
/***********************掉电存储开始********************/
typedef unsigned char BYTE;
typedef unsigned int WORD;          //类型定义
unsigned char x = 0;
sfr  IAP_DATA     =   0xC2;            //IAP数据寄存器
sfr  IAP_ADDRH    =   0xC3;            //IAP地址寄存器高字节
sfr  IAP_ADDRL    =   0xC4;            //IAP地址寄存器低字节
sfr  IAP_CMD      =   0xC5;            //IAP命令寄存器
sfr  IAP_TRIG     =   0xC6;            //IAP命令触发寄存器
sfr  IAP_CONTR    =   0xC7;            //IAP控制寄存器
#define        CMD_IDLE     0                //空闲模式
#define CMD_READ     1                //IAP字节读命令
#define        CMD_PROGRAM  2                 //IAP字节编程命令
#define        CMD_ERASE    3                 //IAP扇区擦除命令
#define ENABLE_IAP   0x82             //if SYSCLK<20MHz
#define IAP_ADDRESS  0x0400                          //测试地址
//void Delay(BYTE n);
void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
void IapEraseSector(WORD addr);
/***********************掉电存储结束****************/
/*****************************数码管开始***********************************/
unsigned int i = 0;//用于扫描数码管
unsigned char bainum1 = 0;//百
unsigned char shinum1 = 0;//十
unsigned char genum1 = 0;//个
sbit pa = P1^0;sbit pb = P3^2;sbit pc = P3^7;sbit pd = P1^3;//数码管段
sbit pe = P1^2;sbit pf = P1^4;sbit pg = P3^3;//数码管段
sbit p1 = P1^1;sbit p2 = P3^6;sbit p3 = P5^5;//数码管位
void s0();void s1();void s2();void s3();void s4();void s5();//数码管部分
void s6();void s7();void s8();void s9();void s10();//数码管部分
void xuaze(unsigned char j);//数码管段显示
void displaynum(unsigned int);//显示函数
//unsigned char code duan [] ={0,1,2,3,4,5,6,7,8,9};
unsigned int bainum11=0,shinum11=0,genum11=0;//用于传到数码管上显示
/*****************************数码管结束***********************************/
unsigned int inum1=0,inum2=0;//触发端子用的计数
unsigned char inum11=0,inum12=0,inum21=0,inum22=0,ss=0;//掉电存储要用到
static unsigned char presstime=0;//时间值按键用到的
unsigned int kf0=1;//按键用的标志位
unsigned int kt0=0;//按键用的标志位
unsigned int  if0=1,if0s=1,it0=0;
unsigned int  mm=0,ff=0,sss=0;//计数用
bit flag_eeprom1=1;//掉电存储的标志位
unsigned int keynum=0;//数码管的位
sbit key2=P3^0;//按键  
sbit key1=P3^1;//按键
sbit out= P5^4;//输出
void timer0_1init();//定时器声明
void keycan();//按键
void keyflag();//按键结束调用
void saveeepro();//掉电存储
extern void displaynums();//将数字传到数码管上显示
void main()
{
        timer0_1init();
         P3M0 = 0xcc;
         P3M1 = 0X00;          //p3口设置强推挽
         P1M0 = 0x1f;
         P1M1 = 0X00;
        inum11 = IapReadByte(1);//读取掉电存储里的值
        inum12 = IapReadByte(2);
        inum21 = IapReadByte(3);
        inum22 = IapReadByte(4);
        if0    = IapReadByte(5);
        if0s   = IapReadByte(6);
        ss           = IapReadByte(7);
           inum1=inum11*100+inum12;//组合掉电存储中的值
           inum2=inum21*100+inum22;
   bainum11=inum1/100;//传到数码管显示
   shinum11=inum1/10%10;
   genum11=inum1%10;           
        while(1){
                keycan();//按键
        }                  
}
void keycan(){//按键
        if(keynum==0){//当按键值等于0的时候调用显示
                displaynums();//数码管的显示
                if(if0s==0){//当if0s等于0时,继电器输出
                        out=0;
                }
                if((flag_eeprom1==1)){//加掉电存储
                        saveeepro();//掉电存储
                        flag_eeprom1=0;
                }               
        }
    if(key1==0){//当按键1按下
                if(kf0){//当标志位kf0=1的时候进行
                        if(presstime>50){//当时间值大于一百的时候
                                kf0=0;//标志位kf0=0
                                kt0=1;//标志位kt0=0
                                flag_eeprom1=1;if0s=1;out=1;if0=1;
                                presstime=0;//时间清零,重新进行
                                keynum++;//数码管的位
                        if(keynum==4){//当位到4则置位0
                                   keynum=0;
                                   if0=0;
                                 }
                                if(out==0){
                                if0=0;
                                }

                        }
                  }
        }else{//当按键松开
                keyflag();
                if((flag_eeprom1==1)){ //加掉电存储,必需加到这,不然有一些小问题
                        flag_eeprom1=0;
                        saveeepro();//掉电存储
                }
        }//按键1结束
    if(key2==0){if(kf0){if(presstime>50){kf0=0;kt0=1;presstime=0;flag_eeprom1=1;//掉电存储的标志位改为1,进行存值操作
//                                if(out==0){
//                                if0=0;if0s=1;out=1;
//                                }
                                switch(keynum){
                                        case 1:
                                                bainum11++;//数码管一加加
                                                if(bainum11>9){//当数码管一加加到9时置为1
                                                        bainum11=0;
                                                }
                                                break;
                                        case 2:shinum11++;if(shinum11>9){shinum11=0;}break;
                                        case 3:genum11++;if(genum11>9){genum11=0;}break;
                                        default:break;
                                }
                        }}}else{keyflag();displaynums();
                                        if((flag_eeprom1==1))//加掉电存储,必需加到这,不然有一些小问题
                                        {   flag_eeprom1=0;
                                            saveeepro();//掉电存储
                                        }
                        }//松开按键进行显示       
}

void tm0_isr() interrupt 1 using 1
{//500等1s
        TL0 = 0x18;                //设置定时初值
        TH0 = 0xFC;                //设置定时初值
        presstime++;
   i++;
           if (if0==0){//当if0==0时开始倒计时
                mm++;
                if(mm==500){//一秒时间到
                        mm=0;
                        ff++;
                        if(ff>60){//一分钟
                                ff=0;
                                sss++;
                                ss=sss;
                                flag_eeprom1=1;
                                if(sss>60){//一小时
                                        sss=0;
                                        inum2--;
                                        flag_eeprom1=1;
                                        if(inum2==0){
                                                if0s=0;//继电器输出
                                                if0=1;//返回设置的时长
                                                flag_eeprom1=1;
                                        }
                                }
                        }
                }       
        }
           switch (i){
                     case 1: s10(); xuaze(bainum1); if(keynum==1 || keynum==0){p1 = 0;}p2 = 1;p3 = 1;break;
                  case 2: s10(); xuaze(shinum1); if(keynum==2 || keynum==0){p2 = 0;}p1 = 1;p3 = 1;break;
                  case 3: s10(); xuaze(genum1);  if(keynum==3 || keynum==0){p3 = 0;}p1 = 1;p2 = 1;break;
                  default:i=0;s10(); break;
                }

}       

void timer0_1init(){//定时器声明
        TMOD=0x11;//将定时器0,1都设置为模式1
        TL0 = 0x18;                //设置定时初值
        TH0 = 0xFC;                //设置定时初值
        TR0=1;//开启定时器0
        TR1=1;//开启定时器1
        EA=1;//开总中断
        ET0=1;//开定时器0的中断
}          
/**********************数码管显示部分开始**************************/
void displaynums(){//将数字传到数码管上显示
        if (if0==0){//当if0==0时num1三个数码管进行显示               
                genum1=inum2%10;//个位
                shinum1=inum2/10%10;//十位
                bainum1=inum2/100;//百
        }else{
                bainum1=bainum11;
                shinum1=shinum11;
                genum1=genum11;
                inum1=bainum11*100+shinum11*10+genum11;        //将num1三个数码管的值付给inum
                inum2=inum1;
        }                         
}
void s0(){pa = 1;pb = 1;pc = 1;pd = 1;pe = 1;pf = 1;pg = 0;}
void s1(){pb = 1;pc = 1;pa = 0;pg = 0;pd = 0;pe = 0;pf = 0;}
void s2(){pa = 1;pb = 1;pg = 1;pe = 1;pd = 1;pf = 0;pc = 0;}
void s3(){pa = 1;pb = 1;pg = 1;pc = 1;pd = 1;pf = 0;pe = 0;}
void s4(){pb = 1;pg = 1;pc = 1;pf = 1;pa = 0;pd = 0;pe = 0;}
void s5(){pa = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 0;pb = 0;}
void s6(){pa = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 1;pb = 0;}
void s7(){pa = 1;pb = 1;pc = 1;pf = 0;pe = 0;pd = 0;pg = 0;}
void s8(){pa = 1;pb = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 1;}
void s9(){pa = 1;pb = 1;pg = 1;pc = 1;pd = 1;pf = 1;pe = 0;}
void s10(){pa =0;pb = 0;pc = 0;pf = 0;pe = 0;pd = 0;pg = 0;}
void xuaze(unsigned char j){
        if(j == 0){s0();}
        else if(j == 1){s1();}
        else if(j == 2){s2();}
        else if(j == 3){s3();}
        else if(j == 4){s4();}
        else if(j == 5){s5();}
        else if(j == 6){s6();}
        else if(j == 7){s7();}
        else if(j == 8){s8();}
        else if(j == 9){s9();}}
/**********************数码管显示部分结束**************************/
/**********************掉电存储部分开始**************************/
//掉电存储
//void Delay(BYTE n){
//   WORD x;
//        while (n--){x = 0;while (++x);}
//}
//关闭IAP
void IapIdle(){
     IAP_CONTR  = 0;                     //关闭IAP功能
     IAP_CMD  = 0;                       //清除命令寄存器
     IAP_TRIG  = 0;                     //清除触发寄存器
     IAP_ADDRH  = 0x80;                  //将地址设置到非IAP区域
     IAP_ADDRL  = 0;
}
//从ISP/IAP/EEPROM区域读取一字节
BYTE IapReadByte(WORD addr){
     BYTE dat;                          //数据缓冲区
     IAP_CONTR = ENABLE_IAP;           //使能IAP
     IAP_CMD = CMD_READ;               //设置IAP命令
     IAP_ADDRL = addr;                 //设置IAP低地址
     IAP_ADDRH = addr >> 8;            //设置IAP高地址
     IAP_TRIG = 0x5a;                   //写触发命令(0x5a
     IAP_TRIG = 0xa5;                   //写触发命令(0xa5
     _nop_();                           //等待ISP/IAP/EEPROM操作完
     dat = IAP_DATA;                    //读ISP/IAP/EEPROM数据
     IapIdle();                         //关闭IAP功能
     return dat;                        //返回
}
//写一字节数据到ISP/IAP/EEPROM区域
void IapProgramByte(WORD addr, BYTE dat){
     IAP_CONTR = ENABLE_IAP;           //使能IAP
     IAP_CMD = CMD_PROGRAM;            //设置IAP命令
     IAP_ADDRL = addr;                 //设置IAP低地址
     IAP_ADDRH = addr >> 8;            //设置IAP高地址
     IAP_DATA = dat;                    //写ISP/IAP/EEPROM数据
     IAP_TRIG = 0x5a;                   //写触发命令(0x5a
     IAP_TRIG = 0xa5;                   //写触发命令(0xa5
     _nop_();                           //等待ISP/IAP/EEPROM操作完
     IapIdle();
}
//扇区擦除
void IapEraseSector(WORD addr){
     IAP_CONTR = ENABLE_IAP;           //使能IAP
     IAP_CMD = CMD_ERASE;              //设置IAP命令
     IAP_ADDRL = addr;                 //设置IAP低地址
     IAP_ADDRH = addr >> 8;           //设置IAP高地址
     IAP_TRIG = 0x5a;                   //写触发命令(0x5a
     IAP_TRIG = 0xa5;                   //写触发命令(0xa5
     _nop_();                           //等待ISP/IAP/EEPROM操作完
     IapIdle();
}
void saveeepro(){//掉电存储
                 inum11=inum1/100;//把int型的值拆分到char型
                 inum12=inum1%100;
                 inum21=inum2/100;
                 inum22=inum2%100;
           IapEraseSector(0);
           IapProgramByte(1, inum11);//数值1
           IapProgramByte(2, inum12);
           IapProgramByte(3, inum21);       
           IapProgramByte(4, inum22);       
           IapProgramByte(5, if0);//倒计时的状态
           IapProgramByte(6, if0s);//继电器的状态
           IapProgramByte(7, ss);//存分
}
/**********************掉电存储部分结束**************************/
void keyflag(){//按键结束调用,按键的建议使用,这样可以减小code,但是触发的不建议
           if(kt0){//当标志位kt0=1的时候进行
                   if(presstime>50){//当时间值大于一百的时候
                        kf0=1;//标志位kf0=1
                        kt0=0;//标志位kt0=0
                           presstime=0;//时间清零,重新进行
                        }
           }
}

应用举例延时接通.JPG (130.81 KB, 下载次数: 86)

应用举例延时接通.JPG

数显可编程延时接通或延时断开模块最新整理配套例程.rar

3.7 MB, 下载次数: 108, 下载积分: 黑币 -5

数显可编程延时接通或延时断开模块原理图及PCB图.rar

192.45 KB, 下载次数: 108, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏8 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:846219 发表于 2020-11-24 14:10 | 只看该作者
这个项目真的很有用

评分

参与人数 1黑币 +30 收起 理由
NMT1999 + 30 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:480051 发表于 2020-12-25 15:12 | 只看该作者
很实用的项目
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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