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

[Atmega16][C] Port A jako magistrala adresowa i danych

mareks 10 Wrz 2008 10:29 3075 6
REKLAMA
  • #1 5521534
    mareks
    Poziom 13  
    Mam problem z obsluga Portu A pracujacego jako magistrala adresowa i danych.Do portu mam podpiete dwa kontrolery CAN i pamiec FIFO . Atmega odczytuje dane z kontrolerow CAN i przyrzuca je do FIFO. Przy malym "ruchu" na magistrali wszystko jest OK ale przy duzym obserwuje ze w FIFO sa zapisane FF zamiast konkretnej wartosci (nie pauje suma kontrolna) .Mikrokontroler zapisuje rekord 30bajtow i w tym rekordzie zdarza sie ze jeden bajt jest zamieniony na FF .Wydaje mi sie ze Atmega ma problem z szybkim przelaczaniem portu A z in na out.AVCC jest podpiete do plusa, zadnych zewnetrznych pull-up'ow jedynie wlaczony wewnetrzny przy stanie bezczynnosci magistrali.Pamiec ma czas dostepu 55ns.Juz mi sie skonczyly pomysly co z tym dalej robic .

    Poprawiłem tytuł:
    https://www.elektroda.pl/rtvforum/topic1015361.html
    [c_p]
  • REKLAMA
  • REKLAMA
  • #3 5521714
    mareks
    Poziom 13  
    Mikrokontroler odczytuje dane z CAN po otrzymaniu przerwania i umieszcza je w RAM w postaci rekordu i ustawia flage ze sa dane do wyslania do FIFO.W main jest funkcja (scheduler) ktora w petli sprawdza czy jest ustawiona flaga.Jezeli jest ustawiona uruchamia funkcje (write_RFIFO_data) wysylki z mikrokontrolera do FIFO. W zalaczniku kod
  • #4 5524910
    kulmar
    Poziom 31  
    
    char read_CAN_reg (char channel, char addr_reg) //3
    {
    	char tm_read;
    	if (channel == 1)
    	{
    		CSel(1); //CS1 0
    		PORTD |= 0x70 ; //Ale 1,!WR 1,!WR1
    		DDRA = 0xFF; //PortA output
    
    
    		PORTA = addr_reg; //put addr_reg on bus    
    
    		PORTD &= ~(_BV(ALE)) ; //Ale 0	 
    
    		DDRA = 0x00; // Port A HiZ
    
    
    		PORTA = 0xFF; //
    		PORTD &=~(_BV(RD)); // !RD 0
    		asm("NOP");
    		tm_read = PINA; //read value from Port A
    		PORTD |= _BV(RD) ;; //!RD 1
    		CSel(0); //all off
    		DDRA = 0x00; //Port A HiZ
    		PORTA = 0xFF; //Port A pull up enabled
    
    
    


    Trochę zgaduję, bo przy braku schematu i innych parametrów, jak częstotliwość zegara i rodzaju procesora trudno o dokładniejszą analizę.
    Wartości 0xff w FIFO nie muszą przecież być zapisywane jako błędne przez procesor, a mogą być błędnie odczytane z kontrolera CAN. Na razie zwróciłem uwagę na sekwencję odczytu z CAN:
    adres kontrolera jest wystawiany na PORTA
    ALE = 0 (Address Latch Enable ?) - rozumiem, że adres jest zatrzaskiwany opadającym zboczem sygnału ALE
    PORTA jest ustawiany w stan wysokiej impedancji.
    Jeśli procesor jest taktowany szybkim zegarem, to być może błędy powstają już tutaj. Pomiędzy zatrzaśnięciem adresu przez ALE a jego wystawieniem na PORTA dodałbym instrukcję nop i przed ustawieniem portu w stan wysokiej impedancji - również nop. Niektóre układy wymagają określonego czasu utrzymania danych na magistrali przed i po zboczu zegara. Ale podkreślam to jest tylko moja spekulacja, gdyż brak jest wystarczających danych. Na razie anlizowałem tylko tą część kodu. Można od wstawienia tych instrukcji w kod zacząć i zobaczyć, czy problem zniknie.

    Pozdrawiam
    Mariusz

    Dodano: typ procesora jest w tytule, nie zauważyłem.

    Pozdrawiam
    Mariusz
  • REKLAMA
  • #5 5527807
    mareks
    Poziom 13  
    Czestotliwosc 16MHz. Te bledne wartosci na pewno nie pochodza od SJA1000 (kontolera CAN). Analizujac dane zapisane w FIFO to 0xFF pojawia sie w roznych momentach i niezaleznie od odczytu z CAN . Min procesor zapisuje do FIFO : czas ,nr kanalu,kilka bajtow pustych wypelnionych zerami i przeklamania zdarzaja sie rowniez tutaj , wiec sadze ze procedura odczytu z kontrolera CAN jest OK.
    Cytat:
    ALE = 0 (Address Latch Enable ?) - rozumiem, że adres jest zatrzaskiwany opadającym zboczem sygnału ALE
    PORTA jest ustawiany w stan wysokiej impedancji.
    Jeśli procesor jest taktowany szybkim zegarem, to być może błędy powstają już tutaj. Pomiędzy zatrzaśnięciem adresu przez ALE a jego wystawieniem na PORTA dodałbym instrukcję nop i przed ustawieniem portu w stan wysokiej impedancji - również nop. Niektóre układy wymagają określonego czasu utrzymania danych na magistrali przed i po zboczu zegara.

    Ok dodam rowniez tutaj nop i sprobuje.
    Ciekawa rzecz udalo mi sie zaobserwowac (w zalaczeniu screenshot) ze procesor nie wykonal operacji jakie powinien zrobic : DDRA = 0XFF i PORTA = value , tylko pozostawil stany portu niezmienione.Zastanawiam sie czy wplyw na takie zachowanie nie ma sam zegar systemowy .W projekcie uzywam zewnetrznego generatora kwarcowego zbudowanego na bramkach podlaczonego do XTAL1.Ale mialem problem z ustawieniami fusebit.Mianowicie z ustawionym CSEL 000 (zewntrzny generator) procesor w ogole nie chodzil , dopiero przestawienie na CSEL 111 (kwarc 8MHz >) spowodowal ze procesor chodzi.Pytanie czy sygnal z generatora przy ustawieniu CSEL 000 musi byc "czysta" fala prostokatna ? U mnie sygnal z generatora nie jest super prostokatny.
  • REKLAMA
  • #7 5530520
    mareks
    Poziom 13  
    Wlasnie tak zrobilem i nic nie pomoglo.Tak sie zastanawiam czy problem nie lezy w tym ze mikrokontroler po prostu jest za wolny.Dwa kanaly CAN obsluguje poprzez przerwania , przerwania od timera co 0,1 ms a w "wolnych chwilach" wysylka i odbior danych z USB .Jest tak zajety obluga przerwan ze mu sie piepszy co widac w zlaczniku w poprzedniej wiadomosci.
REKLAMA