电路原理图如下:
image.png
主控用的STC15W408AS:
STC15W408AS单片机芯片是STC生产的单时钟/机器周期(1T)的单片机,是宽电压/高速/高可靠/低功耗/超强抗干扰的新一代8051单片机,采用STC第九代加密技术,无法解密,指令代码完全兼容传统8051,但速度快8-12倍。 内部集成高精度R/C时钟(±0.3%),±1%温飘(-40℃~+85℃),常温下温飘±0.6%(-20℃~+65℃),ISP编程时5MHz~35MHz宽范围可设置,可彻底省掉外部昂贵的晶振和外部复位电路(内部已集成高可靠复位电路,ISP编程时16级复位门槛电压可选)。3路CCP/PWM/PCA,8路高速10位A/D转换(30万次/秒),1组超高速异步串行通信口( UART,可在3组管脚之间进行切换,分时复用可作3组串口使用),1组高速同步串行通信端口SPI,针对串行口通信/电机控制/强干扰场合。内置比较器,功能更强大。
image.png
#include <STC15F2K60S2.H> //STC15系列单片机头文件都是这个。
  • #define uchar unsigned char
  • #define uint unsigned int
  • #include <STC15F2K60S2.H>
  • #define         MAIN_Fosc                24000000UL        //定义主时钟
  • uchar num=0; //对可控硅移相角控制
  • uchar jishuqi=0;  //记录中断次数,有软起动作用,值不电输出电压不变
  • uchar  sec1=0;
  •   uchar  sec10=0;
  •    uchar  sec100=0;
  •           uchar  sec1000=0;
  • sbit cdqd=P3^3;//启动充电信号0开1关
  • sbit fdqd=P3^4;//启动放电信号0开1关
  • //sbit cdr=P3^5;//充电停止信号 1关,0开
  • sbit fd=P3^7;//充电可控硅通断  0:放电 1:关闭
  • sbit pwm1=P3^5;//放电可控硅位通  0导通,1关闭
  • sbit pwm2=P3^6;//放电可控硅位通  0导通,1关闭
  •   // sbit led=P1^0;        实验板指示灯
  •     sbit led=P1^2;
  •         sbit cf=P1^0;
  • unsigned char i;
  • unsigned int ms;
  • void        delay_ms( ms);
  • /////////////主程序
  • void main()
  • {   cdqd=1;        
  •         fd=1;
  •         pwm1=1;
  •         cf=1;
  •                
  •          //初始化
  •         TMOD=0x01;
  •   // TL0 = 0xa6;                //设置定时初始值 0.1ms
  • //         TH0 = 0xFf;                //设置定时初始值
  • // TL0 = 0x4a;                //设置定时初始值0.2ms
  • //        TH0 = 0xFf;                //设置定时初始值
  •   //  TL0 = 0x91;                //设置定时初始值0.4ms
  • //        TH0 = 0xFe;                //设置定时初始值
  •    // TL0 = 0x38;                //设置定时初始值0.5ms
  • //        TH0 = 0xFe;                //设置定时初始值
  •         
  •    TL0 = 0x9c;                //设置定时初始值        0.1ms
  •         TH0 = 0xFf;                //设置定时初始值
  •    // TL0 = 0x68;                //设置定时初始值        1ms
  •         //TH0 = 0xFC;                //设置定时初始值
  •         EA=0;
  •         ET0=1;
  •         EX0=1;         
  •         IT0=0;//必须设外部中断触发方式为上升沿下降沿同时触发。STC最新15系列单片机外部中断INT0口有上下沿同时触发功能
  •         pwm1=1;
  •         pwm2=1;
  •         led=1;
  •           //   EA=1;
  •         //         TR0=1;
  •         while(1){  
  •                     while(cdqd==0){EA=1; }                         //充电启动
  •                           //  if(cdqd==0){EA=1;        cf=0; }                         //充电启动
  •               jishuqi=0;
  •                     if(cdqd==1){EA=0; jishuqi=0;  }                          //充电关闭
  •                           if(fdqd==0){jishuqi=0; fd=0;        for(i=0;i<3;i++); fd=1;        for(i=0;i<3;i++);         }//放电延时2us};
  •                         //        fd=1;
  •          // if(cf==0)        {
  •                    ////////////////////////////////////////
  •                          //        delay_ms(500);
  •                                  
  •                                 led=~led;
  •                 //                pwm=0;
  •                                        
  •                  // delay_ms(500);
  •                 //                 pwm=1;
  •                     // led=0;
  •                
  •                           // }
  •                 /////////////////////////////////////////////
  •                }
  • }
  • //延时程序
  •    void  delay_ms(ms)
  • {
  •      unsigned int i;
  •          do{
  •               i = 200;
  •                   while(--i)        ;   //14T per loop
  •      }while(--ms);
  • }
  •           void Timer0Init(void)                //1000微秒@24.000MHz
  • {
  •         AUXR |= 0x80;                //定时器时钟1T模式
  •         TMOD &= 0xF0;                //设置定时器模式
  •         TMOD |= 0x01;                //设置定时器模式
  •         TL0 = 0x40;                //设置定时初始值
  •         TH0 = 0xA2;                //设置定时初始值
  •         TF0 = 0;                //清除TF0标志
  •         TR0 = 1;                //定时器0开始计时
  • }
  • //1毫秒定时器中断程序                  
  • void t0() interrupt 1
  • {
  •         unsigned char i;
  • TL0=0x9c;
  • TH0=0xff;                   //1haomiandingshi
  •   // TL0 = 0xa6;                //设置定时初始值 0.1ms
  • //         TH0 = 0xFf;                //设置定时初始值
  • // TL0 = 0x4a;                //设置定时初始值0.2ms
  • //        TH0 = 0xFf;                //设置定时初始值
  •   //  TL0 = 0x91;                //设置定时初始值0.4ms
  • //        TH0 = 0xFe;                //设置定时初始值
  •    // TL0 = 0x38;                //设置定时初始值0.5ms
  • //        TH0 = 0xFe;                //设置定时初始值
  •         
  • //  TL0 = 0x9c;                //设置定时初始值        0.1ms
  • //        TH0 = 0xFf;                //设置定时初始值
  •         // led=~led;
  • //         pwm=~pwm;
  •          num++;
  •          
  •          // jishuqi=8;                固定电压输出               
  •    //        if(jishuqi>4) {jishuqi=5;  if(cdqd==0){}}  //全导通
  • //jishuqi=4;
  •         //第一个半波
  • if(jishuqi==1){
  •                         if(num==75)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                      {
  •                         TR0=0;
  •                         pwm1=0;        //触发MOC3021导通,即触发可控硅导通
  •                         pwm2=0;        //触发MOC3021导通,即触发可控硅导通
  •                         for(i=0;i<2;i++);//延时2us
  •                         pwm1=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •                         pwm2=1;        //触发MOC3021导通,即触发可控硅导通
  •                         num=0;        //清零变量
  •                // led=~led;        //验证指示LED
  •                          //led=0;
  •                      }         
  •              }                //
  •                   if(jishuqi==2){
  •                         if(num==70)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                      {
  •                         TR0=0;
  •                         pwm1=0;        //触发MOC3021导通,即触发可控硅导通
  •                                 pwm2=0;        //触发MOC3021导通,即触发可控硅导通
  •                         for(i=0;i<2;i++);//延时2us
  •                         pwm1=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •                         pwm2=1;        //触发MOC3021导通,即触发可控硅导通
  •                         num=0;        //清零变量
  •          // led=~led;        //验证指示LED
  •                          //led=0;
  •                      }         
  •              }                //
  •                  
  •                   if(jishuqi==3){
  •                         if(num==65)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                      {
  •                         TR0=0;
  •                         pwm1=0;        //触发MOC3021导通,即触发可控硅导通
  •                                 pwm2=0;        //触发MOC3021导通,即触发可控硅导通
  •                         for(i=0;i<2;i++);//延时2us
  •                         pwm1=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •                         pwm2=1;        //触发MOC3021导通,即触发可控硅导通
  •                         num=0;        //清零变量
  •           //led=~led;        //验证指示LED
  •                          //led=0;
  •                      }         
  •              }                //
  •                            if(jishuqi==4){
  •                         if(num==60)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                      {
  •                         TR0=0;
  •                         pwm1=0;        //触发MOC3021导通,即触发可控硅导通
  •                                 pwm2=0;        //触发MOC3021导通,即触发可控硅导通
  •                         for(i=0;i<2;i++);//延时2us
  •                         pwm1=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •                         pwm2=1;        //触发MOC3021导通,即触发可控硅导通
  •                         num=0;        //清零变量
  •          // led=~led;        //验证指示LED
  •                          //led=0;
  •                      }         
  •              }                //
  •                            if(jishuqi>=5){
  •                         if(num==50)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                      {
  •                         TR0=0;
  •                         pwm1=0;        //触发MOC3021导通,即触发可控硅导通
  •                                 pwm2=0;        //触发MOC3021导通,即触发可控硅导通
  •                         for(i=0;i<2;i++);//延时2us
  •                         pwm1=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •                         pwm2=1;        //触发MOC3021导通,即触发可控硅导通
  •                         num=0;        //清零变量
  •          // led=~led;        //验证指示LED
  •                          //led=0;
  •                      }         
  •              }                //
  •                            if(jishuqi==6){
  •                         if(num==40)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                      {
  •                         TR0=0;
  •                         pwm1=0;        //触发MOC3021导通,即触发可控硅导通
  •                                 pwm2=0;        //触发MOC3021导通,即触发可控硅导通
  •                         for(i=0;i<2;i++);//延时2us
  •                         pwm1=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •                         pwm2=1;        //触发MOC3021导通,即触发可控硅导通
  •                         num=0;        //清零变量
  •              //  led=~led;        //验证指示LED
  •                          //led=0;
  •                      }         
  •              }                //
  •           if(jishuqi==7){
  •                         if(num==30)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                      {
  •                         TR0=0;
  •                         pwm1=0;        //触发MOC3021导通,即触发可控硅导通
  •                                 pwm2=0;        //触发MOC3021导通,即触发可控硅导通
  •                         for(i=0;i<2;i++);//延时2us
  •                         pwm1=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •                         pwm2=1;        //触发MOC3021导通,即触发可控硅导通
  •                         num=0;        //清零变量
  •          // led=~led;        //验证指示LED
  •                          //led=0;
  •                      }         
  •              }                //
  • if(jishuqi==8){
  •                         if(num==20)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                      {
  •                         TR0=0;
  •                         pwm1=0;        //触发MOC3021导通,即触发可控硅导通
  •                                 pwm2=0;        //触发MOC3021导通,即触发可控硅导通
  •                         for(i=0;i<2;i++);//延时2us
  •                         pwm1=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •                                 pwm2=1;        //触发MOC3021导通,即触发可控硅导通
  •                         num=0;        //清零变量
  •          // led=~led;        //验证指示LED
  •                          //led=0;
  •                      }         
  •              }                //
  •                  if(jishuqi>=9){
  •                         if(num==60)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                      {
  •                         TR0=0;
  •                         pwm1=0;        //触发MOC3021导通,即触发可控硅导通
  •                                 pwm2=0;        //触发MOC3021导通,即触发可控硅导通
  •                         for(i=0;i<2;i++);//延时2us
  •                         pwm1=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •                                 pwm2=1;        //触发MOC3021导通,即触发可控硅导通
  •                         num=0;        //清零变量                                                                         if(jish                        
  •          // led=~led;        //验证指示LED
  •                          //led=0;
  •                      }         
  •                       }                //
  •         
  •                 //第二个半波                                                
  •         //                  if(jishuqi>=10){
  •                 //        if(num==5)                //延时1毫秒导通,改变num的值即可改变移相触发时间,即改变负载功率大小。num的范围:0<num<10
  •                     // {
  •                 //        TR0=0;
  •         //                pwm=0;        //触发MOC3021导通,即触发可控硅导通
  •         //                for(i=0;i<2;i++);//延时2us
  •         //                pwm=1;        //延时2us之后,关掉脉冲输出,因为可控硅在非过零点情况下触发信号丢失,会继续保持导通。
  •         //                num=0;        //清零变量
  •           //      led=~led;        //验证指示LED
  •                          //led=0;
  •                    //  }         
  •            //  }                //
  •                 //第二个半波                                                                                                  
  •         
  •                                    //第10和大于10个半波
  •                  
  •                                       //        pwm=1;
  •                            //if(num==7){led=~led;}
  •                                    // led=~led;                //验证指示LED
  •                                           //10MS计时器
  •           // if(sec1>=10)        {sec1=0;sec10++;}
  •                 //  if(sec10>=10)        {sec10=0;sec100++;}
  •                 //         if(sec100>=10)        {sec100=0;sec1000++;}
  •                 //                 if(sec1000>=8)        {sec100=0;sec1000++;}
  • }               
  •           //中断程序
  • void ex0() interrupt 0
  • {
  •         IE0=0;
  •         num=0;
  • //        jishuqi++;        //软起过程的半波个数
  •         TR0=1;          //交流过零点的时候,清楚标志、计数变量并启动定时器。 /
  • //        cf=0;
  • sec1++;
  •    if(sec1>=10){sec1=0;jishuqi++;}                                        //sec可以改移相角导通时间
  •         //jishuqi=1;         
  •          if(jishuqi>=7){jishuqi=7;}                                        //sec可以改移相角导通时间           
  • }                                 
  • 复制代码