-
1. Data: 2013-01-06 15:15:46
Temat: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: Jakub Rakus <s...@o...pl>
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
-
2. Data: 2013-01-06 15:26:23
Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: Marek <f...@f...com>
On Sun, 06 Jan 2013 15:15:46 +0100, Jakub Rakus <s...@o...pl>
wrote:
> 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
-
3. Data: 2013-01-06 15:29:38
Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: "Grzegorz Niemirowski" <g...@p...onet.pl>
Jakub Rakus <s...@o...pl> napisał(a):
> 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?
> 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
-
4. Data: 2013-01-06 15:45:11
Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: Jakub Rakus <s...@o...pl>
W dniu 06.01.2013 15:26, Marek pisze:
> 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
-
5. Data: 2013-01-06 15:57:45
Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: Jakub Rakus <s...@o...pl>
W dniu 06.01.2013 15:29, Grzegorz Niemirowski pisze:
>
> 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.
>
> 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
-
6. Data: 2013-01-06 16:01:09
Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: Marek <f...@f...com>
On Sun, 06 Jan 2013 15:45:11 +0100, Jakub Rakus <s...@o...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?
--
Marek
-
7. Data: 2013-01-06 16:09:35
Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: Jakub Rakus <s...@o...pl>
W dniu 06.01.2013 16:01, Marek pisze:
> On Sun, 06 Jan 2013 15:45:11 +0100, Jakub Rakus <s...@o...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
-
8. Data: 2013-01-06 16:58:31
Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: "Grzegorz Niemirowski" <g...@p...onet.pl>
Jakub Rakus <s...@o...pl> napisał(a):
> 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>:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD = 0xFF;
92: 8f ef ldi r24, 0xFF ; 255
94: 81 bb out 0x11, r24 ; 17
PORTD = 0x00;
96: 12 ba out 0x12, r1 ; 18
while(1)
{
PORTD ^= _BV(0);
98: 91 e0 ldi r25, 0x01 ; 1
9a: 82 b3 in r24, 0x12 ; 18
9c: 89 27 eor r24, r25
9e: 82 bb out 0x12, r24 ; 18
#else
//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>
b0: 00 00 nop
b2: f3 cf rjmp .-26 ; 0x9a <main+0x8>
000000b4 <_exit>:
b4: f8 94 cli
000000b6 <__stop_program>:
b6: ff cf rjmp .-2 ; 0xb6 <__stop_program>
--
Grzegorz Niemirowski
http://www.grzegorz.net/
OE PowerTool i Outlook Express: http://www.grzegorz.net/oe/
Uptime: 0 days, 0 hours, 6 minutes and 49 seconds
-
9. Data: 2013-01-06 17:28:40
Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: Jakub Rakus <s...@o...pl>
W dniu 06.01.2013 16:58, Grzegorz Niemirowski pisze:
> Nie wiem, co u Ciebie dokładnie oznacza -O, u mnie jest to -O1.
Zjadła się jedynka, też mam -O1.
> 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...
> //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
-
10. Data: 2013-01-06 17:46:23
Temat: Re: avr i C - kto nie rozumie: kompilator, procesor czy ja?
Od: "Grzegorz Niemirowski" <g...@p...onet.pl>
Jakub Rakus <s...@o...pl> napisał(a):
> 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