Goto page 1, 2 Next
Jakub Rakus
Guest
Sun Jan 06, 2013 3:15 pm
Witajcie,
Ostatnie moje problemy (tu na grupie poruszane) z obsługą uarta na
atmelkach stały się moim gwoździem do trumny bascoma i w końcu się
zawziąłem na C, choć zabierałem się do tego już od roku jak pies do
jeża. No to na początek, standardowo pomrugamy diodą. Ot taki programik:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD = 0xFF;
PORTD = 0x00;
while(1)
{
PORTD ^= _BV(0);
_delay_ms(500);
}
}
I zonk, na porcie ciągle stan wysoki. Podejrzałem plik .lss i niby
wszystko ok, jak patrzę na instrukcję asemblera to powinno działać:
00000038 <main>:
38: 8f ef ldi r24, 0xFF
3a: 81 bb out 0x11, r24
3c: 12 ba out 0x12, r1
3e: 91 e0 ldi r25, 0x01
40: 82 b3 in r24, 0x12
42: 89 27 eor r24, r25
44: 82 bb out 0x12, r24
46: ef ef ldi r30, 0xFF
48: ff e3 ldi r31, 0x3F
4a: 31 97 sbiw r30, 0x01
4c: f1 f7 brne .-4
4e: 00 c0 rjmp .+0
50: f7 cf rjmp .-18
Ale niestety nie działa, stan na porcie zmienia się bez opóźnienia. A
teraz ciekawostka, zamiast wykorzystywać funkcję _delay_ms wstawiłem swoją:
void delay(void)
{
uint16_t i;
for (i=0;i<15000;i++);
}
Patrzę na plik .lss, a tu:
00000038 <delay>:
38: 88 e9 ldi r24, 0x98
3a: 9a e3 ldi r25, 0x3A
3c: 01 97 sbiw r24, 0x01
3e: f1 f7 brne .-4
40: 08 95 ret
00000042 <main>:
42: 8f ef ldi r24, 0xFF
44: 81 bb out 0x11, r24
46: 12 ba out 0x12, r1
48: 91 e0 ldi r25, 0x01
4a: 82 b3 in r24, 0x12
4c: 89 27 eor r24, r25
4e: 82 bb out 0x12, r24
50: fc cf rjmp .-8
Wychodzi na to, że po przełączeniu bitu PD0 w ogóle nie wywołuje funkcji
delay() - no i port tak właśnie się zachowuje, w kółko się przełącza.
Obstawiam opcję, że ja czegoś nie rozumie, ale może ktoś mnie oświeci.
--
Pozdrawiam
Jakub Rakus
Marek
Guest
Sun Jan 06, 2013 3:26 pm
On Sun, 06 Jan 2013 15:15:46 +0100, Jakub Rakus <szczur01@op.pl>
wrote:
Quote:
Wychodzi na to, że po przełączeniu bitu PD0 w ogóle nie wywołuje
funkcji
delay() - no i port tak właśnie się zachowuje, w kółko się
przełącza.
Nie użyłeś volatile przy deklaracji zmiennej "i" w funkcji delay(),
"i" nie jest nigdzie wykorzystane dalej w kodzie funkcji więc
optymalizator wywalił cały for, jak nie potrzebny for to i cała
funkcja delay()...
--
Marek
Grzegorz Niemirowski
Guest
Sun Jan 06, 2013 3:29 pm
Jakub Rakus <szczur01@op.pl> napisał(a):
Quote:
Witajcie,
Ostatnie moje problemy (tu na grupie poruszane) z obsługą uarta na
atmelkach stały się moim gwoździem do trumny bascoma i w końcu się
zawziąłem na C, choć zabierałem się do tego już od roku jak pies do jeża.
A problem był po stronie Bascoma czy niedopracowanego algorytmu?
Quote:
No to na początek, standardowo pomrugamy diodą. Ot taki programik:
#define F_CPU 16000000UL
#include <avr/io.h
#include <util/delay.h
int main(void)
{
DDRD = 0xFF;
PORTD = 0x00;
while(1)
{
PORTD ^= _BV(0);
_delay_ms(500);
}
}
I zonk, na porcie ciągle stan wysoki. Podejrzałem plik .lss i niby
wszystko ok, jak patrzę na instrukcję asemblera to powinno działać:
00000038 <main>:
38: 8f ef ldi r24, 0xFF
3a: 81 bb out 0x11, r24
3c: 12 ba out 0x12, r1
3e: 91 e0 ldi r25, 0x01
40: 82 b3 in r24, 0x12
42: 89 27 eor r24, r25
44: 82 bb out 0x12, r24
46: ef ef ldi r30, 0xFF
48: ff e3 ldi r31, 0x3F
4a: 31 97 sbiw r30, 0x01
4c: f1 f7 brne .-4
4e: 00 c0 rjmp .+0
50: f7 cf rjmp .-18
Ale niestety nie działa, stan na porcie zmienia się bez opóźnienia. A
teraz ciekawostka, zamiast wykorzystywać funkcję _delay_ms wstawiłem
swoją:
void delay(void)
{
uint16_t i;
for (i=0;i<15000;i++);
}
Patrzę na plik .lss, a tu:
00000038 <delay>:
38: 88 e9 ldi r24, 0x98
3a: 9a e3 ldi r25, 0x3A
3c: 01 97 sbiw r24, 0x01
3e: f1 f7 brne .-4
40: 08 95 ret
00000042 <main>:
42: 8f ef ldi r24, 0xFF
44: 81 bb out 0x11, r24
46: 12 ba out 0x12, r1
48: 91 e0 ldi r25, 0x01
4a: 82 b3 in r24, 0x12
4c: 89 27 eor r24, r25
4e: 82 bb out 0x12, r24
50: fc cf rjmp .-8
Wychodzi na to, że po przełączeniu bitu PD0 w ogóle nie wywołuje funkcji
delay() - no i port tak właśnie się zachowuje, w kółko się przełącza.
Obstawiam opcję, że ja czegoś nie rozumie, ale może ktoś mnie oświeci.
Ustawiłeś optymalizacje zgodnie z dokumentacją?
Którego kompilatora używasz?
--
Grzegorz Niemirowski
http://www.grzegorz.net/
OE PowerTool i Outlook Express:
http://www.grzegorz.net/oe/
Uptime: 0 days, 1 hours, 26 minutes and 32 seconds
Jakub Rakus
Guest
Sun Jan 06, 2013 3:45 pm
W dniu 06.01.2013 15:26, Marek pisze:
Quote:
Nie użyłeś volatile przy deklaracji zmiennej "i" w funkcji delay(), "i"
nie jest nigdzie wykorzystane dalej w kodzie funkcji więc optymalizator
wywalił cały for, jak nie potrzebny for to i cała funkcja delay()...
Ooo, no to jest racja, nie pomyślałem. Faktycznie, dodaję volatile,
wtedy śmiga. Podziękował!
Ale nadal pozostaje problem nie działającej funkcji _delay_ms().
--
Pozdrawiam
Jakub Rakus
Jakub Rakus
Guest
Sun Jan 06, 2013 3:57 pm
W dniu 06.01.2013 15:29, Grzegorz Niemirowski pisze:
Quote:
A problem był po stronie Bascoma czy niedopracowanego algorytmu?
Problem polegał na tym, że pomimo wielu prób nie doszedłem do tego jak
stworzyć poprawnie działający algorytm pisząc go tylko w bascomie, nie
angażując w to asemblera, a nie miałem na to ochoty

