Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

Atmega128-niechciany reset czy problem z uartem????pomocy!

lisu_ck
-
-
Posty:3
Rejestracja:27 sty 2007, o 02:21
Lokalizacja:Warszawa
Atmega128-niechciany reset czy problem z uartem????pomocy!

Postautor: lisu_ck » 27 sty 2007, o 02:58

Witam,
Na wstępnie prosiłbym nie odsyłać mnie do innych artykułów o niekontrolowanych resetach atmeg wszelkiej maśći, ponieważ przeglądnąłem ich ich trochę i niestety nic nie pomogło:(.

Otóż jakis czas temu zmajstrowałem sobie zestaw uruchomieniowy z atmegą 128 i kilkoma dodatkami (rs232, flash szeregowy itd).

Niestety, kiedy przyszlo do testowania zaczęły dziać sie bardzo dziwne rzeczy.

Problem dokładnie jest taki:

korzystam z kompilatora codevision avr i chciałem na początek wysłać na PC-ta prosty tekst "hello world" albo cokolwiek w tym rodzaju - problem w tym, że procek zamiast wysłać całe zdanie, wysyła tylko pierwszy znak (czyli w wypadku tego tekstu literę "h"). Co ciekawsze zachowanie proca wskazuje na to, że program jest wykonywany własnie do momentu wysłania pierwszego znaku a później po prostu .. znowu wysyła pierwszy znak i tak w nieskończoność.

Na początku myślałem, że może coś jest z softem nie w porządku, ale okazało się, że procek wysyła ten znak w nieskończoność nawet jeśli fragment programu (czyli po prostu wywołanie funkcji getsf() ) ma być wykonany tylko 1 raz i basta (czyli w programie dokonuję tylko ustawień rejestrów sterujących proca i na końcu kodu wysylam ciąg znaków). Obojętnie czy ten ostatni fragment wsadzę w petle nieskonczona while(1) - wszsytko dzieje sie tak samo.

W sumie to po moich próbach w kodzie wnioskuję, że działa tylko jednorazowe wywołanie funkcji putchar() - następne już nie - co z resztą sprawdzałem.

Zeby nie było, że nie meczylem sie z tym problemem sam napiszę teraz co robiłem, żeby problemowi zaradzić (bezskutecznie):

- procek ma podwójne zabezpieczenie przeciwzakłoceniowe, tzn zasilanie jest zrobione 2x220uF (rownolegle, czyli 440uF) między VCC a masę na wyjsciu stabilizatora, pnadto 220uF na wejściu stab , poza tym kondensatory 1uF między zasilanie i mase bezposrednio na pinach vcc proca, no i jeszcze dławik przeciwzakłóceniowy 22uH na zasilaczu i po 1 dławiku 100uH doprowadzającym zasilanie do pinów Vcc proca,
- pin avcc odizolowany od vcc jednym z w/w dłąwików 100uH,
- takie zabezpieczenia chyba są wystarczające??? ( dodam że wszystko zasilane z 18V zasilacza drukarkowego, który sam w sobie też chyba jakies filtrowanie zakłóceń ma...)
- różnica napiec miedzy VCC i AVCC jest < niż 0.3 (zalecenie z datasheeta), więc to nie jest powód domniemanych resetów,
- próbowałem wyłączania Watchdoga i Brown out resetu - w każdym z przypadków nic się nie zmienia - nadal leci początkowy znak i lipa :( (restart)
- sprawdzałem wszystkie fusebity - ustawiony zewnętrzny oscylator kwarcowy 16MHz (CKSEL , CKOPT , SUT0iSUT1 tak jak podane w datasheecie )
- dodałem do kodu fragment sprawdzający źródło resetu , który działa w ten sposób, że sprawdzam zawartość rejestru MCUCSR i wysyłam na uart info o tym właśnie - wynik jest taki, że w kółko pojawia się znak pokazujący, że reset nie nastąpił , przy czym jeśli wyłączę zasilanie albo wymuszę reseta z "przycisku", to na hyper-terminalu pojawia się wtedy odpowiedni znak(P jesli był to power on reset , E jesli był to reset zewnetrzny - "z przycisku")...ale nigdy nie zauważyłem żeby pokazało jako zrodlo resetu watchdoga...

oto kod:

#include <mega128.h>

// Standard Input/Output functions
#include <stdio.h>
// Declare your global variables here

void main(void)
{
// Declare your local variables here
char c;
//int i;
// Reset Source checking
if (MCUCSR & 1)
{
// Power-on Reset
MCUCSR&=0xF0;
// Place your code here
c='P';
}
else if (MCUCSR & 2)
{
// External Reset
MCUCSR&=0xF0;
// Place your code here
c='E';
}
else if (MCUCSR & 4)
{
// Brown-Out Reset
MCUCSR&=0xF0;
// Place your code here
c='B';
}
else if (MCUCSR & 8)
{
// Watchdog Reset
MCUCSR&=0xF0;
// Place your code here
c='W';
}
else if (MCUCSR & 0x10)
{
// JTAG Reset
MCUCSR&=0xF0;
// Place your code here
c='J';
}
else
{
c='.';
};

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Port E initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTE=0x00;
DDRE=0x00;

// Port F initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTF=0xFF;
DDRF=0xFF;

// Port G initialization
// Func4=In Func3=In Func2=In Func1=In Func0=In
// State4=T State3=T State2=T State1=T State0=T
PORTG=0x00;
DDRG=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x00;
EICRB=0x00;
EIMSK=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ETIMSK=0x00;

// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: Off
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud rate: 9600
UCSR0A=0x00;
UCSR0B=0x18;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x67;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

putchar(c); <---- ten putchar działa jakby był w pętli while(1){...}, a co ciekawsze kolejne jego wywołania w kodzie nie działają już, stąd wnioskuje, ze to reset proca...

}

- sprawdziłem też układ max232a z którego korzystam - na nóżkach są odp napięcia wynikające z działąnia charge-pump'a (coś ponad 9v itd).
- poza tym raczej wykluczam jakieś zwarcie, bo wszystko jest montowane na płytce robionej w zewnętrznej firmie (dobra solder maska), zawsze korzystam z topnika i sprawdzałem czy nie ma zwarć pikaczem w multimetrze.

i tutaj moje pomysły się skończyły...

na razie nie mam czasu, żeby obejrzeć zasilanie na oscyloskopie na uczelni (w poszukiwaniu jakis szpilek i innych kwiatków), ale nie omieszkam tego zrobić, jeśli po sesji płytka nadal nie będzie działać

może macie jakieś sugestie, co w takim razie należałoby sprawdzić????

MDz
-
-
Posty:365
Rejestracja:29 mar 2003, o 13:35
Lokalizacja:Warszawa
Kontaktowanie:

Postautor: MDz » 27 sty 2007, o 10:54

Czy dobrze rozumiem, że program wywala się przy _pierwszym_ wywołaniu jakiejkolwiek procedury? Źle ustawiony stos?

Pierwsze skojarzenie:
Czy w fusebitach wyłączyłeś tryb zgodności z ATMega103?

Np. na stronie Jurka Szczesiula (http://avrside.ep.com.pl/) znajdziesz takie wyjaśnienie:

"... Atmega 128 jest dostarczona z zaprogramowanym trybem kompatybilności z modelem 103, z czym wiąże się mniejszy obszar RAM oraz niedostępność rozszerzonych rejestrów. Avr-gcc samoczynnie inicjalizuje stos na końcu RAM - a więc w trybie kompatybilności poza rzeczywiście dostępnym sprzętowo obszarem. Objawia się to trudnym do zinterpretowania wywracaniem się programu przy pierwszym przerwaniu czy wywołaniu funkcji, chociaż pierwsze testy wykazały poprawność pracy układu. .."


--
MDz
Ostatnio zmieniony 27 sty 2007, o 11:08 przez MDz, łącznie zmieniany 2 razy.

lisu_ck
-
-
Posty:3
Rejestracja:27 sty 2007, o 02:21
Lokalizacja:Warszawa

Postautor: lisu_ck » 27 sty 2007, o 11:00

Witam:)

Tego fusebita właśnie nie ruszałem :). Zaraz spróbuję.

armi
-
-
Posty:2
Rejestracja:19 sty 2004, o 23:31
Lokalizacja:Poznań

Postautor: armi » 27 sty 2007, o 12:03

miałem podobny przypadek tylko z Atmega8 i odbieraniem znaku. po odebraniu następował reset. Problem polegał na zastosowaniu złego wektora przerwania w procedurze obsługującej przerwanie odbiornika (SIG_USART0_RECV zamiast SIG_UART_RECV)

ale i tak w koncu stanęło na tym, ze testuję w pętli RXC, a nadawanie odbywa się tylko w przerwaniu timera ...

choć widzę, ze przerwania w UCSR0B są wyłączone, więc to pewnie nie to ...

lisu_ck
-
-
Posty:3
Rejestracja:27 sty 2007, o 02:21
Lokalizacja:Warszawa

Postautor: lisu_ck » 27 sty 2007, o 20:00

No i ... już działa :D - jednak tryb zgodności z Atmega103 był tym problemem :) strzał w 10tkę! Wieelkiee dzięki MDz!!!!

Wróć do „Elektronika - tematy dowolne”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 6 gości