用户
 找回密码
 注册
1#
跳转到指定楼层

自制电源瞬变发生器

[复制链接]
本帖最后由 cdmzxh 于 2017-12-3 17:12 编辑

为了应付消防部门派来厂里的电子3C检查,厂里的消防电子产品必须要有做过电源瞬变试验才算合格,市面上与网上都没有“电源瞬变发生器”这种产品,刚好俺学了51m88,就自制了一台,调试了1天,基本上可以对付使用。http://v.youku.com/v_show/id_XMzIwNjg1NzcwMA==.html?spm=a2h3j.8428770.3416059.1
以下是程序

#include<stc12c5620AD.h>
#define uint unsigned int
#define uchar unsigned char

sbit k1=P2^0; //输出继电器
sbit s1=P3^4; //启动按钮
sbit s2=P3^3; //暂停按钮
sbit LED1=P2^5;        //电源指示
sbit LED3=P2^4;        //断电指示
sbit LED2=P3^5;        //通电指示
sbit bee=P2^1;

bit flg0=0;
bit flg1=0;


sbit en=P3^7;           //位定义使能信号输入端
sbit rs=P2^6;           //位定义数据、命令选择端
sbit rw=P2^7;
uint t=0;
uint time=0;
uint time0=0;
uint time1=0;
//uint time2=0;
uint count=0;

void init_Timer0();//定时器0初始化

void write_xs(uchar add,uint dat);  //显示程序(add是地址,dat是数据)
void write_dc(uchar add1,uint dat); //显示程序(add是地址,dat是数据)
void init_xian_shi();
void init_xian_shi2();
void init_xian_shi3();
void init_1602();             //初始化函数
void reset();   //复位


void delay(uint t)
{
  uint x,y;
  for(x=t;x;x--)
  {
          for(y=120;y;y--);
  }
}

void init_Timer0()//定时器0初始化
{
        TMOD=0x11;
        TH0=(65536-1000)/256;//定时0.1毫秒
        TL0=(65536-1000)%256;
        TR0=1;
        ET0=1;
        EA=1;
}


void Timer0() interrupt 1 //定时器0中断模式1                 1mS
{
        TH0=(65536-1000)/256;
        TL0=(65536-1000)%256;
        TR0=1;
        if(flg0)               
        {               
                if(time0)
                {
                        time0--;       
                        if(time0>=1000)
                        {
                                k1=1;
                                LED2=1;
                                LED3=0;          
                        }
                        else
                        {
                            k1=0;
                                LED2=0;
                                LED3=1;
                        }       
                }       
                else
                {
                          k1=0;
                        LED2=0;
                        LED3=1;               
                        write_xs(6,count);
                        time0=10000;
                        count++;        
                }
                if(t)
                {  
                        t--;
                }
                else
                {
                        time++;
                        if(time==5000)
                                time=0;
                        write_dc(0x45,time);
                        t=1000;       
                }        
        }  
}


void write_com(uchar com)//命令函数
{
        rs=0;
        P1=com;
        delay(1);
        en=1;
        delay(2);
        en=0;
}

void write_dat(uchar dat)//数据函数
{
        rs=1;
        P1=dat;
        delay(1);
        en=1;
        delay(2);
        en=0;
}

void init_1602()             //初始化函数
{
        delay(50);
    en=0;
        rw=0;
       
        write_com(0x38);//将液晶设置为8位数据线格式,2行字符显示
        delay(5);
        write_com(0x38);//将液晶设置为8位数据线格式,2行字符显示
        delay(5);      
        write_com(0x38);//将液晶设置为8位数据线格式,2行字符显示
        delay(5);
        write_com(0x08);//
        delay(5);     
        write_com(0x0c);//将液晶设置为显示功能开,无光标,不闪烁
        delay(5);      
        write_com(0x06);//将液晶设置为写入新数据后光标右移
        delay(5);      
        write_com(0x01);//清除液晶显示屏幕信息,将光标撤回液晶显示屏的左上方并且将地址计数器(AC)的值设为0
        delay(5);
}

void write_xs(uchar add,uint dat) //显示程序(add是地址,dat是数据)
{
         uint bai; uchar shi,ge;              //定义三个变量,百位,十位,个位
     bai=dat/100;                                                 //数据对百求模
         shi=dat%100/10;                                         //数据对百求余对十求模
         ge=dat%10;                     //数据对十求余
         write_com(0x80+add);
         write_dat(0x30+bai);       
     write_dat(0x30+shi);
         write_dat(0x30+ge);
}

void write_dc(uchar add1,uint dat) //显示程序(add是地址,dat是数据)
{
         uint qian, bai; uchar shi,ge;              //定义三个变量,百位,十位,个位
         qian=dat/1000;
     bai=dat%1000/100;                                                 //数据对百求模
         shi=dat%100/10;
         ge=dat%10;                     //数据对十求余
         write_com(0x80+add1);
         write_dat(0x30+qian);
         write_dat(0x30+bai);       
     write_dat(0x30+shi);  
         write_dat(0x30+ge);
}

void init_xian_shi()
{
        write_xs(6,count);                                         //计数显示地址初始化
        write_dc(0x45,time);                   //时间显示地址初始化

        write_com(0x80);    write_dat('C');    //显示次数初值Count=000         
    write_com(0x81);        write_dat('o');
    write_com(0x82);        write_dat('u');
        write_com(0x83);        write_dat('n');       
        write_com(0x84);        write_dat('t');
        write_com(0x85);        write_dat(':');
        write_com(0x86);        write_dat('0');
        write_com(0x87);        write_dat('0');
        write_com(0x88);        write_dat('0');

        write_com(0x80+0x40); write_dat('T');   //显示时间初值Time=000ms
        write_com(0x80+0x41); write_dat('i');
        write_com(0x80+0x42); write_dat('m');
        write_com(0x80+0x43); write_dat('e');
        write_com(0x80+0x44); write_dat(':');
        write_com(0x80+0x45); write_dat('0');
        write_com(0x80+0x46); write_dat('0');                                                                       
        write_com(0x80+0x40+7);  write_dat('0');
    write_com(0x80+0x40+8); write_dat('0');
        write_com(0x80+0x40+9); write_dat('s');

}

