📄 sine_pwm_voltage-regulator_32_int.c
字号:
;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 + -