⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 solarctrl.cpp

📁 利用ATTINY26 mcu开发的一款太阳能电源箱的程序
💻 CPP
字号:
			//////////////////////////////////////////////////////////////
			//															//
			//				无线数据采集模块操作系统	(V1.1.00)		//
			//				建于:2007-9-26								//
            //              初完于:                                    // 
            //              测试完于:                                  // 
			//				作者:苏伟									//
			//				E_MAIL:SUWEI0527@LIVE.CN					//
			//////////////////////////////////////////////////////////////

			//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
			//												%
			//本程序是由GCC编译,由PROGRAMMERS NOTEPAD 2编写%
			//												%
			//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#include"avr/io.h"
#include<avr/interrupt.h>
#include"solar_ctrl.h"
//-----------------------------
//AD数据采集
int          adcsum;
char         adc_chnum;
bool         ADC_FINISHED;
#if debug
#define      ADCCTNUM       1
#else
#define      ADCCTNUM       6
#endif
int          adc_max;
int          adc_min;
char adccount;
ISR(SIG_ADC)//数据采集ADC
{
    char adcl;
    int adcsum1;
    
	cli();
	adcl=ADCL;
    adcsum1=ADCH;
	adcsum1<<=8;
	adcsum1+=adcl;
#if debug
	adcsum=adcsum1;
#else
	if(adc_max<adcsum1)
	adc_max=adcsum1;
	if((adccount==null)||(adc_min>adcsum1))
	adc_min=adcsum1;
	adcsum+=adcsum1;
#endif
    adccount++;
	if(adccount<ADCCTNUM)
        START_ADC();
    else
    {
        ADC_FINISHED=true;
        adccount=null;
    }
    sei();
}

char timer_cn;
ISR(SIG_OVERFLOW0)
{
    cli();
    TCNT0=0x82;   //125=7D FF-7D=82;1MHzMCUKC时,12小时误差为:5.76分钟 
                  //125个64分频为8毫秒,处理125次为 1秒 
    timer_cn++;
    if(timer_cn==timer_second)
    {
       timer_cn=0x00;
       timer_th++;//最大12小时,12X3600=43200 
       if((timer_tc!=null)&&(timer_th==timer_tc))
       {
          timer_th=0x00;
          turnoff_load();
          T0stoptimer();
       }
    }
    if(adccount==null)
       START_ADC();
    sei(); 
} 
ISR(SIG_OVERFLOW1)
{
    cli();
    sei();
} 
//--------------------------------
//
#if !tra_data
void display(char ad)
{
     if(ad==null)
     {
       PORTB&=~(1<<PORTB4);
       PORTA&=~(1<<PORTA6);
       PORTA&=~(1<<PORTA7);
       return;
     }
     if(ad==0xff)
     {
       PORTB|=1<<PORTB4;
       PORTA|=1<<PORTA6;
       PORTB|=1<<PORTA7;
       return;
     }
     if((ad&WORK_LED)!=null)
       PORTB|=(1<<PORTB4);
     else
       PORTB&=~(1<<PORTB4);
     if((ad&CHARGE_LED)!=null)
       PORTA|=(1<<PORTA6);
     else
       PORTA&=~(1<<PORTA6);
     if((ad&OVERCH_LED)!=null)
       PORTA|=(1<<PORTA7);
     else
       PORTA&=~(1<<PORTA7);
}
#else
void display(int ad)
{
     int i,j,k;
     j=0x01;
     for(i=0;i<=9;i++)
     {
       PORTB&=~(1<<PORTB4);
       if((ad&j)!=null)
        PORTA|=(1<<PORTA6);
       else
        PORTA&=~(1<<PORTA6);
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        PORTB|=(1<<PORTB4);
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        nop();
        do{
        k=PINA;
        k&=0X80;
        }while(!k);
        j<<=1;
     }
}