void init_xian_shi2()
{
        write_xs(6,count);                                         //计数显示地址初始化
        write_dc(0x45,time);                   //时间显示地址初始化


        write_com(0x80);    write_dat('C');    //显示次数初值Count=000         
    write_com(0x81);        write_dat('o');
    write_com(0x82);        write_dat('u');
        write_com(0x83);        write_dat('n');       
        write_com(0x84);        write_dat('t');
        write_com(0x85);        write_dat(':');
        write_com(0x80+10);        write_dat('S');
        write_com(0x80+11);        write_dat('T');
        write_com(0x80+12);        write_dat('O');
        write_com(0x80+13);        write_dat('P');
        write_com(0x80+0x40); write_dat('T');   //显示时间初值Time=000ms
        write_com(0x80+0x41); write_dat('i');
        write_com(0x80+0x42); write_dat('m');
        write_com(0x80+0x43); write_dat('e');
        write_com(0x80+0x44); write_dat(':');
        write_com(0x80+0x40+9); write_dat('s');

}

void init_xian_shi3()
{
        write_xs(6,count);                                         //计数显示地址初始化
        write_dc(0x45,time);                   //时间显示地址初始化

        write_com(0x80);    write_dat('C');    //显示次数初值Count=000         
    write_com(0x81);        write_dat('o');
    write_com(0x82);        write_dat('u');
        write_com(0x83);        write_dat('n');       
        write_com(0x84);        write_dat('t');
        write_com(0x85);        write_dat(':');
        write_com(0x80+0x40); write_dat('T');   //显示时间初值Time=000ms
        write_com(0x80+0x41); write_dat('i');
        write_com(0x80+0x42); write_dat('m');
        write_com(0x80+0x43); write_dat('e');
        write_com(0x80+0x44); write_dat(':');
        write_com(0x80+0x40+9); write_dat('s');
        write_com(0x80+0x40+11); write_dat('O');
        write_com(0x80+0x40+12); write_dat('N');
}

void DYSB()/*电源瞬变*/
{       
        uchar as;
        bit s_flg=0;  //按键标志
        flg0=0;
        if(s1==0)          //按下启动按键
        {       
                while(s1==0);//等松手
                flg0=1;                 //开始计时
        //        flg1=1;
                LED3=0;                 //断电灯灭
                init_1602();
                delay(20);
                init_xian_shi3();//刷新液晶显示
                while(1)
                {       
                        if(s2==0&&s_flg==0)        //按下暂停按键
                        {        flg0=0;                        //停止计时
                                delay(30);as++;
                        }
                        else as=0;
                       
                        if(as>=50)
                        {       
                               
                                k1=0;                        //
                                LED2=0;
                                LED3=1;
                                init_1602();
                                delay(20);
                                init_xian_shi2();
                        //        while(s2==0);  //等松手
                                s_flg=1;           //按键标志转换
                        }
                        if(s1==0&&s_flg==1)//按下启动按键
                        {       
                                while(s1==0&&s_flg==1);//等松手
                                init_1602();
                                delay(20);
                                init_xian_shi3(); //刷新液晶显示
                                flg0=1;                          //开始计时
                                LED3=0;
                                s_flg=0;                  //按键标志转换
                        }
                         if(count>=500)                //运行500次
                        {       
                                flg0=0;                        //停止计时
                        //        flg1=0;               
                                init_1602();
                                delay(20);
                                init_xian_shi2();
                                write_xs(6,count);//刷新液晶显示
                                k1=0;                          //切断电源
                                LED2=0;                          //通电灯灭
                                LED3=1;                          //断电灯亮
                                while(1)
                                {       
                                        if(s2==0)          //按暂停键复位
                                                delay(30);
                                        if(s2==0)
                                        {
                                                while(s2==0);
                                                time=0;
                                                count=0;
                                                reset();   //复位
                                        }
                                }       
                        }
                }
        }
}

void reset()   //复位
{
        ((void (code *) (void)) 0x0000) ();       
}

void main()
{
        P3M0=0x00; //0000 0000
        P3M1=0x20; //0010 0000

        P2M0=0x00; //0000 0000
        P2M1=0x31; //0011 0001

        /*P1M0=0x00;
        P1M1=0xff;        */
        time=0;
        count=0;

        init_Timer0();//定时器0初始化
//        init_Timer1();//定时器1初始化
        init_1602();
        init_xian_shi();
        init_xian_shi2();
        flg0=0;
        k1=0;
        s1=1;
        s2=1;
        LED1=1;
        LED2=0;
        LED3=1;
        bee=1;

        while(1)
        {       
          DYSB();/*电源瞬变*/       
        }
}


911373505023208105.jpg (43.2 KB, 下载次数: 0)

911373505023208105.jpg

64641832841989018.jpg (94.45 KB, 下载次数: 0)

64641832841989018.jpg

507799314108915005.jpg (73.18 KB, 下载次数: 0)

507799314108915005.jpg

文档 10000.jpg (50.06 KB, 下载次数: 0)

文档 10000.jpg

收拾收拾0000.jpg (112.62 KB, 下载次数: 0)

收拾收拾0000.jpg
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回顶部