Külső megszakítás - WinAVR

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
Avatar
kisstam05
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2009. március 1. vasárnap, 7:00

Külső megszakítás - WinAVR

Hozzászólás Szerző: kisstam05 »

Sziasztok !

Mivel még kezdő vagyok az avr programozáshoz, konkrétan az Atmega128-hoz , ezért természetesen semmi sem úgy megy ahogy elképzeltem. :? Konkrétan az a problémám hogy nem megy a külső megszakítás és nem jövök rá hogy miért. Proteus-ban tesztelek.

Kód: Egész kijelölése

#include <avr/io.h>
#include <avr/delay.h> 
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/iom128.h>

static int SREG_start;

ISR(INT5_vect) {
	PORTA = 0xFF;
	_delay_ms(100);
	PORTA = 0x00;
	SREG = SREG_start;
}

int main (void) {
	
	EICRB |= 0b00001111; // felfutó élek
	EIMSK |= (1 << INT5) ; //int 5 engedélyezése
	sei();
	
	SREG_start = SREG;   // a megszakítás után ide kérne visszatérnie

	PORTD|=8;
	_delay_ms(1000)	;
	while (1)	{	  //foprogram ciklusa
		PORTD &=~8;
	}
}
Egyéb infó .:
Az Atmega-ra egy 8MHZ-kristály van kötve. USART-ot használok, az összes kimenetet vezérlésre , a bemeneteket szenzorikára.

Ha kisegítenétek annak nagyon örülnék.

Előre is köszi!
A hozzászólást 1 alkalommal szerkesztették, utoljára kisstam05 2009. április 20. hétfő, 13:32-kor.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Törölve!
A hozzászólást 1 alkalommal szerkesztették, utoljára kapu48 2009. április 20. hétfő, 12:39-kor.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Az mintha a SEI(); lenne....


Hardveresen jó a bemenet?:) Azza a felhúzásra kapcsol és a lábon ott a lehúzóellenállás?
Avatar
irak
Biztosítékgyilkos
Hozzászólások: 73
Csatlakozott: 2005. november 2. szerda, 7:00

Hozzászólás Szerző: irak »

Hali!

Azért nézzük át.
Mi a terved a programrészlettel?

Nekem 1-2 dolog ködös:)
Avatar
irak
Biztosítékgyilkos
Hozzászólások: 73
Csatlakozott: 2005. november 2. szerda, 7:00

Hozzászólás Szerző: irak »

Ja értem.
Külső jelre, beállítod a portd.8-at, egy pillanatra.
Probáld így:

#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/iom128.h>

ISR(INT5_vect) {
PORTA = 0xFF;
_delay_ms(100);
PORTA = 0x00;
PORTD|=8;
_delay_ms(1000) ;
}

int main (void) {
DDRA=0xFF; //
DDRB=0x00; //
DDRC=0xFF; //
DDRD=0x0F; //
DDRE=0x00; //

EICRB |= 0b00001111; // felfutó élek
EIMSK |= (1 << INT5) ; //int 5 engedélyezése
sei();

PORTD|=8;
_delay_ms(1000) ;
while (1) { //foprogram ciklusa
PORTD &=~8;
}
}

Nagyjából értem mit akarsz az SREG-es dologgal.
De az SREG csak a kontroller állapotát tükrözi, az aktuális utasítás címét nem.
Egyébként az IRQ mikor végzett, oda tér vissza ahol éppen tartott a vérehajtás...tehát a végtelen ciklusodba.
Avatar
kisstam05
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2009. március 1. vasárnap, 7:00

Hozzászólás Szerző: kisstam05 »

Valóban :oops: , lemaradt 1-2 ellenállás. Úgy megy a megszakítás csak nem oda tér vissza ahova kéne. Nem egy ledet villogtat csak már kínomba annyira le egyszerűsítettem a progit hogy ez maradt. A lényeg az hogy van

Kód: Egész kijelölése

// ide kéne visszatérnie akármikor megnyomom a megszakítás gombot.
while (1) {
       usart_init();  // uart beállítása
       usart_conn(); // protokoll kommunikáció felépítése 
       .
       .
       while(!(PIND & (1<<6)));
}
akkor ezt meg sem lehet oldani ?
Avatar
irak
Biztosítékgyilkos
Hozzászólások: 73
Csatlakozott: 2005. november 2. szerda, 7:00

Hozzászólás Szerző: irak »

Úgy megtudod, hogy az irq egy változóba beír, ami kilépési feltétel a while ciklusnak.


ISR(INT5_vect) {
kilep=0;
}


