หากเรามองจาก ท้องฟ้า เราจะเห็น สิ่งที่เคลื่อนไหว ภายใต้ ของความคิดเรา ถ้าเรามองขึ้นไปจากใจเรา เราจะเห็น ทุกชีวิต กำลังดิ้นรน เพื่อ แสวงหา อาหาร เพื่อ หล่อเลี้ยง ชีวิตของตนเอง และ สิ่งที่ตนรัก และเป็นที่รัก ของตนเอง และแล้ว ทุกชีวิต ก็ พบว่า ความกระหายใคร่ ได้ ใคร่มี ใคร่เป็น หรือ ความทะยานอยาก นี่เอง ที่เป็นสาเหตุ ให้มนุษย์ ต้องเดินทางอยู่ ตลอดชีวิต ลองหยุดเดินทางด้วยยานพาหนะ แล้วหันมาเดินทาง ด้วยจิตวิญญาณ แล้วการ เดินทางไกล จะใกล้เข้าทุกขณะจิต หายใจเข้า ตามรู้ หายใจออก ตามรู้
วันพุธที่ 2 พฤศจิกายน พ.ศ. 2559
การควบคุมมอเตอร์สามเฟสด้วย half bridge#ifndef __PGMSPACE_H_ #define __PGMSPACE_H_ 1 #include #define PROGMEM #define PGM_P const char * #define PSTR(str) (str) typedef void prog_void; typedef char prog_char; typedef unsigned char prog_uchar; typedef int8_t prog_int8_t; typedef uint8_t prog_uint8_t; typedef int16_t prog_int16_t; typedef uint16_t prog_uint16_t; typedef int32_t prog_int32_t; typedef uint32_t prog_uint32_t; #define strcpy_P(dest, src) strcpy((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src)) #define strcmp_P(a, b) strcmp((a), (b)) #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_float_near(addr) pgm_read_float(addr) #define pgm_read_byte_far(addr) pgm_read_byte(addr) #define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_float_far(addr) pgm_read_float(addr) #endif // 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)
ไม่มีความคิดเห็น:
แสดงความคิดเห็น