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

📄 sine_pwm_voltage-regulator_32_int.c

📁 sinewave inverter drawing and c code
💻 C
📖 第 1 页 / 共 2 页
字号:
;taner_nedjip@yahoo.com
#include <16F876A.h>
#device *=16
#device ADC=8
#fuses HS,WDT,PUT,BROWNOUT,NOPROTECT,NOLVP,NOCPD
#use delay(clock=20000000, RESTART_WDT)
#use fast_io(B)
#use fast_io(C)


const long sine_wave[32] = {81,162,241,318,392,462,527,588,642,691,733,768,795,  // sine wave constants;
                            815,827,831,827,815,795,768,733,691,642,588,527,462,
                            392,318,241,162,81,0};
const int volt_sine_ref[32] = {0,5,9,14,18,23,27,31,34,37,40,42,44,46,47,48,48,
                               48,47,46,44,42,40,37,34,31,27,23,18,14,9,5};
//const int delta_v_h[16] = {7,7,6,6,6,5,5,5,4,4,4,3,3,3,2,2};
//const int delta_v_l[16] = {3,3,3,3,3,3,3,2,2,2,2,1,1,1,0,0};
const int delta_corr[32] = {3,6,9,12,15,18,20,23,25,27,28,30,31,31,32,32,32,31,
                            31,30,28,27,25,23,20,18,15,12,9,6,3,0};


const int ab_chan=0, stdby_chan=1, i_chan=2, acc_chan=3, v_chan=4;
int index, sine_pol, inv_mode, stdby_mode, stdby, i, inv_on, inv_off;
int low_curr_h, low_curr_l, over_curr, short_curr, high_ab, stdby_go_blink;
int low_acc, high_acc, high_t_stop, high_t_blink, low_curr;
int low_acc_delay, acc_avg_counter, volt_ref_counter, volt_l_avg_counter, volt_h_avg_counter;
int volt_h, volt_l, volt_h_avg, volt_l_avg, delta;
int acc_v, acc_v_avg, volt_a, volt_b, stdby_i, stdby_i_h, stdby_i_l, stdby_i_avg_counter;
int volt_ref, volt_ref_avg, curr_h, curr_l, curr_h_avg, curr_l_avg;
signed int delta_h_v, delta_l_v, delta_h_ref, delta_l_ref, volt_ref_delta;
signed long int level_corr[32];
signed int shape_corr[32];
long int pwm_pos, pwm_neg;
long int volt_h_temp, volt_l_temp, volt_ref_temp, acc_v_temp, over_curr_delay;
long int stdby_delay, stdby_go_delay, high_t_delay, curr_h_temp, curr_l_temp, stdby_i_temp;
const long pwm_max=1023;
const int curr_l_max=32, short_curr_l=16, ab_max=63, volt_ref_const_h=168, volt_ref_const_l=87;
const int stdby_i_h_max=239, stdby_i_h_min=143, stdby_max=253, stdby_min=2;
const int curr_h_max=223, curr_h_min=143, curr_l_min=111, short_curr_h=239;
const int acc_max_l=92, acc_max_h=98, acc_min_l=60, acc_min_h=66;


#separate
void sine_pwm_start(void)                                                        // Start mode;
{
   set_pwm1_duty((sine_wave[index]+level_corr[index])>>1);                       // positive start sine half wave;
   output_high(PIN_C1);                                                          // A=1;
   output_low(PIN_C0);                                                           // Z=0;
   output_low(PIN_B1);
   set_adc_channel(ab_chan);
   delay_us(10);
   read_adc(ADC_START_ONLY);
   delay_us(20);
   volt_a=read_adc(ADC_READ_ONLY);
   if(volt_a>=ab_max) {
      high_ab++;
      break;
   }
   output_low(PIN_C3);
   set_adc_channel(i_chan);
   delay_us(10);
   read_adc(ADC_START_ONLY);
   delay_us(20);
   curr_h=read_adc(ADC_READ_ONLY);
   if(curr_h>=short_curr_h) {
      short_curr++;
      break;
   }
   else if(curr_h>curr_h_max) over_curr_delay++;
      else over_curr_delay=0;
}


