добрый день всем! помогите решить проблему с реализацией 3 х шим сигналов а точнее пачка сигналов в определенный период времени Код (C++): //#include <TimerOne.h> #include <Wire.h> //#include <LiquidCrystal_I2C.h> //выход импульсов......................................... #define dimPinA 5 #define dimPinB 6 #define dimPinC 7 //вход детекторов ......................................... const int POT=0; // Аналоговый вход A0 для подключения потенциометр //.......................................................... volatile int ticA=0,ticB=0,ticC=0; bool f2=0, q=0,f1=0,f3=0,t=0,flagfasa=0;// f1-f3 флаги таймеров задержки вентелей, q разрешение кнопки, t флаг пуск осчета угла , с стоп отсчетов int Dimmer=130,UgolAC_BC=0,F=0; //T ТАЙМЕР УГЛА ФАЗ, TX УГОЛ ФАЗ , x таймер увеличения напруги, //unsigned long timing; //LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display byte a=0,b=0,c=0; int valpot = 0;byte d=0; void setup() { Serial.begin(9600); TCCR2A = 0b00000010; //таймер 2 от пинов отключен, режим СТС, предделитеь = 32 TCCR2B = 0b00000011; //итого частота 16М/32 = 500К OCR2A = 20; //регистр стравнения 20, частота = 500К/20 = 25К TIMSK2 = 0b00000010; //разрешаем прерывание по сравнению /*/ // Пины D3 и D11 - 31.4 кГц TCCR2B = 0b00000001; // x1 TCCR2A = 0b00000001; // phase correct // Пины D5 и D6 - 31.4 кГц TCCR0B = 0b00000001; // x1 TCCR0A = 0b00000001; // phase correct // Пины D9 и D10 - 31.4 кГц TCCR1A = 0b00000001; // 8bit TCCR1B = 0b00000001; // x1 phase correct /*/ // pinMode(dimPinA, OUTPUT); pinMode(dimPinB, OUTPUT); pinMode(dimPinC, OUTPUT); digitalWrite(dimPinA, 0); digitalWrite(dimPinB, 0); digitalWrite(dimPinC, 0); // pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt (2), detect_downBC, RISING ); attachInterrupt(digitalPinToInterrupt (3), detect_downAC, RISING); //Timer1.initialize(40); //Timer1.attachInterrupt(timer_interrupt); /*/ lcd.init(); // initialize the lcd lcd.backlight(); lcd.setCursor(0, 0); lcd.print("init"); lcd.setCursor(0, 0); lcd.print("speed="); lcd.setCursor(0, 1); lcd.print("Tx="); /*/ } void loop() { valpot = analogRead(POT); Dimmer=map(valpot,0,1023,17,255); // lcd.setCursor(7, 0); // lcd.print(Dimmer); Serial.println(Dimmer); } //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ-------------------------- //void timer_interrupt() { ISR(TIMER2_COMPA_vect) { // прерывания таймера срабатывают каждые 40 мкс if(flagfasa==1){F++;} if(F==83 ){f3=1;flagfasa=0;ticB=0; digitalWrite(dimPinB, 0); F=0; } // if(F==83 ){f3=1;flagfasa=0;ticB=0; OCR1A = 0; F=0; } //..............AC if(f1==1){ticA++;if (ticA== Dimmer){f1=0;digitalWrite(dimPinA, 1);}} //if(f1==1){ticA++;if (ticA== Dimmer){f1=0;OCR0A = 128;}} //...............BC if(f2==1){ticC++;if (ticC== Dimmer){digitalWrite(dimPinC, 1);f2=0;}} // if(f2==1){ticC++;if (ticC== Dimmer){OCR2A = 128;f2=0;}} //...............AB if(f3==1){ticB++; if (ticB== Dimmer){digitalWrite(dimPinB,1); f3=0;}} //if(f3==1){ticB++; if (ticB== Dimmer){OCR1A = 128; f3=0;}} // поиск угла фаз AC BC пересечений if(t==1){UgolAC_BC++;} } //контроль фаз AB АС ВС...................................................................... // AC пересечение фаз void detect_downAC() { if(c==0){ t=1;} // пуск стоп таймера угла фаз Tx f1=1;ticA=0; digitalWrite(dimPinA, 0); // OCR0A = 0; } // BC пересечение фаз void detect_downBC() { if(t==1){ c=1;t=0;} if( flagfasa==0 ){f2=1; flagfasa=1;ticC=0;} digitalWrite(dimPinC, 0); //OCR2A = 0; } // AB пересечение фаз void detect_downAB(){f1=1;ticB=0;} //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ-------------------------- В место digitalWrite(dimPinA, 0);digitalWrite(dimPinC, 0);digitalWrite(dimPinB, 0); нужен шим сигнал
вот пример кода но 3 шима у меня не получилось сделать 20кгц Код (C++): #include <avr/interrupt.h> byte F2KHz=0; //флаг 2КГц int d1000 = 0;//счетчик-делитель на 1000 byte F2Hz =0; //флаг 2Гц byte btn = 0; //флаг кнопки 1-нажата ISR(TIMER2_COMPA_vect) //прерывание таймера2 4000 раз в сек { F2KHz = 1 - F2KHz; //тот самый тоггль уровня, на флаге - меандр в 2КГц if (d1000++ == 1000) {d1000 = 0; F2Hz = 1 - F2Hz;} //деление на 1000 и меандр в 2Гц } void setup() { pinMode (9,OUTPUT); //выход 100КГц ... честно говоря говно на ослике pinMode (2,INPUT_PULLUP); //пин кнопки, делаем вид, что антидребезг - аппаратный ;) TCCR0B = 0; //останавливаю работу часов ардуино, миллис больше нет! TIMSK0 = 0; TCCR1A = 0b00000000; //первый таймер от пинов отключен, предделитель =1, режим СТС TCCR1B = 0b00001001; //курим даташит OCR1A=80; //регистр сравнения = 80, частота 100КГц, еще курим даташит TCCR2A = 0b00000010; //таймер 2 от пинов отключен, режим СТС, предделитеь = 32 TCCR2B = 0b00000011; //итого частота 16М/32 = 500К OCR2A = 125; //регистр стравнения 125, частота = 500К/125 = 4К TIMSK2 = 0b00000010; //разрешаем прерывание по сравнению } void loop() { btn = 1 - digitalRead(2); //читаем кнопку, активный GND if (F2KHz && (!btn || btn && F2Hz) ) //проверяем все флаги, курим булеву алгебру и КНФ TCCR1A = 0b01000000; //подключаем 100КГц к пин9 else TCCR1A = 0b00000000; //не подключаем ;) } взято с другого сайта автор wdrakula
примерно так Код (C++): /* плавный пуск переменки на Arduino. Симистор через оптопару */ //#include <TimerOne.h> #include <Wire.h> //#include <LiquidCrystal_I2C.h> //выход импульсов......................................... // #define dimPinA 4 // #define dimPinB 6 // #define dimPinC 7 //вход детекторов ......................................... const int POT=0; // Аналоговый вход A0 для подключения потенциометр //.......................................................... volatile int ticA=0,ticB=0,ticC=0; bool f2=0, q=0,f1=0,f3=0,t=0,flagfasa=0;// f1-f3 флаги таймеров задержки вентелей, q разрешение кнопки, t флаг пуск осчета угла , с стоп отсчетов int Dimmer=130,UgolAC_BC=0,F=0; //T ТАЙМЕР УГЛА ФАЗ, TX УГОЛ ФАЗ , x таймер увеличения напруги, //unsigned long timing; //LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display byte a=0,b=0,c=0; int valpot = 0;byte d=0; void setup() { Serial.begin(9600); TCCR2A = 0b00000010; //таймер 2 от пинов отключен, режим СТС, предделитеь = 32 TCCR2B = 0b00000011; //итого частота 16М/32 = 500К OCR2A = 20; //регистр стравнения 20, частота = 500К/20 = 25К TIMSK2 = 0b00000010; //разрешаем прерывание по сравнению // // Пины D3 и D11 - 31.4 кГц TCCR2B = 0b00000001; // x1 TCCR2A = 0b00000001; // phase correct // Пины D5 и D6 - 31.4 кГц TCCR0B = 0b00000001; // x1 TCCR0A = 0b00000001; // phase correct // Пины D9 и D10 - 31.4 кГц TCCR1A = 0b00000001; // 8bit TCCR1B = 0b00000001; // x1 phase correct // /*/ pinMode(dimPinA, OUTPUT); pinMode(dimPinB, OUTPUT); pinMode(dimPinC, OUTPUT); digitalWrite(dimPinA, 0); digitalWrite(dimPinB, 0); digitalWrite(dimPinC, 0); /*/ analogWrite(10, 0); analogWrite(9, 0); analogWrite(11, 0); pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt (2), detect_downBC, RISING ); attachInterrupt(digitalPinToInterrupt (3), detect_downAC, RISING); //Timer1.initialize(40); //Timer1.attachInterrupt(timer_interrupt); /*/ lcd.init(); // initialize the lcd lcd.backlight(); lcd.setCursor(0, 0); lcd.print("init"); lcd.setCursor(0, 0); lcd.print("speed="); lcd.setCursor(0, 1); lcd.print("Tx="); /*/ } void loop() { valpot = analogRead(POT); Dimmer=map(valpot,0,1023,17,255); // lcd.setCursor(7, 0); // lcd.print(Dimmer); Serial.println(Dimmer); analogWrite(5, 32); } //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ-------------------------- //void timer_interrupt() { ISR(TIMER2_COMPA_vect) { // прерывания таймера срабатывают каждые 40 мкс if(flagfasa==1){F++;} // if(F==83 ){f3=1;flagfasa=0;ticB=0; digitalWrite(dimPinB, 0); F=0; } if(F==83 ){f3=1;flagfasa=0;ticB=0; analogWrite(10, 0); F=0; } //..............AC // if(f1==1){ticA++;if (ticA== Dimmer){f1=0;digitalWrite(dimPinA, 1);}} if(f1==1){ticA++;if (ticA== Dimmer){f1=0;analogWrite(9, 32);}} //...............BC // if(f2==1){ticC++;if (ticC== Dimmer){digitalWrite(dimPinC, 1);f2=0;}} if(f2==1){ticC++;if (ticC== Dimmer){analogWrite(11, 32);f2=0;}} //...............AB // if(f3==1){ticB++; if (ticB== Dimmer){digitalWrite(dimPinB,1); f3=0;}} if(f3==1){ticB++; if (ticB== Dimmer){analogWrite(10, 32); f3=0;}} // поиск угла фаз AC BC пересечений if(t==1){UgolAC_BC++;} } //контроль фаз AB АС ВС...................................................................... // AC пересечение фаз void detect_downAC() { if(c==0){ t=1;} // пуск стоп таймера угла фаз Tx f1=1;ticA=0; // digitalWrite(dimPinA, 0); analogWrite(9, 0); } // BC пересечение фаз void detect_downBC() { if(t==1){ c=1;t=0;} if( flagfasa==0 ){f2=1; flagfasa=1;ticC=0;} // digitalWrite(dimPinC, 0); analogWrite(11,0); } // AB пересечение фаз void detect_downAB(){f1=1;ticB=0;} //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------
Наугад делается всё? Надо открыть даташит и посмотреть, у какого таймера 3 блока сравнения. На нём и сделать. Для этого великолепно подходят аттини 0-ой и 1-серии, а также MSP430 - у этих МК таймеры изумительные. У старого атмеловского хлама таких возможностей и рядом нет.
да получилось на угад в протеусе неодекватно работает поэтому так , переделал уже по дата шиту в желе проверил
Код (C++): //#include <TimerOne.h> #include <Wire.h> #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) //#include <LiquidCrystal_I2C.h> //выход импульсов......................................... // #define dimPinA 4 // #define dimPinB 6 // #define dimPinC 7 //вход детекторов ......................................... const int POT=0; // Аналоговый вход A0 для подключения потенциометр //.......................................................... volatile int ticA=0,ticB=0,ticC=0; bool f2=0, q=0,f1=0,f3=0,t=0,flagfasa=0;// f1-f3 флаги таймеров задержки вентелей, q разрешение кнопки, t флаг пуск осчета угла , с стоп отсчетов int Dimmer=230,UgolAC_BC=0,F=0; //T ТАЙМЕР УГЛА ФАЗ, TX УГОЛ ФАЗ , x таймер увеличения напруги, //unsigned long timing; //LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display byte a=0,b=0,c=0; int valpot = 0,count=0; byte d=0; void setup() { Serial.begin(9600); // TCCR2A = 0b00000010; //таймер 2 от пинов отключен, режим СТС, предделитеь = 32 TCCR2B = 0b00000011; //итого частота 16М/32 = 500К OCR2A = 20; //регистр стравнения 20, частота = 500К/20 = 25К TIMSK2 = 0b00000010; //разрешаем прерывание по сравнению // /*/ Пины D3 и D11 - 4 кГц TCCR2B = 0b00000010; // x8 TCCR2A = 0b00000001; // phase correct /*/ // Пины D5 и D6 - 4 кГц TCCR0B = 0b00000010; // x8 TCCR0A = 0b00000001; // phase correct // Пины D9 и D10 - 4 кГц TCCR1A = 0b00000001; // 8bit TCCR1B = 0b00000010; // x8 phase correct // /*/ pinMode(dimPinA, OUTPUT); pinMode(dimPinB, OUTPUT); pinMode(dimPinC, OUTPUT); digitalWrite(dimPinA, 0); digitalWrite(dimPinB, 0); digitalWrite(dimPinC, 0); /*/ /*/ pinMode(9, OUTPUT); pinMode(10, OUTPUT); pinMode(11, OUTPUT); sbi(TCCR1A, COM1B1);OCR1B = 0; // устанавливаем уровень ШИМ 10 sbi(TCCR1A, COM1A1);OCR1A = 0; // устанавливаем уровень ШИМ 9 sbi(TCCR2A, COM2A1);OCR2A = 0;//11 /*/ analogWrite(5, 0); analogWrite(6, 0); analogWrite(10, 0); /*/ pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); /*/ attachInterrupt(digitalPinToInterrupt (2), detect_downBC, RISING ); attachInterrupt(digitalPinToInterrupt (3), detect_downAC, RISING); //Timer1.initialize(40); //Timer1.attachInterrupt(timer_interrupt); /*/ lcd.init(); // initialize the lcd lcd.backlight(); lcd.setCursor(0, 0); lcd.print("init"); lcd.setCursor(0, 0); lcd.print("speed="); lcd.setCursor(0, 1); lcd.print("Tx="); /*/ } void loop() { /*/ valpot = analogRead(POT); Dimmer=map(valpot,0,1023,17,255); /*/ // lcd.setCursor(7, 0); // lcd.print(Dimmer); Serial.println(Dimmer); if(Dimmer!=0){ if(count==200){Dimmer--;count=0;} } } //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ-------------------------- //void timer_interrupt() { ISR(TIMER2_COMPA_vect) { // прерывания таймера срабатывают каждые 40 мкс if(Dimmer!=0 and count!=200){count++;} if(flagfasa==1){F++;} // if(F==83 ){f3=1;flagfasa=0;ticB=0; digitalWrite(dimPinB, 0); F=0; } if(F==83 ){f3=1;flagfasa=0;ticB=0; analogWrite(6, 0); F=0; } //if(F==83 ){f3=1;flagfasa=0;ticB=0; sbi(TCCR1A, COM1B1);OCR1B = 0; F=0; }//10 //sbi(TCCR1A, COM1B1);OCR1B = 0; // устанавливаем уровень ШИМ 10 //sbi(TCCR1A, COM1A1);OCR1A = 0; // устанавливаем уровень ШИМ 9 //sbi(TCCR2A, COM2A1);OCR2A = 0;//11 //..............AC // if(f1==1){ticA++;if (ticA== Dimmer){f1=0;digitalWrite(dimPinA, 1);}} if(f1==1){ticA++;if (ticA== Dimmer){f1=0;analogWrite(5, 200);}} //if(f1==1){ticA++;if (ticA== Dimmer){f1=0;sbi(TCCR1A, COM1A1);OCR1A = 100; }}//9 //...............BC // if(f2==1){ticC++;if (ticC== Dimmer){digitalWrite(dimPinC, 1);f2=0;}} if(f2==1){ticC++;if (ticC== Dimmer){analogWrite(9, 200);f2=0;}} // if(f2==1){ticC++;if (ticC== Dimmer){sbi(TCCR2A, COM2A1);OCR2A = 100;f2=0;}}//11 //...............AB // if(f3==1){ticB++; if (ticB== Dimmer){digitalWrite(dimPinB,1); f3=0;}} if(f3==1){ticB++; if (ticB== Dimmer){analogWrite(6, 200); f3=0;}} // if(f3==1){ticB++; if (ticB== Dimmer){sbi(TCCR1A, COM1B1);OCR1B = 100; f3=0;}}//10 // поиск угла фаз AC BC пересечений if(t==1){UgolAC_BC++;} } //контроль фаз AB АС ВС...................................................................... // AC пересечение фаз void detect_downAC() { if(c==0){ t=1;} // пуск стоп таймера угла фаз Tx f1=1;ticA=0; // digitalWrite(dimPinA, 0); analogWrite(5, 0); } // BC пересечение фаз void detect_downBC() { if(t==1){ c=1;t=0;} if( flagfasa==0 ){f2=1; flagfasa=1;ticC=0;} // digitalWrite(dimPinC, 0); analogWrite(9,0); } // AB пересечение фаз void detect_downAB(){f1=1;ticB=0;} //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------