Здравствуйте всем не могу понять как работает внешнее прерывание на атмеге328Р. Настроил прерывание по нарастанию импульса, написал код когда первый импульс появляется ставит высокое положение 6 выходе через 4,5 миллисекунд гасит, когда второй импульс приходит он не поднимает 6 выход а поднимает только на третим импульсе и так через импульс он должен поднимать выход.но у меня он то поднимает через импульс то поднимает на каждый импульс
Код (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; }
Лично я при возникновении непоняток с работой любого блока контроллера всегда пишу отдельный код для отладки именно этого непонятного участка. А в вашем коде даже не хочется разбираться - очень много всего, не относящегося к задаваемому вопросу. А вдруг вы накосячили именно в том коде? Попробуйте все же написать отдельный скетч только для внешнего прерывания - наверняка все прояснится. А если нет - то давайте его в студию. В маленьком скетче вам помогут навести порядок