Ардуино pvm и таймер

Тема в разделе "Arduino & Shields", создана пользователем serega4789, 7 май 2020.

  1. serega4789

    serega4789 Нерд

    добрый день всем! помогите решить проблему с реализацией 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); нужен шим сигнал
     
  2. serega4789

    serega4789 Нерд

    вот пример кода но 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
     
  3. serega4789

    serega4789 Нерд

    примерно так
    Код (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;}
    //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------
     
  4. parovoZZ

    parovoZZ Гуру

    Наугад делается всё?
    Надо открыть даташит и посмотреть, у какого таймера 3 блока сравнения. На нём и сделать. Для этого великолепно подходят аттини 0-ой и 1-серии, а также MSP430 - у этих МК таймеры изумительные. У старого атмеловского хлама таких возможностей и рядом нет.
     
  5. serega4789

    serega4789 Нерд

    да получилось на угад в протеусе неодекватно работает поэтому так , переделал уже по дата шиту в желе проверил
     
  6. serega4789

    serega4789 Нерд

    Код (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;}
    //----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------
     
  7. serega4789

    serega4789 Нерд

    у меня нет возможности покупать другие чипы работаю с мегой esp и nano начинал с pic
     
  8. serega4789

    serega4789 Нерд

    эти таймеры должны работать независимо друг от друга