#endif
void beep(void)
{
     char pb;
     pb=PORTB;
     if((pb&0x04)!=null)
       PORTB&=(~(1<<PORTB2));
     else
       PORTB|=(1<<PORTB2);
}
int adc_result_op(void)
{
     int res1;
 #if debug
     res1=null;
     return adcsum;
 #else
     adcsum=adcsum-adc_max-adc_min;
     res1=adcsum/(ADCCTNUM-2);
     if(adcsum!=null)
     adcsum=null;
     adc_max=null;
     adc_min=null;
     return  res1; 
 #endif
}
int cycle_out(int vin,int vout)
{
    int sd;
    int toff;
    int vf=5;
    int vsat=3;
    if((vin<=vsat)||(vin>=vout))
    return null;
    sd=((vout+(2*vf)-vin)*100)/(vin-vf-vsat);  
    //toff=(sd*OC_CYCLE)/(sd+100);//TON 
    toff=(100*OC_CYCLE)/(sd+100); //TOFF
    if(toff>=OC_CYCLE)
    toff=null;
    return toff; 
}
void battery_chg(int batmax)
{
     int toff;
  if(batmax!=null)
  {
      if(solar_nmv!=solar_ch)//太阳电池低,升压 
      {
          toff=cycle_out(solar_nmv,batmax);
          solar_ch=solar_nmv;
          if(toff>OC_CYCLE/2)
          toff=OC_CYCLE/2;
          OC1A_V(OC_CYCLE-toff);//此值为 Toff  
          OC1C_V(OC_CYCLE);
          OC1B_V(null);
          T11CK();
      }
  }else
    if(OCR1A!=NULL)
    {
        OC1A_V(NULL);
        STOPT1CK();
    }
}
void init_register(void)
{
     //MCU寄存器设置 
     MCUCR=0X40;
     MCUSR=NULL;
     //定时器中断使能设置
     DIST1CA();
     DIST1CB();
     DIST0IE();
     DIST1IE();  
     //ADC设置
     ENADC();
     ADCCK(ADCCK128);
     ADC_CH(ADCMIN_CH); 
     ENADCIE();
     START_ADC();
     
     
     sei();
     
}
void init_port(void)
{
     cli();
     //A口设置 
 #if !tra_data
     DDRA=(1<<DDA7)|(1<<DDA6);
     PORTA=null;
#else
     DDRA=(1<<DDA6);
     PORTA=NULL;
#endif
     //B口设置
     DDRB=FULL;
     PORTB=0XC0;
      
}

void init_mem(void)
{
     int i;
     i=0x60;
     for(i=0x60;i<0xdd;i++)
     MEM_IO(i)=0x00;
     adccount=0X00;
     adc_chnum=ADCMIN_CH;
     ADC_FINISHED=false;
     low_v=false;
     first_tem=false;
     over_tem=false;
     solar_ch=null;
     load_nmv=null;
     cycle_num=low_cycle;
     load_nmv=null;
}
//-------------------------------------
//

