找回密码
 立即注册

QQ登录

只需一步,快速开始

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

无线单路可编程遥控带数码管延时程序四位数码管显示倒计时遥控继电器

[复制链接]
跳转到指定楼层
楼主
ID:280979 发表于 2019-11-17 23:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<STC15W408AS.h>                 //库文件
#include <intrins.H>
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int  //宏定义无符号整型
typedef unsigned char  INT8U;
typedef unsigned int   INT16U;
#define ENABLE_ISP 0x82 //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值
#define WD1        0x5a        //使用STC11xx系列单片机时,先写入0x5a,然写入0xa5
#define WD2        0xa5
char IAPAddr=0;
/********************************************************************
                            初始定义
*********************************************************************/
static uint ss=0; //ss为静态
uint t=0,smg=0,ge=0,shi=0,bai=0,qian=0,y=0,s=0,j=0,z=0,k=0,a=0,kf=0,zz=0,sd=0,sv=0,so=0,sl=0;
sbit aj1=P3^0; //选位         
sbit aj2=P3^1; //加时间
sbit L1=P3^5; //数码管1
sbit L2=P3^4; //数码管2
sbit L3=P3^3; //数码管3
sbit L4=P3^2; //数码管
sbit out = P3^7;   //继电器
sbit in_1 = P3^6;   //输入触发端
sbit in_2 = P5^4;   //遥控输入触发端
sbit in_3 = P5^5;   //遥控输入触发端
code uchar seg7code[10]={0x6F,0x21,0x8F,0xAB,0xE1,0xEA,0xEE,0x23,0xEF,0xEB}; //显示段码 数码管字跟
uchar x;
uchar wei=0;
/********************************************************************
                            延时函数
*********************************************************************/
union union_temp16
{
    INT16U un_temp16;
    INT8U  un_temp8[2];
}my_unTemp16;

INT8U Byte_Read(INT16U add);              //读一字节,调用前需打开IAP 功能
void Byte_Program(INT16U add, INT8U ch);  //字节编程,调用前需打开IAP 功能
void Sector_Erase(INT16U add);            //擦除扇区
void IAP_Disable();                       //关闭IAP 功能
void Delay();
/*******************************************************************
*                        选位按键
********************************************************************/
void key_1(){
    if(aj1==0)
         {
           if(ss>220){ ss=0;
                if(aj1==0){
                     z=1;
                      y+=1;//选位标志位
                           k=0;                //倒计时标志位
                            out=1;         //停止输出
                           if(y==5){
                             y=0;           //选位标志重个位开始重新选
                                 z=0;          //全部显示
                                 s=sd+sv+so+sl;        //把s值给kf
                                 kf=s;
                                 Sector_Erase(0);   //擦除EEPROM
                                 Byte_Program(1, (sd));  //写入扇区
                                 Byte_Program(2, (sv/10));
                                 Byte_Program(3, (so/100));
                                 Byte_Program(4, (sl/1000));
                          }
                        }
                  }
           while(aj1==0);
         }
  }
/*******************************************************************
*                        加按键
********************************************************************/
void key_2(){
    if(aj2==0)
         {
           if(ss>220){ ss=0;
                if(aj2==0){
                     if(y==1){          //个位
                                   sd+=1;
                                     if(sd==10){
                                           sd=0;
                                          }
                                    }
                    if(y==2){           //十位
                                   sv+=10;
                                     if(sv==100){
                                          sv=0;
                                         }
                                   }
                        if(y==3){                //百位
                                    so+=100;
                                          if(so==1000){
                                            so=0;
                                          }
                                          }
                         if(y==4){                //百位
                                    sl+=1000;
                                          if(sl>9999){
                                            sl=0;
                                          }
                                   }
                        // if(s>=10000){s=9999;}
                        }
                  }
           while(aj2==0); //按一下加一下
         }
  }
/*******************************************************************
*                        暂停,继续按键
********************************************************************/
void key_3(){
    if(in_3==1)
         {
           if(ss>220){ ss=0;
                if(in_3==1){
                           zz++;
                         if(zz==1){k=0;out=1;}  
                         if(zz==2){k=1;zz=0;}
                        }
                  }
           while(in_3==1);
         }
  }
/*******************************************************************
*                        定时器配置
********************************************************************/
void ConfigTimer0(){
        TMOD=0x01;//将定时器0,1都设置为模式1
    TH0=0XFC;//1ms
    TL0=0X66;
        TR0=1;//开启定时器0
        ET0=1;//开定时器0的中断
        EA=1;//开总中断
}