#separate
void sine_pwm_norm(void)                                                         // Normal mode;
{
   switch (sine_pol) {
      case 0:                                                                    // negative sine half wave;
         set_adc_channel(v_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_l=read_adc(ADC_READ_ONLY);
         volt_l_temp+=volt_l;
         pwm_neg=sine_wave[index] + shape_corr[index] + level_corr[index];
         if(pwm_neg>pwm_max) pwm_neg=pwm_max;
         //if(pwm_neg<0) pwm_neg=0;
         set_pwm1_duty(pwm_neg);
         output_low(PIN_C1);                                                     // A=0;
         output_low(PIN_C0);                                                     // Z=0;
         output_high(PIN_B1);
         //set_pwm2_duty(volt_l);
         set_adc_channel(ab_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_b=read_adc(ADC_READ_ONLY);
         if(volt_b>=ab_max) {
            high_ab++;
            break;
         }
         output_low(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_l=read_adc(ADC_READ_ONLY);
         if(curr_l<=short_curr_l) {
            short_curr++;
            break;
         }
         else if(curr_l<curr_l_max){
               over_curr_delay++;
               //level_corr[index+1]-=delta_corr[index+1];
            }
            else over_curr_delay=0;
         output_high(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_h=read_adc(ADC_READ_ONLY);
         curr_h_temp+=curr_h;
         /*if(index) {
            delta_l_v=(127-volt_sine_ref[index])-volt_l;
            delta=delta_corr[index-1]>>2;
            if(delta_l_v>delta) shape_corr[index-1]--;
            else if(delta_l_v<-delta) shape_corr[index-1]++;
         }*/
         if(index==31) {
            curr_h_avg=curr_h_temp>>5;
            if((curr_h_avg<stdby_i_h)&&(!inv_on)) low_curr_l=1;
            else low_curr_l=0;
            volt_l_avg=volt_l_temp>>5;
            delta_l_ref=volt_l_avg-(volt_ref_const_l-volt_ref_delta);
            if(delta_l_ref>2) for(i=0; i<32; i++) level_corr[i]+=delta_corr[i]>>1;
            if(delta_l_ref<-2) for(i=0; i<32; i++) level_corr[i]-=delta_corr[i]>>1;
            curr_h_temp=0;
            volt_l_temp=0;
            sine_pol=1;
         }
         break;
      case 1:                                                                    // positive sine half wave;
         set_adc_channel(v_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_h=read_adc(ADC_READ_ONLY);
         volt_h_temp+=volt_h;
         pwm_pos=sine_wave[index] + shape_corr[index] + level_corr[index];
         if(pwm_pos>pwm_max) pwm_pos=pwm_max;
         //if(pwm_pos<0) pwm_pos=0;
         set_pwm1_duty(pwm_pos);
         output_high(PIN_C1);                                                    // A=1;
         output_low(PIN_C0);                                                     // Z=0;
         output_low(PIN_B1);
         //set_pwm2_duty(volt_h);
         set_adc_channel(ab_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_a=read_adc(ADC_READ_ONLY);
         if(volt_a>=ab_max) {
            high_ab++;
            break;
         }
         output_low(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_h=read_adc(ADC_READ_ONLY);
         if(curr_h>=short_curr_h) {
            short_curr++;
            break;
         }
         else if(curr_h>curr_h_max) {
               over_curr_delay++;
               //level_corr[index+1]-=delta_corr[index+1];
            }
            else over_curr_delay=0;
         output_high(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_l=read_adc(ADC_READ_ONLY);
         curr_l_temp+=curr_l;
         /*if(index) {
            delta_h_v=(127+volt_sine_ref[index])-volt_h;
            delta=delta_corr[index-1]>>2;
            if(delta_h_v>delta) shape_corr[index-1]++;
            else if(delta_h_v<-delta) shape_corr[index-1]--;
         }*/
         if(index==31) {
            curr_l_avg=curr_l_temp>>5;
            if((curr_l_avg>stdby_i_l)&&(!inv_on)) low_curr_h=1;
            else low_curr_h=0;
            volt_h_avg=volt_h_temp>>5;
            delta_h_ref=(volt_ref_const_h+volt_ref_delta)-volt_h_avg;
            if(delta_h_ref>2) for(i=0; i<32; i++) level_corr[i]+=delta_corr[i]>>1;
            else if(delta_h_ref<-2) for(i=0; i<32; i++) level_corr[i]-=delta_corr[i]>>1;
            curr_l_temp=0;
            volt_h_temp=0;
            sine_pol=0;
         }
         break;
   }
}


#separate
void sine_pwm_stop(void)                                                         // Stop mode;
{
   set_pwm1_duty((sine_wave[index]+level_corr[index])>>1);                       // negative stop sine half wave;
   output_low(PIN_C1);                                                           // A=0;
   output_low(PIN_C0);                                                           // Z=0;
   output_high(PIN_B1);
   set_adc_channel(ab_chan);
   delay_us(10);
   read_adc(ADC_START_ONLY);
   delay_us(20);
   volt_b=read_adc(ADC_READ_ONLY);
   if(volt_b>=ab_max) {
      high_ab++;
      break;
   }
   output_low(PIN_C3);
   set_adc_channel(i_chan);
   delay_us(10);
   read_adc(ADC_START_ONLY);
   delay_us(20);
   curr_l=read_adc(ADC_READ_ONLY);
   if(curr_l<=short_curr_l) {
      short_curr++;
      break;
   }
   else if (curr_l<curr_l_max){
         over_curr_delay++;
         //shape_corr[index+1]-=delta_i[index+1];
      }
      else over_curr_delay=0;
}


#separate
void sine_pwm_stdby(void)                                                        // Standby mode;
{
   switch (stdby_mode) {
      case 0:
         sine_pwm_start();
         if(index==31) {
            stdby_mode++;
         }
         break;
      case 1:                                                                    // negative sine half wave;
         pwm_neg=sine_wave[index] + level_corr[index];
         if(pwm_neg>pwm_max) pwm_neg=pwm_max;
         //if(pwm_neg<0) pwm_neg=0;
         set_pwm1_duty(pwm_neg);
         output_low(PIN_C1);                                                     // A=0;
         output_low(PIN_C0);                                                     // Z=0;
         output_high(PIN_B1);
         set_adc_channel(v_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_l=read_adc(ADC_READ_ONLY);
         volt_l_temp+=volt_l;
         set_adc_channel(ab_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_b=read_adc(ADC_READ_ONLY);
         if(volt_b>=ab_max) {
            high_ab++;
            break;
         }
         output_low(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_l=read_adc(ADC_READ_ONLY);
         if(curr_l<=short_curr) {
            short_curr++;
            break;
         }
         else if (curr_l<curr_l_max){
               over_curr_delay++;
               //shape_corr[index+1]-=delta_i[index+1];
            }
            else over_curr_delay=0;
         output_high(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_h=read_adc(ADC_READ_ONLY);
         curr_h_temp+=curr_h;
         if(index==31) {
            curr_h_avg=curr_h_temp>>5;
            if(curr_h_avg>=stdby_i_h) stdby=0;
            volt_l_avg=volt_l_temp>>5;
            delta_l_ref=volt_l_avg-(volt_ref_const_l-volt_ref_delta);
            if(delta_l_ref>2) for(i=0; i<32; i++) level_corr[i]+=delta_corr[i]>>1;
            if(delta_l_ref<-2) for(i=0; i<32; i++) level_corr[i]-=delta_corr[i]>>1;
            curr_h_temp=0;
            volt_l_temp=0;
            stdby_mode++;
         }
         break;
      case 2:                                                                    // positive sine half wave;
         pwm_pos=sine_wave[index] + level_corr[index];
         if(pwm_pos>pwm_max) pwm_pos=pwm_max;
         //if(pwm_pos<0) pwm_pos=0;
         set_pwm1_duty(pwm_pos);
         output_high(PIN_C1);                                                    // A=1;
         output_low(PIN_C0);                                                     // Z=0;
         output_low(PIN_B1);
         set_adc_channel(v_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_h=read_adc(ADC_READ_ONLY);
         volt_h_temp+=volt_h;
         set_adc_channel(ab_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_a=read_adc(ADC_READ_ONLY);
         if(volt_a>=ab_max) {
            high_ab++;
            break;
         }
         output_low(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_h=read_adc(ADC_READ_ONLY);
         if(curr_h>=short_curr_h) {
            short_curr++;
            break;
         }
         else if(curr_h>curr_h_max) {
               over_curr_delay++;
               //shape_corr[index+1]-=delta_i[index+1];
            }
            else over_curr_delay=0;
         output_high(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_l=read_adc(ADC_READ_ONLY);
         curr_l_temp+=curr_l;
         if(index==31) {
            curr_l_avg=curr_l_temp>>5;
            if((curr_l_avg<=stdby_i_l)) stdby=0;
            volt_h_avg=volt_h_temp>>5;
            delta_h_ref=(volt_ref_const_h+volt_ref_delta)-volt_h_avg;
            if(delta_h_ref>2) for(i=0; i<32; i++) level_corr[i]+=delta_corr[i]>>1;
            else if(delta_h_ref<-2) for(i=0; i<32; i++) level_corr[i]-=delta_corr[i]>>1;
            curr_l_temp=0;
            volt_h_temp=0;
            stdby_mode++;
         }
         break;
      case 3:
         sine_pwm_stop();
         if(index==31) {
            stdby_mode=0;
            inv_mode++;
         }
         break;
   }
}


#int_timer0
void sine_pwm(void)
{
   restart_wdt();
   clear_interrupt(int_timer0);
   set_timer0(60);
   if((!low_acc)&&(!high_acc)&&(!inv_off)) {                                     // check acc value and inverter state;
      switch (inv_mode) {                                                        // check invereter mode;
         case 0:                                                                 // start mode;
            sine_pwm_start();
            if(index==31) {
               sine_pol=0;
               inv_mode++;
            }
            break;
         case 1:                                                                 // normal mode;
            if((!high_t_stop)&&(!low_curr)&&(!low_acc_delay)) {
               output_high(PIN_B4);                                              // Green LED-ON;
               output_low(PIN_B5);                                               // Red LED-OFF;
            }
            sine_pwm_norm();
            if(index==31) {
               if((low_curr_l)&&(low_curr_h)) {                                  // check for low current;
                  low_curr=1;
                  stdby_go_delay++;
                  if((!low_acc_delay)&&(!high_t_stop)) {
                     if(stdby_go_blink>30) {
                        output_high(PIN_B4);                                     // Blink Green&Red LEDs;
                        output_high(PIN_B5);
                     }
                     else {
                        output_low(PIN_B4);
                        output_low(PIN_B5);
                     }
                     if(!stdby_go_blink) stdby_go_blink=60;
                     else stdby_go_blink--;
                  }
                  if((stdby_go_delay>600)&&(!sine_pol)) {
                     stdby=1;
                     stdby_go_delay=0;
                     stdby_go_blink=60;
                     low_curr_l=0;
                     low_curr_h=0;
                     low_curr=0;
                     inv_mode++;
                     output_low(PIN_B4);
                     output_low(PIN_B5);
                  }
               }
               else {
                  low_curr=0;
                  stdby_go_delay=0;
                  stdby_go_blink=60;
               }
            }

⌨️ 快捷键说明

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