while(1){
kilep=1;
while (kilep) {
usart_init(); // uart beállítása
usart_conn(); // protokoll kommunikáció felépítése
.
.
while(!(PIND & (1<<6)));
}
}
Avatar
kisstam05
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2009. március 1. vasárnap, 7:00

Hozzászólás Szerző: kisstam05 »

Köszönöm a segítséget. Így már elboldogulok, csak kicsit átírom a kódot.
Avatar
kisstam05
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2009. március 1. vasárnap, 7:00

Hozzászólás Szerző: kisstam05 »

Itt a végeredmény, a nagy hajrában megtaláltam hogy lehet ugrálni :D

Kód: Egész kijelölése

#include <avr/io.h>
#include <avr/delay.h> 
#include <avr/interrupt.h>
#include <avr/iom128.h>
#include <setjmp.h>


jmp_buf env;  // tárolni fogja hogy hova ugrunk.

int main (void) {
	EICRB = 0b00001100; //00110000 felfutó él
	EIMSK = (1 << INT5);
	sei();

	setjmp (env);             // ugráspont beálítása

	PORTD|=8;
	_delay_ms(100)	;
	while (1)	{	
		usart_init(); // uart beállítása
                usart_conn(); // protokoll kommunikáció felépítése
                .
                while(!(PIND & (1<<6))); 
                PORTD&=~8;
	}
}

ISR(INT5_vect) {
	PORTA = 0xFF;
	_delay_ms(100);
	PORTA = 0x00;
	longjmp (env, 1);   //ugrás
}
Avatar
irak
Biztosítékgyilkos
Hozzászólások: 73
Csatlakozott: 2005. november 2. szerda, 7:00

jump

Hozzászólás Szerző: irak »

Szevasz!

Nem értem miért ragaszkodsz te az ugráláshoz, az IRQ-ból ez így nem illik:)

A megszakítás lementi a verembe forráscímet, meg a C fordító még 1-2 regisztert is.
Ha így simán kiugrasz, az IRQ végét jelentő RETI utasítás elmarad(ergo veremben marad a cím, meg miegyéb) , és gyanítom hogy elöbb-utóbb veremtúlcsordulásod lesz.
Az a PORTD|=8 miért nem fér bele az IRQ függvénybe?

De ha műxik ez igy jól, akkor ok!
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

A megszakításból RETI-vel kel kilépni!
Ha nem így teszel, akkor elmarad az automatikus INT engedélyezés, és a veremből a visszatérési cím kivétele!
Amit illik a programban pótolni! Különben előbb, utóbb hibát okoz!
:roll:
Avatar
kisstam05
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2009. március 1. vasárnap, 7:00

Hozzászólás Szerző: kisstam05 »

Ragaszkodom hozzá :) , mivel a while(1) -n belül elég komoly és komplex programrészlet van amit nem publikálhatok egyéb okok miatt :? . De ki kell ugranom mindenképpen meg kell szakítani azt a részt és ki kell ugrani a while ciklus elé.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Megszakitas:
- belep
- jelzobit bebillent
- vegeznivalo megtesz
- RETI


Foprogramban:
if flag=1 then.....


A megszakittas ha tul hosszu, akkor abbol akadas lesz!
Ha megszakitasbol nem lepsz ki, akkor a követkeuot nem tudod fogadni!
Probalj meg LCDre kiirni vmit megszakitasbol....
Pl gombnyomast. Nezd meg a Bascom Megszakitas fejezetet.... Ott van minta:)
Avatar
kisstam05
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2009. március 1. vasárnap, 7:00

Hozzászólás Szerző: kisstam05 »

javíts ki ha tévedek, ( programozó lennék )

Kód: Egész kijelölése

while(1){
       while(feltetel){
               csinál_valamit_1();
               csinál_valamit_2();
                             // teszemazt itt jár a program, és megtörténik a megszakítás, akkor ide is fog visszatérni és lefut a többi programrész, aminek nem lenne szabad, ( akár elöl , akár hátul tesztelő ciklusom van), és a szubrutinokba nem tehetek minden sor után vizsgálatot, mert az kb 400-500 sor
               csinál_valamit_n-1();
               csinál_valamit_n();
           }
}
hogy nem tudom használni újra a megszakítást, erre szolgál a longjmp() második paramétere, ha jól értelmeztem.
Avatar
irak
Biztosítékgyilkos
Hozzászólások: 73
Csatlakozott: 2005. november 2. szerda, 7:00

Érdekes.

Hozzászólás Szerző: irak »

Hát nemtudom.

Forgass le egy hasonló programot, visszafordítom gépi kódra, és megmondom mit csinál a longjmp(), ha gondolod persze.
Lehet hogy lekezel mindent, nem mondom hogy nem...

De jut eszembe, mi lenne ha a reset-et használnád triggernek?
Válasz küldése