void start_up_timer0(void)
{
     ENT0IE();
     TCNT0=0x82;         //125=7D FF-7D=82;1MHzMCUKC时,
                         //125个64分频为8毫秒,处理125次为 1秒 
                         //12个小时误差:5.76分钟。 
     T064CK();
     timer_cn=null;
     timer_tc=null;
     timer_th=null;
} 
void start_up_timer1(void)
{
     ENT1IE();
     //CTROC1A();
     //CTROC1B();
     //PWMOC1A();
     //PWMOC1B();
     STOPT1CK();
     OC1A_V(NULL);
     OC1B_V(null);
     OC1C_V(NULL); 
}
void program_start()
{
  int bt;
  int bt1=null;
  int bt2=null;
  char dis=null;
     while(1)
     {
        if(ADC_FINISHED)
        {
            feed_dog();
            switch(adc_chnum)
            {
               //dis=null; 
               case ADCCH0://太阳能板检测 
                     feed_dog();
                     bt=adc_result_op();
                     solar_nmv=(2*bt)/5;//如果bt*4,则solar_nmv将会精确到10mV 
                                        //与外接电阻有关 150ohm+10ohm
                     if(solar_nmv<=SLMIN)
                       sunup=false;
                     if(solar_nmv>=SLMAX)
                       sunup=true;
                    break; 
              //%%%%%%%%%%%%%%%%%%%%%%%%%%%      
               case ADCCH1://电池检测 
                     feed_dog();
                     
                     bt=adc_result_op();
               #if tra_data
                     display(bt);
               #endif
                     //---------过温 --------------//
                     if(over_tem)
                       break;
                     battery_nmv=(3*bt)/10;//如果bt*3,则battery_nmv将会精确到10mV 
                                        //与外接电阻有关120ohm+10ohm
                     //电池输出没有二极管就不用+7,7=0.7v 
                     //battery_nmv+=7;//没有二极管,就不用+7 
                     //---------12v过压------------//
                     low_v=false;
                     if(battery_nmv>=BATT12VMAX-10)  
                     {
                         dis|=OVERCH_LED;
                         if(sunup)
                         {
                             turnoff_solar();//太阳出来,开启太阳能充电
                         }
                               bt2=null;
                               PORTB&=(~(1<<PORTB2));
                         break;
                      }
                       dis&=0XFE;
                      
                      //----------12v欠压----------//
                      if(battery_nmv<=BATT12VMIN-10) 
                      {
                          low_v=true;
                          if(battery_nmv>=BATT12VMIN-15)
                          {
                             bt2++;
                             if(bt2>=0x1f)
                             {bt2=00;
                              beep();
                              }
                          }
                          else
                          {
                              bt2=null;
                              PORTB&=(~(1<<PORTB2));
                              dis=null;
                          }                              
                          if(sunup)
                          {
                            turnon_solar(); //太阳出来,开启太阳能充电 
                            if(solar_nmv<battery_nmv)
                            {
                                 dis|=CHARGE_LED;
                               battery_chg(BATT12VMAX); //启动PWM充电 

                            }
                            else
                            {
                               battery_chg(null);
                            }
                          }
                          break;
                      }
                      bt2=null;
                      PORTB&=(~(1<<PORTB2));
                      //---------12V正常 --------//
                      if((battery_nmv>BATT12VMIN+10)&&(battery_nmv<BATT12VMAX-10))
                      {
                         if(sunup)
                         {
                            turnon_solar(); //太阳出来,开启太阳能充电 
                            
                            if(battery_nmv>solar_nmv)
                            {
                             dis|=CHARGE_LED;
                             dis&=0xfe;
                            }
                         }else
                            turnoff_solar();
                      }
                    break;
                    
               //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
               
               case ADCCH2://电池温度检测 
                     feed_dog();
                     bt=adc_result_op();
                     #if !tra_data 
                     if(!first_tem)//记录环境温度 
                     {
                         init_tem=bt;
                         first_tem=true;
                         //应该保存到EEPROM,以备 
                     }
                     else
                     {
                         bt=bt-init_tem;
                         if(bt>=OVERTEM_BATTMAX)
                         {
                           over_tem=true;
                           turnoff_load();
                           turnoff_solar();
                         }
                         else
                           if(bt<OVERTEM_BATTMIN)
                           over_tem=false;
                     }
                     #endif
                    break;
                    
               //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
               
               case ADCCH3://定时检测 
                     feed_dog();
                     bt=adc_result_op();
               #if !tra_data 
                    if(low_v||sunup)
                      break;
                     bt/=TIMERADC_SCALE;
                     if(bt!=null)
                     {
                        start_up_timer0();
                        bt*=TIMER_TMIN;
                        timer_tc=bt;
                     }
               #endif
                    break;
                    
                    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                    
               case ADCCH4://负载电压检测
               //无负载则会间隙工作 
                     feed_dog();
                     bt=adc_result_op();
                     bt1=bt;
                     bt1*=12;//校正误差11.7% 
                     bt1/=100;
                     bt+=bt1;
              #if !tra_data
                   if(low_v||over_tem)
                    {
                      turnoff_load();
                      dis&=0xf9;
                      break;
                    }
                    turnon_load();
                    dis|=WORK_LED;
                    output_nmv=(2*bt)/5;//如果bt*4,则output_nmv将会精确到10mV 
                                        //与外接电阻有关150ohm+10ohm
                    #endif
                    break;
                    
               //%%%%%%%%%%%%%%%%%%%%%%%%
                    
               default:
                    feed_dog();
                    adc_chnum=ADCMIN_CH;
                    break;    
            }  
           ADC_FINISHED=false;                        
           adc_chnum++;
           ADC_CH(adc_chnum);
           if(adc_chnum>ADCMAX_CH)
           {
              adc_chnum=ADCMIN_CH;
              ADC_CH(ADCMIN_CH);
           }
           START_ADC();
       #if !tra_data 
           display(dis);
       #endif
        }
     }
}
void EN_wtdog(void)
{
     WDTCR=0X18;
     WDTCR=(1<<bit3)|(1<<bit1);
 }
int main(void)
{
    init_port();
    init_mem();
    init_register();
    start_up_timer0();
    start_up_timer1();    
    EN_wtdog();
    program_start(); 
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -