หากเรามองจาก ท้องฟ้า เราจะเห็น สิ่งที่เคลื่อนไหว ภายใต้ ของความคิดเรา ถ้าเรามองขึ้นไปจากใจเรา เราจะเห็น ทุกชีวิต กำลังดิ้นรน เพื่อ แสวงหา อาหาร เพื่อ หล่อเลี้ยง ชีวิตของตนเอง และ สิ่งที่ตนรัก และเป็นที่รัก ของตนเอง และแล้ว ทุกชีวิต ก็ พบว่า ความกระหายใคร่ ได้ ใคร่มี ใคร่เป็น หรือ ความทะยานอยาก นี่เอง ที่เป็นสาเหตุ ให้มนุษย์ ต้องเดินทางอยู่ ตลอดชีวิต ลองหยุดเดินทางด้วยยานพาหนะ แล้วหันมาเดินทาง ด้วยจิตวิญญาณ แล้วการ เดินทางไกล จะใกล้เข้าทุกขณะจิต หายใจเข้า ตามรู้ หายใจออก ตามรู้
วันจันทร์ที่ 7 พฤศจิกายน พ.ศ. 2559
แนะแนวทางการสร้างอินเวอร์เตอร์/* * * DDS Sine Generator mit ATMEGS 328 * Timer2 generates the 31250 KHz Clock Interrupt * Use Timer2 Interrupt to change duty cycle for the output PWM signals * D. Tolken * 120 degress out of phase signals for 3 phase BLDC motor controller * CPUT, South Africa a Huge thumbs up and thanks must be given to Martin Nawrath for the developement of the original code to generate a sine wave using PWM and a LPF. Link: http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/ */ #include "avr/pgmspace.h" //Store data in flash (program) memory instead of SRAM // Look Up table of a single sine period divied up into 256 values. Refer to PWM to sine.xls on how the values was calculated PROGMEM prog_uchar sine256[] = { 127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240, 242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223, 221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78, 76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31, 33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124 }; #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) //define a bit to have the properties of a clear bit operator #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))//define a bit to have the properties of a set bit operator int PWM1= 11;// PWM1 output, phase 1 int PWM2 = 3; //[WM2 ouput, phase 2 int PWM3 = 10; //PWM3 output, phase 3 int offset_1 = 85; //offset 1 is 120 degrees out of phase with previous phase, Refer to PWM to sine.xls int offset_2 = 170; //offset 2 is 120 degrees out of phase with offset 1. Refer to PWM to sine.xls int program_exec_time = 6; //monitor how quickly the interrupt trigger int ISR_exec_time = 7; //monitor how long the interrupt takes double dfreq; const double refclk=31376.6; // measured output frequency // variables used inside interrupt service declared as voilatile volatile byte current_count; // Keep track of where the current count is in sine 256 array volatile byte ms4_delay; //variable used to generate a 4ms delay volatile byte c4ms; // after every 4ms this variable is incremented, its used to create a delay of 1 second volatile unsigned long phase_accumulator; // pahse accumulator volatile unsigned long tword_m; // dds tuning word m, refer to DDS_calculator (from Martin Nawrath) for explination. void setup() { pinMode(PWM1, OUTPUT); //sets the digital pin as output pinMode(PWM2, OUTPUT); //sets the digital pin as output pinMode(PWM3, OUTPUT); //sets the digital pin as output pinMode(program_exec_time, OUTPUT); //sets the digital pin as output pinMode(9, OUTPUT); //sets the digital pin as output sbi(PORTD,program_exec_time); //Sets the pin Setup_timer1(); Setup_timer2(); //Disable Timer 1 interrupt to avoid any timing delays cbi (TIMSK0,TOIE0); //disable Timer0 !!! delay() is now not available sbi (TIMSK2,TOIE2); //enable Timer2 Interrupt dfreq=1000.0; //initial output frequency = 1000.o Hz tword_m=pow(2,32)*dfreq/refclk; //calulate DDS new tuning word } void loop() { while(1) { sbi(PORTD,program_exec_time); //Sets the pin if (c4ms > 250) // c4ms = 4ms, thus 4ms *250 = 1 second delay { c4ms=0; //Reset c4ms dfreq=analogRead(0); //Read voltage on analog 1 to see desired output frequency, 0V = 0Hz, 5V = 1.023kHz cbi (TIMSK2,TOIE2); //Disable Timer2 Interrupt tword_m=pow(2,32)*dfreq/refclk; //Calulate DDS new tuning word sbi (TIMSK2,TOIE2); //Enable Timer2 Interrupt } } } //Timer 1 setup //Set prscaler to 1, PWM mode to phase correct PWM, 16000000/510 = 31372.55 Hz clock void Setup_timer1(void) { // Timer1 Clock Prescaler to : 1 sbi (TCCR1B, CS10); cbi (TCCR1B, CS11); cbi (TCCR1B, CS12); // Timer1 PWM Mode set to Phase Correct PWM cbi (TCCR1A, COM1A0); sbi (TCCR1A, COM1A1); cbi (TCCR1A, COM1B0); sbi (TCCR1A, COM1B1); // Mode 1 / Phase Correct PWM sbi (TCCR1A, WGM10); cbi (TCCR1A, WGM11); cbi (TCCR1B, WGM12); cbi (TCCR1B, WGM13); } //Timer 1 setup //Set prscaler to 1, PWM mode to phase correct PWM, 16000000/510 = 31372.55 Hz clock void Setup_timer2() { // Timer2 Clock Prescaler to : 1 sbi (TCCR2B, CS20); cbi (TCCR2B, CS21); cbi (TCCR2B, CS22); // Timer2 PWM Mode set to Phase Correct PWM cbi (TCCR2A, COM2A0); // clear Compare Match sbi (TCCR2A, COM2A1); cbi (TCCR2A, COM2B0); sbi (TCCR2A, COM2B1); // Mode 1 / Phase Correct PWM sbi (TCCR2A, WGM20); cbi (TCCR2A, WGM21); cbi (TCCR2B, WGM22); } //Timer2 Interrupt Service at 31372,550 KHz = 32uSec //This is the timebase REFCLOCK for the DDS generator //FOUT = (M (REFCLK)) / (2 exp 32) //Runtime : 8 microseconds ISR(TIMER2_OVF_vect) { cbi(PORTD,program_exec_time); //Clear the pin sbi(PORTD,ISR_exec_time); // Sets the pin phase_accumulator=phase_accumulator+tword_m; //Adds tuning M word to previoud phase accumulator. refer to DDS_calculator (from Martin Nawrath) for explination. current_count=phase_accumulator >> 24; // use upper 8 bits of phase_accumulator as frequency information OCR2A=pgm_read_byte_near(sine256 + current_count); // read value fron ROM sine table and send to PWM OCR2B=pgm_read_byte_near(sine256 + (uint8_t)(current_count + offset_1)); // read value fron ROM sine table and send to PWM, 120 Degree out of phase of PWM1 OCR1A = pgm_read_byte_near(sine256 + (uint8_t)(current_count + offset_2));// read value fron ROM sine table and send to PWM, 120 Degree out of phase of PWM2 OCR1B = pgm_read_byte_near(sine256 + (uint8_t)(current_count + offset_2));// read value fron ROM sine table and send to PWM, 120 Degree out of phase of PWM2 //increment variable ms4_delay every 4mS/125 = milliseconds 32uS if(ms4_delay++ == 125) { c4ms++; ms4_delay=0; //reset count } cbi(PORTD,ISR_exec_time); //Clear the pin }
สมัครสมาชิก:
ส่งความคิดเห็น (Atom)
ไม่มีความคิดเห็น:
แสดงความคิดเห็น