0
Σε συνεχεια του : http://www.hlektronika.gr/forum/showthread.php?t=82267
Ελεγα να το αφησω για το χειμωνα, ωστε να γεμισω δημιουργικα τα βραδια μου ΑΛΛΑ με τρωει
Λοιπον εβγαλα το κομματι του Inverter και ειπα να ξαναμετρησω σηματα και κυματομορφες απο τον μΕ.Tα 3-PWM που ερχονται (2 απο τον Timer1 και ενα απο τον Timer0) ειναι συγχρονισμενα μεταξυ τους αλλα μονο τετραγωνικοι παλμοι δεν ειναι. Δειτε στην εικονα και ταση αλλα και μορφη.
Και τα 3-PWM ειναι σε PhaseCorrect mode με prescaler_1. (23.5kHz συχνοτητα για κρυσταλλο 12MHz).
Ακομα και να ανανεωσεις την τιμη του PWM-καταχωρητη (κυκλο εργασιας) πριν κανει μια περιοδο δεν θα αλλαξει κατι, παρα μονο οταν ολοκληρωσει την περιοδο.Οποτε δεν μου βγαζει νοημα αυτο που γινεται.
Τα σηματα ηταν πεντακαθαρα οταν πρωτοεγραψα τον κωδικα και μου φαινεται και παραξενο να 'χαλασαν" ταυτοχρονα και τα 3 pwm-pin μαζι.
Ανεβαζω κωδικα/διαγραμμα ροης και παλμογραφηματα.
(κομματια κωδικα πχ συναρτησεις LCD αφαιρεθηκαν λογω περιορισμου μεγεθους του post)Κώδικας:/* * SV_3phase.c * Created: 5/14/2015 * Author: Savvas Kokkinidis * E-mail: Sabbaskok@hotmail.com IR2109 and IR21091 mosfet drivers, have opposite SD signals !!!!! */ #define F_CPU 12000000UL // System clock. #define WDTO_15MS 0 //*************************** #define WDTO_30MS 1 //***** WDT's times *********** #define SD_led 7 #define SD_entoli 6 #define Vdc 230 #include <util/delay.h> //********************************** #include <avr/pgmspace.h> // #include <math.h> // Libraries #include <avr/io.h> // #include <avr/interrupt.h> // #include <avr/wdt.h> //********************************* unsigned char sector = 0; // in which sector we are unsigned char step = 0 ; // in which point we are volatile unsigned char step_rate ; // accesing step of table unsigned char table_end = 179; // end of table unsigned char update = 0 ; // Time to reload PWM unsigned char OCR0_temp,OCR1A_temp,OCR1B_temp ; // Temp register to reload PWM at 'same time' unsigned char F_display ; // Inverter output Freq volatile uint16_t count=0; // Tick from Hall sensor volatile uint16_t counter_HalfSec = 0; // Use 5400Hz interupt for 1/2 Sec measure volatile uint16_t rpm=0; // RMP value uint8_t stop_lcd[] = "STOP"; // Basic diplay info. uint8_t run_lcd[] = " RUN"; uint8_t volt_lcd[] = " V= "; uint8_t freq_lcd[] = "F= Hz"; uint8_t RPM_lcd[] = "RPM= "; uint8_t W_a_i_t[] = " ** WAIT ** "; //******* Calculate with EXCEL => [Ub = sin(THETA)*255] 0 <= THETA <= 60 ************// unsigned char Ub_table[180] = { 0,1,3,4,6,7,9,10,12,13,15,16,17,19,20,22,23,25,26,28,29, 31,32,33,35,36,38,39,41,42,43,45,46,48,49,51,52,54,55,56, 58,59,61,62,63,65,66,68,69,70,72,73,75,76,77,79,80,82,83, 84,86,87,88,90,91,92,94,95,97,98,99,101,102,103,105,106, 107,108,110,111,112,114,115,116,118,119,120,121,123,124, 125,126,128,129,130,131,133,134,135,136,138,139,140,141, 142,144,145,146,147,148,150,151,152,153,154,155,156,158, 159,160,161,162,163,164,165,166,168,169,170,171,172,173, 174,175,176,177,178,179,180,181,182,183,184,185,186,187, 188,189,190,191,192,193,194,195,195,196,197,198,199,200, 201,202,203,203,204,205,206,207,208,208,209,210,211,212, 212,213,214,215,215,216 }; #define lcd_D7_port PORTA // lcd D7 connection #define lcd_D7_bit PORTA7 #define lcd_D7_ddr DDRA #define lcd_D7_pin PINA // busy flag #define lcd_D6_port PORTA // lcd D6 connection #define lcd_D6_bit PORTA6 #define lcd_D6_ddr DDRA #define lcd_D5_port PORTA // lcd D5 connection #define lcd_D5_bit PORTA5 #define lcd_D5_ddr DDRA #define lcd_D4_port PORTA // lcd D4 connection #define lcd_D4_bit PORTA4 #define lcd_D4_ddr DDRA #define lcd_E_port PORTB // lcd Enable pin #define lcd_E_bit PORTB1 #define lcd_E_ddr DDRB #define lcd_RS_port PORTB // lcd Register Select pin #define lcd_RS_bit PORTB0 #define lcd_RS_ddr DDRB #define lcd_RW_port PORTB // lcd Read/Write pin #define lcd_RW_bit PORTB5 #define lcd_RW_ddr DDRB // LCD module information #define lcd_LineOne 0x00 // start of line 1 #define lcd_LineTwo 0x40 // start of line 2 //#define lcd_LineThree 0x14 // start of line 3 (20x4) //#define lcd_lineFour 0x54 // start of line 4 (20x4) //#define lcd_LineThree 0x10 // start of line 3 (16x4) //#define lcd_lineFour 0x50 // start of line 4 (16x4) // LCD instructions #define lcd_Clear 0b00000001 // replace all characters with ASCII 'space' #define lcd_Home 0b00000010 // return cursor to first position on first line #define lcd_EntryMode 0b00000110 // shift cursor from left to right on read/write #define lcd_DisplayOff 0b00001000 // turn display off #define lcd_DisplayOn 0b00001100 // display on, cursor off, don't blink character #define lcd_FunctionReset 0b00110000 // reset the LCD #define lcd_FunctionSet4bit 0b00101000 // 4-bit data, 2-line display, 5 x 7 font #define lcd_SetCursor 0b10000000 // set cursor position //**********************// //**************************************************// void pwm_setup(); void ADC_setup(); void run_stop_setup(); void watchdog(); void lcd_write_4(uint8_t); void lcd_write_instruction_4f(uint8_t); void lcd_write_character_4f(uint8_t); void lcd_write_string_4f(uint8_t *); void lcd_init_4f(void); void lcd_check_BF_4(void); void lcd_wait_pin(void); void lcd_display_all(void); //**************************************************// void ADC_setup() { ADCSRA = 0x8D; // ADC setup, ADC enable, 32 prescaler , Interupt enable ADMUX = 0x40 ; // ADC0 signle ended , AVcc = Vcc } void other_pin_setup() { DDRD &= ~(1<<PC7); // RUN-STOP switch PORTD|= (1<<PC7); DDRA &= ~(1<<PA0); // ADC channel 0 input DDRC |= (1<<SD_led) ; // LED for run-stop DDRC |= (1<<SD_entoli) ; // Signal for SD. Shut down or no DDRD &= ~(1<<PD2); // Hall sensor input. INT0 MCUCR|=(1<<ISC01); //Falling edge on INT0 triggers interrupt. GICR|=(1<<INT0); //Enable INT0 interrupt } void watchdog() { wdt_enable(WDTO_15MS) ; // Setup WDT for 15mSec } void pwm_setup() { DDRB |= (1<<PB3); // OC0 pin - PWM1 DDRD |= (1<<PD4) | (1<<PD5) ; // OC1A & OC1B - PWM2 & PWM3 TIMSK |= (1<<TOIE0); // enable Timer0 interupt on top TIMSK |= (1<<OCIE2); OCR2 = 34; // 5405 Hz TCCR2 = 0x0C ; // 64 prescaler /* OCR0 = 0; // PWM register value OCR1A = 0; OCR1B = 0; */ TCCR1A = 0xA1; // Timer1 _ Compare Match Up Counting for both PWM2/PWM3 / Center Alligned TCCR1B=0x01; // PWM Phase Correct / 8 bit / 1 Prescaler / 2937 Hz Freq TCCR0 = 0x61; // Timer0 _ Compare Match Up Counting PWM1 / Center Alligned / 1 Prescaler / 2937 Hz Freq // Above 3 instructions must be in that order, so Timer1_PWM and Timer0_PWM are synchronized. (almost... 1 Clock_Cycle) } int main(void) { _delay_ms(500); // w8 0.5sec , for power issues other_pin_setup(); // PIN conf PORTC &= ~(1<<SD_led); // Keep power state OFF, lcd_wait_pin can be stucked if LCD isnt connected correctly. PORTC &= ~(1<<SD_entoli); // Will stuck inside busy_flag fuction. Better dont start if cant basic info ( optional) lcd_wait_pin(); // LCD pin conf AND loading pwm_setup(); // PWN pins conf and PWM register setup ADC_setup(); // ADC setup watchdog(); // WDT setup sei(); while(1) { ADCSRA |= (1<<ADSC); // fire ADC conversion lcd_display_all(); // display basic info (freq,volt,rpm, RUN-STOP) wdt_reset(); } } ISR(INT0_vect) { count++; // INT0 interupt. From hall sensor } ISR(TIMER2_COMP_vect) // Here every 185 uSec- 5405 Khz - MAX 2 uS inside inrpt { // ( 6 sector * 180 points = 1080 points , 5400/1080 = 5 Hz. Basic Frequency ! ) // Its 5405 Hz and not 5400 cause of execution time . counter_HalfSec++; if(counter_HalfSec >= 2700) { rpm=count*120; // 60*count for 1 sec, so 120*count for 0.5 sec counter_HalfSec=0; count = 0; } if (PIND & (1<<PD7)) // RUN { PORTC |= (1<<SD_led); PORTC &= ~(1<<SD_entoli); if((char)(step+step_rate) > table_end) { step = (step+step_rate) - table_end; if((char)(sector+1)==6) { sector = 0; } else { sector += 1 ; } } else { step = step + step_rate ; } update = 1; // Let other interrupt reload PWM } else // STOP { PORTC &= ~(1<<SD_led); // Power state OFF PORTC |= (1<<SD_entoli); // Power state OFF // OCR0 = 0 ; // OCR1A = 0 ; // OCR1B = 0 ; step = 0; // clear step update = 0 ; // DONT let other interrupt reload PWM } wdt_reset(); } ISR(TIMER0_OVF_vect) // Here every PWM_freq -> 2937 Khz - 340 uSec { if (update==1) // Its time to reload PWM { unsigned char Ub = (step_rate*Ub_table[step])/10; // Ub from table. /10 is used for V/F law. 10 is the basic Freq unsigned char Ua = (step_rate*Ub_table[table_end-step])/10; // Ua cant be load from same table cause its opposite from Ub unsigned char Uc = 255- Ua- Ub ; // Uc switch(sector) // calculate PWM values for each sector. { case 0: OCR0_temp = (Ua+Ub+0.5*Uc); OCR1A_temp = (Ub+0.5*Uc); OCR1B_temp = (0.5 * Uc); break; case 1: OCR0_temp = (Ua + 0.5*Uc); OCR1A_temp = (Ua+Ub+0.5*Uc); OCR1B_temp = (0.5 * Uc); break; case 2: OCR0_temp = (0.5*Uc); OCR1A_temp = (Ua+Ub+0.5 * Uc); OCR1B_temp = (Ub + 0.5* Uc); break; case 3: OCR0_temp = (0.5 * Uc); OCR1A_temp = (Ua+0.5*Uc); OCR1B_temp = (Ua+Ub+0.5*Uc); break; case 4: OCR0_temp = (Ub+0.5*Uc); OCR1A_temp = (0.5*Uc); OCR1B_temp = (Ua+Ub+0.5*Uc); break; case 5: OCR0_temp = (Ua+Ub+0.5*Uc); OCR1A_temp = (0.5 * Uc); OCR1B_temp = (Ua+0.5*Uc); break; default: break; } OCR0=OCR0_temp; //******************************************************************// OCR1A=OCR1A_temp; // Reload PWM registers at 'same time' (smallest time between) OCR1B=OCR1B_temp; //******************************************************************// update = 0 ; // Clear update variable } wdt_reset(); // WDT reset } ISR(ADC_vect) // Diakopi A/D Conversion complete { step_rate = (ADC/100) + 2 ; // 10-50 Hz , changes here affect V/F law and display too !! if(step_rate >10) { step_rate = 10 ; // Max Freq 50 Hz , optional BUT too much high step_rate may affect current waveform.Table only 180 points } wdt_reset(); }
3_phase_teliko.jpgdasdsad.jpg