- poza tym po
skompilowaniu miałem i tak już ogromny program (3kB!), a w planie
jeszcze kilka funkcjonalności, więc i tak bym doszedł do granicy
możliwości darmowego bascoma.
Quote:
Ustawiłeś optymalizacje zgodnie z dokumentacją?
Którego kompilatora używasz?
Korzystam z code::blocks i avr-gcc w wersji 4.5.3. Ustawiam
optymalizację na -O. Co ciekawe, gdy wyłączę optymalizację w ogóle,
oczywiście mam ostrzeżenie, że funkcje z delay.h będą działać
niepoprawnie, kompiluje się, program wynikowy jest ogromny, ale... działa.
--
Pozdrawiam
Jakub Rakus
Marek
Guest
Sun Jan 06, 2013 4:01 pm
On Sun, 06 Jan 2013 15:45:11 +0100, Jakub Rakus <szczur01@op.pl>
wrote:
Quote:
Ale nadal pozostaje problem nie działającej funkcji _delay_ms().
Zgaduje teraz (nie znam się na avr), czy czasem nie potrzeba
wcześniej wywolac jakaś funkcję konfigurujaca bibliotekę wszystkich
funkcji delay? Skąd delay wie jaka jest aktualna częstotliwość
zegara?
--
Marek
Jakub Rakus
Guest
Sun Jan 06, 2013 4:09 pm
W dniu 06.01.2013 16:01, Marek pisze:
Quote:
On Sun, 06 Jan 2013 15:45:11 +0100, Jakub Rakus <szczur01@op.pl> wrote:
Ale nadal pozostaje problem nie działającej funkcji _delay_ms().
Zgaduje teraz (nie znam się na avr), czy czasem nie potrzeba wcześniej
wywolac jakaś funkcję konfigurujaca bibliotekę wszystkich funkcji delay?
Skąd delay wie jaka jest aktualna częstotliwość zegara?
Zgodnie z tym co napisano na początku delay.h wystarczająca jest
linijka, którą mam na początku kodu:
#define F_CPU 16000000UL
A nawet gdyby jej nie było to przyjmie sobie domyślną wartość F_CPU
1000000UL.
--
Pozdrawiam
Jakub Rakus
Grzegorz Niemirowski
Guest
Sun Jan 06, 2013 4:58 pm
Jakub Rakus <szczur01@op.pl> napisał(a):
Quote:
Korzystam z code::blocks i avr-gcc w wersji 4.5.3. Ustawiam optymalizację
na -O. Co ciekawe, gdy wyłączę optymalizację w ogóle, oczywiście mam
ostrzeżenie, że funkcje z delay.h będą działać niepoprawnie, kompiluje
się, program wynikowy jest ogromny, ale... działa.
Nie wiem, co u Ciebie dokładnie oznacza -O, u mnie jest to -O1. Twój program
działa bez żadnego problemu u mnie na ATmega32 (może kompilujesz na zły
procesor). Używam Atmel Studio 6 (
AVR/GNU C Compiler : (AVR_8_bit_GNU_Toolchain_3.4.0_663) 4.6.2)
Poza tym w pierwszym poście piszesz: "I zonk, na porcie ciągle stan wysoki."
z czego wynika, że u Ciebie w ogóle nie wykonuje się pętla while.
Mój lss:
00000092 <main>:
Jakub Rakus
Guest
Sun Jan 06, 2013 5:28 pm
W dniu 06.01.2013 16:58, Grzegorz Niemirowski pisze:
Quote:
Nie wiem, co u Ciebie dokładnie oznacza -O, u mnie jest to -O1.
Zjadła się jedynka, też mam -O1.
Quote:
Poza tym w pierwszym poście piszesz: "I zonk, na porcie ciągle stan
wysoki." z czego wynika, że u Ciebie w ogóle nie wykonuje się pętla while.
Zasugerowałem się tym, że leda mi ciągle świeci, ale faktycznie pętla
się wykonuje - tylko, że cholernie szybko...
Quote:
//round up by default
__ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
#endif
__builtin_avr_delay_cycles(__ticks_dc);
a0: 2f ef ldi r18, 0xFF ; 255
a2: 39 e6 ldi r19, 0x69 ; 105
a4: 48 e1 ldi r20, 0x18 ; 24
a6: 21 50 subi r18, 0x01 ; 1
a8: 30 40 sbci r19, 0x00 ; 0
aa: 40 40 sbci r20, 0x00 ; 0
ac: e1 f7 brne .-8 ; 0xa6 <main+0x14
ae: 00 c0 rjmp .+0 ; 0xb0 <main+0x1e
O widzisz tu właśnie jest rozbieżność - u Ciebie jak widzę działa to
dokładnie tak jak opisane jest to na początku delay.h. U mnie
_HAS_DELAY_CYCLES ma wartość 1, więc teoretycznie także powinna zostać
wywołana funkcja _builtin_avr_delay_cycles, a z jakiegoś powodu tak się
nie dzieje.
--
Pozdrawiam
Jakub Rakus
Grzegorz Niemirowski
Guest
Sun Jan 06, 2013 5:46 pm
Jakub Rakus <szczur01@op.pl> napisał(a):
Quote:
O widzisz tu właśnie jest rozbieżność - u Ciebie jak widzę działa to
dokładnie tak jak opisane jest to na początku delay.h. U mnie
_HAS_DELAY_CYCLES ma wartość 1, więc teoretycznie także powinna zostać
wywołana funkcja _builtin_avr_delay_cycles, a z jakiegoś powodu tak się
nie dzieje.
A czy ten Twój toolchain ma w ogóle tę funkcję? I dlaczego użwasz akurat
tego toolchaina a nie np. Atmel Studio 6 albo WinAVR?
--
Grzegorz Niemirowski
http://www.grzegorz.net/
OE PowerTool i Outlook Express:
http://www.grzegorz.net/oe/
Uptime: 0 days, 0 hours, 57 minutes and 50 seconds
Jakub Rakus
Guest
Sun Jan 06, 2013 6:13 pm
W dniu 06.01.2013 17:46, Grzegorz Niemirowski pisze:
Quote:
A czy ten Twój toolchain ma w ogóle tę funkcję? I dlaczego użwasz akurat
tego toolchaina a nie np. Atmel Studio 6 albo WinAVR?
Ale ja to wszystko robię pod linuxem. Więc podejrzewam właśnie brak owej
funkcji.
--
Pozdrawiam
Jakub Rakus
Grzegorz Niemirowski
Guest
Sun Jan 06, 2013 6:56 pm
Jakub Rakus <szczur01@op.pl> napisał(a):
Quote:
Ale ja to wszystko robię pod linuxem. Więc podejrzewam właśnie brak owej
funkcji.
Też mi się wydaje, że jej tam nie ma. Ma moim Ubuntu jest tak samo jak u
Ciebie. Dlatego najprościej będzie zainstalować sobie Atmel Studio na
Windowsie. Chyba, że jest jakiś prosty patch na avt-libc, ale nie znalazłem.
--
Grzegorz Niemirowski
http://www.grzegorz.net/
OE PowerTool i Outlook Express:
http://www.grzegorz.net/oe/
Uptime: 0 days, 2 hours, 4 minutes and 54 seconds
Jakub Rakus
Guest
Sun Jan 06, 2013 8:48 pm
W dniu 06.01.2013 18:56, Grzegorz Niemirowski pisze:
Quote:
Też mi się wydaje, że jej tam nie ma. Ma moim Ubuntu jest tak samo jak u
Ciebie. Dlatego najprościej będzie zainstalować sobie Atmel Studio na
Windowsie. Chyba, że jest jakiś prosty patch na avt-libc, ale nie
znalazłem.
Windows jest feee, nie chce go

Ale znalazłem przyczynę i rozwiązanie
problemu, otóż problemem jest położenie plików nagłówkowych. Domyślnie
kompilator gcc-avr w ich poszukiwaniu przeszukuje katalog /usr/include a
tam niestety wszystkiego nie ma, wystarczy w ustawieniach kompilatora
zmienić mu ścieżkę na /usr/lib/avr/include i nagle wszystko zaczyna
działać jak należy.
--
Pozdrawiam
Jakub Rakus
Atlantis
Guest
Sun Jan 06, 2013 10:15 pm
W dniu 2013-01-06 16:09, Jakub Rakus pisze:
Quote:
A nawet gdyby jej nie było to przyjmie sobie domyślną wartość F_CPU
1000000UL.
Chyba, że ustawimy inną w makefile.
Adam Wysocki
Guest
Tue Jan 08, 2013 12:15 pm
Jakub Rakus <szczur01@op.pl> wrote:
Quote:
#define F_CPU 16000000UL
_delay_ms(500);
Za dużo.
http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html
The maximal possible delay is 262.14 ms / F_CPU in MHz.
Daj:
for (int i(0); i < 50; ++i)
_delay_ms(10);
--
Gof
http://www.chmurka.net/
Goto page 1, 2 Next