logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega128] [GCC] Symulowanie przerwania w AVR Studio?

Myrek1 10 Cze 2008 20:36 3941 6
REKLAMA
  • #1 5233316
    Myrek1
    Poziom 23  
    Witam.
    Piszę procedurę obsługi SPI w Atmedze. W pewnym momencie oczywiście trzeba sprawdzić flagę, czy dana się wysłała. Jednak symulator nie generuje tego przerwania. Czy tak już ma symulator? Z Helpa wyczytałem, że jest symulacja SPI i przerwań, u mnie nic się nie zmienia.
    Oczywiście mam ustawione globalne przerwania i te od SPI.
    Oto kod:

    #include <io.h>
    #include <MCP23S17.h>
    #include <interrupt.h>
    
    #define SS_NISKI() (PORTB &= ~0x01); //stan niski na SS
    #define SS_WYSOKI() (PORTB |= 0x01); //stan wysoki na SS
    
    #define ADRES 0x02; //adres A0=1, A1=A2=0
    
    void spi_init(void)
    {
    	SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPIE); //tryb nadrzedny, predkosc 4MHz, wlaczenie SPI, big endian, wlaczenie przerwania
    	DDRB |= 0b00000111; //ustawienie kierunku bitow portu
    	SS_WYSOKI(); //stan wysoki na SS
    }
    
    void spi_wyslij(char dana)
    {
    	SPSR |= (1 << SPIF);
    	SPDR = dana;
    	while(!(SPSR & (1<<SPIF)));
    }
    
    
    
    void mcp23s17_zapisz(unsigned char rejestr, unsigned char dana)
    {
    	SS_NISKI();
    	spi_wyslij(0x02 | 0x01 | 0x40);
    	spi_wyslij(rejestr);
    	spi_wyslij(dana);
    	SS_WYSOKI();
    }
    
    void main(void)
    {
    	sei();
    	spi_init();
    	mcp23s17_zapisz(IOCONB, 0b00001000);
    	mcp23s17_zapisz(IOCONB, 0xFF);
    	mcp23s17_zapisz(GPIOB, 0b00000010);
    
    }
    
  • REKLAMA
  • #2 5233474
    BoskiDialer
    Poziom 34  
    Wywoływanie przerwania w symulatorze może i jest, ale twój program nieoczekiwanie będzie się wtedy resetował. Nie musisz załączać przerwania (SPIE) żeby sprawdzać flagę SPIF. Jeśli załączysz SPIE, procek (symulowany) będzie przechodził do odpowiedniego wektora przerwań, a tam nie ma żadnej procedury obsługi przerwania (domyślnie jest skok pod etykietę __bad_interrupt a tam jest skok pod adres zerowy, czyli nastąpi reset programowy).
  • REKLAMA
  • #3 5233532
    Myrek1
    Poziom 23  
    No ok, ale sie nie resetuje, bo to przerwanie nie występuje, dlaczego?
  • REKLAMA
  • #4 5233695
    adamusx
    Poziom 27  
    Poza tym program po wykonaniu następujących linii kodu:

      sei();
       spi_init();
       mcp23s17_zapisz(IOCONB, 0b00001000);
       mcp23s17_zapisz(IOCONB, 0xFF);
       mcp23s17_zapisz(GPIOB, 0b00000010);


    opuszcza funkcję main() i pewnie się wykrzacza, gdyż nie masz na końcu zadnej petli nieskonczonej.
  • REKLAMA
  • #5 5233716
    Myrek1
    Poziom 23  
    To jest bez znaczenia. Napisałem, że pisze dopiero program. Mam tylko problem z tą flagą i zatrzymującym się programem (w symulatorze) na tej linii:

    while(!(SPSR & (1<<SPIF))); 
    
  • Pomocny post
    #6 5233740
    BoskiDialer
    Poziom 34  
    Powiem tak: symulator działa bardzo dokładnie (przed chwilą sprawdziłem). Odwzorowuje wszystkie detale SPI. W dokumentacji jest napisane, że jeśli pin SS jest wejściem o stanie niskim, to bit MSTR jest kasowany. Ponieważ DDRB konfigurujesz po SPCR, to nie udaje Ci się ustawić bitu MSTR (zostaje on natychmiast skasowany) i SPI pracuje jako slave. Przesuń ustawienie DDRB przed załączenie SPI, a będzie działać.

    (edit)

    :arrow:adamusx - brak pętli nieskończonej nie może powodować wykrzaczenia się kodu. Po powrocie z funkcji main wykonywanie przechodzi przez sekcje bodajże .fin9 do .fin0, przy czym .fin0 jest skokiem do _exit - pętli nieskończonej (wycinek ze zrzutu który miałem pod ręką):
    
          fe:	0e 94 85 00 	call	0x10a	; 0x10a <main>
         102:	0c 94 22 20 	jmp	0x4044	; 0x4044 <_exit>
    (...)
    00004044 <_exit>:
        4044:	ff cf       	rjmp	.-2      	; 0x4044 <_exit>
    

    źródło: http://www.nongnu.org/avr-libc/user-manual/mem_sections.html#sec_dot_fini
  • #7 5233874
    Myrek1
    Poziom 23  
    @BoskiDialer, to jest to. Wielkie THX, również za pierwszą uwagę.
    Nie wiedziałem o tym, dlatego kiedyś miałem podobny problem (ten ze skokiem pod puste przerwanie).
    Zamiana linijek również pomogła, teraz jest wszystko ok.

    Jednak nie zamykam wątku bo mogę mieć jeszcze kilka pytań.

    Aha, nie jest też potrzebne zerowanie bitu SPIF, bo się sam zeruje po zapisie danej do rejestru SPDR
REKLAMA