Furyfax Skrevet 16. april 2007 Del Skrevet 16. april 2007 (endret) Innlegget er på engelsk, jeg gidder ikke å skrive om, copy og paste fra et annet forum jeg skrev på. Hello again. I have another obstackle i want to pass.My code is built in this matter: int index =0; //Counter for the different video modes /* PORT C */ PORTC = 0xFF; /*PC0-7 = Input */ DDRC = 0x00; // check for button press to change state if (PINC != 0xFF){ Switch(index)[ case 0: *send different commands on the I2C. index++; break; case 1: *send different commands on the I2C. index++; break; case 2: *send different commands on the I2C. index=0; break; I have 4 push buttons connectes as you see in the illustration which is attached. When i press button 1, I want the code to send commands when the button is pressed. I'm afraid the button will oscillate, which gets the index to suddenly "jump" to the value 3 instead of just jumping one step at a time. My first question is if my code is correct, when I just want this code to work for button 1 like it is connected in the illustration. My second question is, I wish to avoid the button to oscillate. Then my idea is to use interupts. I've tried reading the datasheet how this works. But I'm not quite sure. What do I have to include,how do I enable interupt, and how do I get interupt to work. Hope someone can help me with this problem. -Paul- Kort sagt så er jeg redd for "prelling" på knappen, slik at dette kan få index min til å hoppe flere hakk enn ett hakk om gangen. Dette vil jeg unngå ved å bruke interrupt. Men hvordan gjøres dette, er ny innenfor AVR familien. Jeg vet jeg skal inkludere interrupt.h filen, men det er omtrent det jeg er sikker på. Endret 16. april 2007 av Furyfax Lenke til kommentar
Dr_VingTor Skrevet 16. april 2007 Del Skrevet 16. april 2007 hmm... står atmega64 på tegninga, men det ser ikke ut til å være en atmega64 synes jeg... atmega64 har nemlig 64 pinner, kretsen i skjema har bare 44 ser det ut til... Videre har du ikke koblet knappene til porter som støtter eksternt interrupt, så interrupt fra knappene vil ikke være mulig. Det du kan gjøre er å bruke en timer og noen variabler som sørger for at det må gå en liten tid mellom hvert knappetrykk. Å bruke eksternt interrupt trenger ikke være nok i seg selv, det kan godt hende du vil trenge en slik timer likevel. kommer litt an på hvor raks interruptrutinen blir. når det gjelder kode (avr-gcc) for interrupt: ... #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> ... INTERRUPT(SIG_OVERFLOW0) //counter0/timer0 { //C-kode } SIGNAL(SIG_UART_RECV) { //C-kode } SIG_UART_RECV og SIG_OVERFLOW0 er bare eksempler (fra kode jeg har brukt..), se .h filene for å finne det du vl ha. To alternativer, den ene eksekverer med global interrupt på, den andre med globalt interrupt av i selve avbruddrutinen. Kjekt hvis du skal ha interrupt av høyere prioritet o.l. Lenke til kommentar
jogamaster Skrevet 16. april 2007 Del Skrevet 16. april 2007 hmm... står atmega64 på tegninga, men det ser ikke ut til å være en atmega64 synes jeg... atmega64 har nemlig 64 pinner, kretsen i skjema har bare 44 ser det ut til... Videre har du ikke koblet knappene til porter som støtter eksternt interrupt, så interrupt fra knappene vil ikke være mulig. Det du kan gjøre er å bruke en timer og noen variabler som sørger for at det må gå en liten tid mellom hvert knappetrykk. Å bruke eksternt interrupt trenger ikke være nok i seg selv, det kan godt hende du vil trenge en slik timer likevel. kommer litt an på hvor raks interruptrutinen blir. når det gjelder kode (avr-gcc) for interrupt: ... #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> ... INTERRUPT(SIG_OVERFLOW0) //counter0/timer0 { //C-kode } SIGNAL(SIG_UART_RECV) { //C-kode } SIG_UART_RECV og SIG_OVERFLOW0 er bare eksempler (fra kode jeg har brukt..), se .h filene for å finne det du vl ha. To alternativer, den ene eksekverer med global interrupt på, den andre med globalt interrupt av i selve avbruddrutinen. Kjekt hvis du skal ha interrupt av høyere prioritet o.l. 8394987[/snapback] SIGNAL og INTERRUPT er utdatert, i nye versoner skal det benyttes kun ISR(INTERRUPT_VECTOR), for å finne navnet på interrupt vektoren kan man sjekke ioXXX.h fila som ligger under include/avr . Skal man ha på global interrupt kan man bare enable med en gang man går inn i rutinen, Ellers så har en del AVR kretser interrupt på alle pinner eks ATMEGA44/88/168 serien. Men man benytter vel ikke pinn interrupt for her det er vel timer interrupt slik som Dr_VingTor sier som er den riktige løsningen. Sett opp en timer med interrupt ca 50Hz, så sier man at det treng to timerinterrupt med knappen nede for at det skal reagere (selvsagt må man eksprimentere litt her for å få riktig timing å slikt). Man kan også sette inn et delay etter knappen er trykket ned slik at det går en liten stund før nytt trykk godtas (gjøre også med samme timer interrupt). Lenke til kommentar
Furyfax Skrevet 16. april 2007 Forfatter Del Skrevet 16. april 2007 (endret) (/&%¤¤"()/&==)/&(&¤## *sukk* Takk for svar. Har kanskje gått på en liten blunder. Meininga var å bruke Atmega64. Men jeg har copy paste fra ett annet prosjekt, dette har ført til at eg kopierte en Atmega164. Dette har ikke altfor mye å si. Dette er forvørig en liten del av et hovedprosjekt, kravet var at vi skulle bruke en mikrokontroller fra AVR familien, så om jeg bruker 164 eller 64 har lite å si. Siden jeg allerede har lagd kortutlegg og sånn så er jeg pent nødt til å bruke en Atmega164. Kall meg gjerne dum.. Men jeg skjønner fremdeles ikke nøyaktiv hvordan jeg skal dette helt til. Har leta etter kodeeksempel, men det meste jeg finner er assembly kode. I databladet til Atmega164 står det følgende under interrupt: The External Interrupts are triggered by the INT2:0 pin or any of the PCINT31:0 pins. Mine knapper er jo koblet til PCINT18-21. Skal det ikke da være mulig? Endret 16. april 2007 av Furyfax Lenke til kommentar
Furyfax Skrevet 16. april 2007 Forfatter Del Skrevet 16. april 2007 Kom på en annen ting. Jeg kan jo fjerne denne prelling "mekanisk" også ved å ta en kondis og en motstand i paralell på knappen. Dette vil jo få prellingen til å lade opp kondisen, og deretter gå høy.. Eller? Lenke til kommentar
Dr_VingTor Skrevet 16. april 2007 Del Skrevet 16. april 2007 hvis du bruker en mega164 så blir det en annen sak ja. den har visst interrupt på alle pinnene, så da er det bare å sette den opp rett. kap 11.i databladet tar for seg dette... kond og motstander kan funke det, men vil vell trenge en motstand i serie også fra kond inn på io pinne. jeg ville brukt timer (billigere, færre komponenter), det virker garantert. Lenke til kommentar
Furyfax Skrevet 16. april 2007 Forfatter Del Skrevet 16. april 2007 Tusen takk for all hjelp Dr_VingTor! Setter pris på det! Blir litt lesing på meg, kommer tilbake om/når jeg setter meg fast igjen! Lenke til kommentar
Furyfax Skrevet 16. april 2007 Forfatter Del Skrevet 16. april 2007 (endret) Jeg har følgende kode nå: SIGNAL (SIG_INT0){ int button=1; } int main(){ /* PORT C */ DDRC = 0b00111111; // 2 first are outputs, next 6 are inputs PORTC = 0xFF; // Set Pin (PC02) as the pin to use PCMSK |= (1<<PINC2); // interrupt on INT0 pin falling edge (sensor triggered) MCUCR = (1<<ISC01) | (1<<ISC00); // turn on interrupts! GIMSK |= (1<<INT0); while(1){ // check for button press to change state if (button | startup){ switch(index){ case0: *send different I2C commands* startup=0; break; case1: *send different I2C commands* startup=0; break; }//end switch button=0; }//end if }//end while Jeg får warning at signal.h som jeg inkluderer er obselete. Er dett kilden til errorene og warningene? Her er warnings og errors: C:/WinAVR/avr/include/avr/signal.h:36:2: warning: #warning "This header file is obsolete. Use <avr/interrupt.h>." ../hovedoppgave.c: In function `main': ../hovedoppgave.c:71: error: `PCMSK' undeclared (first use in this function) ../hovedoppgave.c:71: error: (Each undeclared identifier is reported only once ../hovedoppgave.c:71: error: for each function it appears in.) ../hovedoppgave.c:77: error: `GIMSK' undeclared (first use in this function) ../hovedoppgave.c:81: warning: `SIG_INT0' appears to be a misspelled signal handler ../hovedoppgave.c:81: warning: static declaration of 'SIG_INT0' follows non-static declaration ../hovedoppgave.c:81: warning: previous declaration of 'SIG_INT0' was here Endret 16. april 2007 av Furyfax Lenke til kommentar
jogamaster Skrevet 16. april 2007 Del Skrevet 16. april 2007 Ja som jeg sa er INTERRUPT og SIGNAL utdatert. ISR(INT_vector) benyttes!! som da ligger i avr/interrupt.h, ellers når det gjelder de andre feilene. Har du inkludert avr/io.h samt inkludert prosessor type i make fila?? Lenke til kommentar
Furyfax Skrevet 16. april 2007 Forfatter Del Skrevet 16. april 2007 (endret) Fant iallfall ut litt av feilene. Jeg henviste til registre som ikke finnes i Atmega164. Tror jeg nå har fikset dette. Legger ved et innlegg jeg har på et annet forum, for å se om det er noe input her ifra. (Det er på engelsk igjen): Not sure which _vect to use, I've now used the "INT0_vect ", but I'm not sure wether I should use "PCINT0_vect". Any input on that ? I've now written the following: #include <avr/interrupt.h> int button=0; ISR(INT0_vect) //ISR(PCINT0_vect) { button=1; }//END INT0_vect int main(){ /* PORT C */ DDRC = 0b00111111; PORTC = 0xFF; /*PC0-7 = Input */ // Set Pin (PCint18) as the pin to use for this example PCMSK2 |= (1<<PCINT18); // interrupt on INT0 pin falling edge (sensor triggered) EICRA = (1<<ISC01) | (1<<ISC00); // turn on interrupts! EIMSK |= (1<<INT0); while(1){ // check for button press to change state if (button | startup){ bla bla bla} I know only get errors and no warnings, they are: ../hovedoppgave.c:76: error: `PCMSK2' undeclared (first use in this function) ../hovedoppgave.c:76: error: (Each undeclared identifier is reported only once ../hovedoppgave.c:76: error: for each function it appears in.) ../hovedoppgave.c:76: error: `PCINT18' undeclared (first use in this function) Jeg har fått litt informasjon her ifra. Nongnu EDIT: Her er nøyaktig det som står foran main i mitt program: /* OS headers */ #include <avr/interrupt.h> #include <avr/sleep.h> #include <avr/io.h> /* General purpose include files */ /* App required include files. */ #include "hovedoppgave.h" /* Static functions and variables */ int button=0; /* define CPU frequency in Mhz here if not defined in Makefile */ #ifndef F_CPU #define F_CPU 20000000UL #endif #define VSP 0xB0 /* I2C clock in Hz */ #define SCL_CLOCK 400000L ISR(INT0_vect) //ISR(PCINT0_vect) { button=1; }//END INT0_vect /************************************************************************* Initialization of the I2C bus interface. Need to be called only once *************************************************************************/ void i2c_init(void) { /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ TWSR = 0; /* no prescaler */ TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */ }/* i2c_init */ Endret 16. april 2007 av Furyfax Lenke til kommentar
jogamaster Skrevet 16. april 2007 Del Skrevet 16. april 2007 Ok kan jo spørre deg en gang til da om du har includert avr/io.h samt spesifiser prosessortype i makefile/kompilator direktiv??? Lenke til kommentar
Furyfax Skrevet 16. april 2007 Forfatter Del Skrevet 16. april 2007 Jepp det kan du. Editerte forrige, kom på at jeg glemte det, sorry. Lenke til kommentar
jogamaster Skrevet 16. april 2007 Del Skrevet 16. april 2007 Men det er vel en annen fil du må inkludere det i hvær fil! (kommer jo litt på hvordan filene linkes å slikt men mest vanlig må du ha med det med i hvær fil). Lenke til kommentar
Furyfax Skrevet 16. april 2007 Forfatter Del Skrevet 16. april 2007 (endret) Fant ut av feilen. Hadde definert chippen som Atmega164, og den fantes visst ikke. Den måtte defineres som Atmega164P! Gjorde dette og alt ordna seg! Fy faen for et slit og drit. Nå gjenstår det bare å teste å se at det ikke fungerer slikt jeg trodde, hehe. Endret 16. april 2007 av Furyfax Lenke til kommentar
Furyfax Skrevet 17. april 2007 Forfatter Del Skrevet 17. april 2007 Etter å ha lest litt rundt er jeg ganske usikker på om koden fin funker slik jeg ønsker. Jeg har en pushbutton koblet til PIN21(PCINT18), når denne knappen blir trykket vil jeg at den skal enable en interrupt rutine som setter et flagg høyt. Her er koden: #include interrupt.h int button =0; ISR(PCINT2_vect) { button=1; }//END PCINT2_vect int main(){ /* PORT C */ DDRC = 0b00111111; // Setting the first two to outputs (SCL & SDA) The rest are set as inputs. PORTC = 0xFF; PCMSK2 |= (1<<PCINT18); EICRA = (1<<ISC01) | (1<<ISC00); // Kan noen forklare meg litt hva som skjer her? if(button){ /*bla bla*/ }//end if }//end main Jeg er usikker på hva EICRA = (1<<ISC01) | (1<<ISC00); gjør, noen som har noe input på det ? Lenke til kommentar
Firesky Skrevet 17. april 2007 Del Skrevet 17. april 2007 Jeg er usikker på hva EICRA = (1<<ISC01) | (1<<ISC00); gjør, noen som har noe input på det ? 8404947[/snapback] EICRA er et register i chippen, ISC01 og ISC00 er 2 forsjellige bit i dette registeret. Når man skriver slik som over så setter man disse bittene høy, og overser de andre bit'ene i registeret bytter du ut ett'tallet med null istedet vil du sette dem lav Lenke til kommentar
Furyfax Skrevet 17. april 2007 Forfatter Del Skrevet 17. april 2007 (endret) Ja jeg vet hvordan de sette høy eller lav. Men hvilke utfører dette registret, hav skjer i de forksjellige tilstandene? Endret 17. april 2007 av Furyfax Lenke til kommentar
Firesky Skrevet 17. april 2007 Del Skrevet 17. april 2007 Beklager, jeg misforsto vist :=) Det registeret bestemmer om den skal reagere hvis den går fra høy til lav, eller lav til høy osv. Altså verdien som kommer inn på den eksterne interrupten. Det kunne iallefall se slik ut i databladet, se side 64 i databladet. Lenke til kommentar
Furyfax Skrevet 17. april 2007 Forfatter Del Skrevet 17. april 2007 Så det vil si om jeg ikke skriver EICRA = (1<<ISC01) | (1<<ISC00); så vil den reagere både fra lav til høy og høy til lav, eller ? Lenke til kommentar
Firesky Skrevet 17. april 2007 Del Skrevet 17. april 2007 (endret) Ikke helt, hvis du ser i databladet på side 64 som sagt så vil du se en tabell over hvordan den vil oppføre seg etter hvile bit du setter. Der står det også hvordan du skal bruke registeret og hva man må/bør ta hensyn til. Datablad EDIT: det står Mega644 i databladet, men det var det som var linka til på siden til Mega164 på avrfreaks, så jeg regner med dem er rimelig like. Endret 17. april 2007 av Firesky Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå