как работает внешнее прерывание

Тема в разделе "Микроконтроллеры AVR", создана пользователем Yerabdi, 25 сен 2017.

  1. Yerabdi

    Yerabdi Гик

    Здравствуйте всем не могу понять как работает внешнее прерывание на атмеге328Р.
    Настроил прерывание по нарастанию импульса, написал код когда первый импульс появляется ставит высокое положение 6 выходе через 4,5 миллисекунд гасит, когда второй импульс приходит он не поднимает 6 выход а поднимает только на третим импульсе и так через импульс он должен поднимать выход.но у меня он то поднимает через импульс то поднимает на каждый импульс
     
  2. Tomasina

    Tomasina Сушитель лампочек Модератор

    где он?
     
  3. DIYMan

    DIYMan Guest

    Код в студию.
     
  4. Radius

    Radius Гик

    А где код?
     
  5. Yerabdi

    Yerabdi Гик

    Код (C++):
    #include <avr/io.h>
    #include <avr/interrupt.h>
    volatile unsigned int Danie_Rx,Temp=0,shet_adc;
    volatile unsigned char danie_tx;
    volatile unsigned int ACP/*razrezhenie MAP */,ob2=0,T,ob,time_ob=0;
    volatile float acp_2=0,oborot_2=0;
    volatile unsigned char zad_t=45,zad_t2=0,zad_t3=0,otsechka,top_cor=0,zad_vpris2=0,vprisk_top2=0,top_cor2=0,zad_vpris4=0;
    volatile unsigned char val,ad2=0,ad,val2,sel_chanel,pauza=0,pauza2=20,acp2,oborot,signal_xx,correct=0;
    volatile unsigned char zapusk=0,Period=0,off,off2,raz_xx,raz_uskor=0,signal_xx2=0,pol=0;
    volatile unsigned char ch=0,zn_acp,zn_temp,per_adc=0,zn_adc,per_ch=0;
    #define PIN_INT0 PD2
    //******timer0*****
    ISR (TIMER0_COMPA_vect)
    {
         T++;//shet zadershki impulsa
         ob++;//shet oborota
         per_adc++;
      if (T == zad_t3)
      {PORTD &=~(1<<PD6);}
        if (pauza2 == T && pol == 1)
        {pauza=1;
        }
         
    }
    //*********ADC***********
    ISR (ADC_vect)
    {    
         volatile unsigned char set_admux = ADMUX;
        set_admux &=~((1<<MUX3)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0));
       switch (ch)
       {
           case 1: set_admux |=(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(1<<MUX0);break;
           case 2 : set_admux |=(0<<MUX3)|(0<<MUX2)|(1<<MUX1)|(0<<MUX0);break;
           default:break;
       }
       ADMUX=set_admux;
        //*****zna******
        if (ch == 1)
        { ACP=ADCW;//znachenie MAP
        }
        //*****temperatura reduktora****
        if (ch == 2)
        {Temp=ADCW;//znachenie MAP
        }
        ADCSRA |=(1<<ADSC);

    }
    //***********external interrupt******************
    ISR (INT0_vect)
    {  
        zapusk++;  
        if(pauza ==0 && pol == 0)
    {
        PORTD |=(1<<PD6);  T=0;pol=1;}  
          if (pauza == 1 && pol == 1)
          {pauza=0;pol=0;     }
         
    }

    //******************


    int main(void)
    {   DDRC &=~(1<<PC1);//vhod MAP datchika
        DDRC &=~(1<<PC2);//vhod Reduktor datchika
        DDRD &=~(1<<PD7);//vhod otsechka na XX dvigatelya
        PORTD |=(1<<PD7);
        DDRD |=(1<<PD6);//vihod na force
        PORTD &=~(1<<PD6);
        DDRD |=(1<<PD4);//vihod na klapan reduktora
        PORTD &=~(1<<PD4);
        //********ACP************
        ADCSRA |=(1<<ADEN)
        //разрешение использование АЦП
        |(1<<ADIE)|(0<<ADPS2)|(0<<ADPS1)|(1<<ADPS0);//4 delim
        ADMUX |=(1<<REFS0);//|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(1<<MUX0);//подключили к 5В
        //arduino A1
        ADCSRA |=(1<<ADSC);
         //настраиваем вывод на вход
        DDRD &= ~(1<<PIN_INT0);
        //включаем подтягивающий резистор
        PORTD |= (1<<PIN_INT0);
        EICRA |=(1<<ISC01)|(1<<ISC00);//interrupt rising
        EIMSK |=(1<<INT0);//external interrupt Int0 pin2
        //********Timer0***********
        TCCR0A |= (1<<WGM01);  // Режим CTC (сброс по совпадению)
        TIMSK0 |=(1<<OCIE0A);  // Разрешить прерывание по совпадению
        OCR0A=24; //24 по достижении уходить в вектор прерывании, 24 равняется к 100 microsec
        TCNT0=0;
        TCCR0B |=(1<<CS01)|(1<<CS00);; // CLK/64

        asm("sei");
        while(1)
        {  per_ch = adc_perekl();
           vprisk_top2 = vprisk_top();//rashet zadershki vpriska topliva
           oborot = shet_ob(); //shet oborota
           otsechka = sw_but();//signal s otsechk
           top_cor = Cor();
        }    
       
    }
    //*****ADC_per*******
    int adc_perekl ()
    {
      if (per_adc > 0 && per_adc < 5)
        {ch=1;   }
      if (per_adc > 5 && per_adc < 10 )
         {ch=2;    }
      if (per_adc == 10)
         {per_adc=0; }
             
      zn_temp=Temp>>2;
      if (zn_temp < 70)
      {PORTD |=(1<<PD4); }
      else
       {PORTD &=~(1<<PD4);}        
    }
    //*******************
    //*****vprisk_top*****
    int vprisk_top ()
    {
       acp2=ACP*0.1;
       acp_2=acp2;
       oborot_2=oborot;
      zad_t2 = (acp_2/oborot_2)*10;
      if ((acp2 >= 60) && (otsechka==0))//uskorenie motora
        {  
          zad_vpris2=zad_t2;
          if (oborot > 25 && acp2 > 60)
          {raz_uskor=1; top_cor2=top_cor; }
        if ((oborot < 20) && (raz_uskor == 1)&&(acp2 < 60))//pri otsecke motora na 1200 oborotah
        {zad_vpris2=0; raz_uskor=0;   }
        }
         else
         {  zad_vpris2=0; top_cor2=0; }
       
        if ( otsechka == 1 )  //motor XX
        {zad_vpris2=0;top_cor2=0;
        }
        zad_t3 = (zad_t+zad_vpris2)+top_cor2;  
         return zad_t3;

    }

    //********oboroti**************
    int shet_ob ( )
    {  
       if (zapusk == 1 && off ==0)//start sheta oborota
         {
          ob=0;    off=1;off2=0;
         }
        if (zapusk == 2 && off2 ==0)//fiksasya oborota
        {pauza=0;
        time_ob=ob;//sohranim znachenie oborota
        zapusk=1;off2=1;
        off=0;
        ob=0;
        ob2=(30/(time_ob*0.0001))/60;//rashet oborota v sekundu
        }
         return ob2;
     
    }
     
  6. sslobodyan

    sslobodyan Гик

    Лично я при возникновении непоняток с работой любого блока контроллера всегда пишу отдельный код для отладки именно этого непонятного участка. А в вашем коде даже не хочется разбираться - очень много всего, не относящегося к задаваемому вопросу. А вдруг вы накосячили именно в том коде? Попробуйте все же написать отдельный скетч только для внешнего прерывания - наверняка все прояснится. А если нет - то давайте его в студию. В маленьком скетче вам помогут навести порядок :)
     
  7. ostrov

    ostrov Гуру

    Этот код правда делает только что вы написали?