/*******************************************************************
*                         显示
********************************************************************/
void led(uint date)
{
qian=date/1000;
bai=date%1000/100;
shi=date%100/10;
ge=date%10;
}

/********************************************************************
                            主函数
*********************************************************************/
void main()
{
     P1M0 = 0xff;
     P1M1 = 0x00;
         //P3M0 = 0x34;
     //P3M1 = 0x00;
         ConfigTimer0();
          // out=0;
           ge= Byte_Read(1);    //读EEPROM的值,存到read_eeprom  
          shi= Byte_Read(2);    //读EEPROM的值,存到read_eeprom
          bai= Byte_Read(3);    //读EEPROM的值,存到read_eeprom
         qian= Byte_Read(4);    //读EEPROM的值,存到read_eeprom
          s=ge+shi*10+bai*100+qian*1000;
          kf=s;
           while(1)
    {          
           key_1();
            key_2();
                key_3();
                if(in_1==0){         //P3.6口输入标志位
                k=1;
                }
                         if(in_2==1){ //        遥控从新开始计数
                 k=1;s=kf;zz=0;j=0;
                    }
          if(y==0){led(s);}
          if(y==1){led(sd);}
          if(y==2){led(sv);}
          if(y==3){led(so);}
          if(y==4){led(sl);}
          }
}
/********************************************************************
                            定时中断服务函数
*********************************************************************/
void t0(void) interrupt 1 //定时中断服务函数
{
    TH0=0xFC;
    TL0=0x66;
    ss++;
     if(z==0){
          smg++;
          }
           else{
             smg=y;//让逐个显示位
           }          
                if(k==1){
                 out=0;
                    j++;  // 让毫秒变秒
                         if(j==1000){        //1s
                           s-=1; //减时间
                            j=0;
                         if(s==0){
                           out=1;        //输出
                            s=kf;         //归刚刚设定的值
                             k=0;        //倒计时位归0
                           }
                         }
                  }
        switch(smg)
        {
          case 1:  P1=seg7code[ge]; L1=1;L2=1;L3=1;L4=0;break;
          case 2:  P1=seg7code[shi]; L1=1;L2=1;L3=0;L4=1;break;
          case 3:  P1=seg7code[bai]; L1=1;L2=0;L3=1;L4=1;break;
          case 4:  P1=seg7code[qian]; L1=0;L2=1;L3=1;L4=1;break;
          default:  smg=0;L1=1;L2=1;L3=1;L4=1; break;
        }
}
       

/*********************************************************************************************
*********************************************************************************************/
//读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节
INT8U Byte_Read(INT16U add)
{
    IAP_DATA = 0x00;
    IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x01;                 //IAP/ISP/EEPROM 字节读命令

    my_unTemp16.un_temp16 = add;
    IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
    IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址

    //EA = 0;
    IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
    return (IAP_DATA);
}
/*********************************************************************************************/
//字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据
void Byte_Program(INT16U add, INT8U ch)
{
    IAP_CONTR = ENABLE_ISP;         //打开 IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x02;                 //IAP/ISP/EEPROM 字节编程命令

    my_unTemp16.un_temp16 = add;
    IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
    IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址

    IAP_DATA = ch;                  //要编程的数据先送进IAP_DATA 寄存器
    //EA = 0;
    IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
/*********************************************************************************************
//擦除扇区, 入口:DPTR = 扇区地址 */
void Sector_Erase(INT16U add)
{
    IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x03;                 //IAP/ISP/EEPROM 扇区擦除命令

    my_unTemp16.un_temp16 = add;
    IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
    IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址

    //EA = 0;
    IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
/*********************************************************************************************/
void IAP_Disable()
{
    //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
    IAP_CONTR = 0;      //关闭IAP 功能
    IAP_CMD   = 0;      //清命令寄存器,使命令寄存器无命令,此句可不用
    IAP_TRIG  = 0;      //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
    IAP_ADDRH = 0;
    IAP_ADDRL = 0;
}
/*********************************************************************************************/

无线单路可编程遥控带数码管延时模块原理图及PCB图.rar

251.61 KB, 下载次数: 30, 下载积分: 黑币 -5

程序包.rar

516.53 KB, 下载次数: 31, 下载积分: 黑币 -5

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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