AVR[C] Kod zajmuje duzo pamięci

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

AVR[C] Kod zajmuje duzo pamięci

Post autor: Dawid2379 » 29 mar 2012, 19:11

Dlaczego ten kod zajmuje tyle miejsca???

Kod: Zaznacz cały

#include <avr/io.h>
#include <util/delay.h>
 
 
int main(void)
{

DDRB = 0xFF; //Port B wyjscia
PORTB = 0x00; //stan niski na poczatku programu
DDRD = 0x00;
PORTB = 0xFF;

uint8_t i=24;
uint8_t b=12;


while(1)
{

        if(!(PIND & 1<<PD0))
			{ 
			  _delay_ms(10); 
			                  
				   { 
				     i+=1; 
				   } 
				   if(i>24)
				   { 
				      i=25; 
			 	   }              	              				          
			   
            }
			    
		    else if(!(PIND & 1<<PD1))
			{ 
			  _delay_ms(10);
                 
				     { 
				      i-=1; 
			 	     } 
					 if(i<2)
                     { 
				      i=1; 
			 	     }    
                 }

   PORTB = 0x00;
   _delay_ms(1.7);
   PORTB = 0xFF;
   _delay_ms(70);
   PORTB = 0x00;
   _delay_ms(1.7);
   PORTB = 0xFF;
   _delay_ms(i);
   PORTB = 0x00;
   _delay_ms(1.7);
   PORTB = 0xFF;
   _delay_ms(b);
   PORTB = 0x00;
   _delay_ms(1.7);
   PORTB = 0xFF;
   _delay_ms(88);
   
   }
 }

	
Program: 3814 bytes (186.2% Full)
(.text + .data + .bootloader)
Data: 264 bytes (206.3% Full)
(.data + .bss + .noinit)
[/quote]

kaliska5
Użytkownik
Posty: 348
Rejestracja: 01 maja 2008, 8:24
Lokalizacja: z nienacka
Kontakt:

Post autor: kaliska5 » 29 mar 2012, 19:35

Włącz optymalizacje.Poza tym sprawdzasz zwarcie przycisku do masy a nigdzie nie załączasz rezystorów podciągających na porcie D.

Awatar użytkownika
tymon_x
-
Posty: 64
Rejestracja: 14 wrz 2010, 16:48
Lokalizacja: Gdańsk

Post autor: tymon_x » 29 mar 2012, 23:16

Kod: Zaznacz cały

_delay_ms(1.7);
_delay_ms(i);
Zrobiłeś dwie najgorsze rzeczy na świecie, używasz float (mniejsze zło) i do funkcji generującą programowe opóźnienie (do kitu) używasz zmienną (wielkie zło). Zobacz jaki Tobie wygeneruje to listing.

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 30 mar 2012, 6:44

Poza tym co napisali koledzy wyżej, jest jeszcze funkcja _delay_us(), czyli mikrosekundy, stąd zamiast:

Kod: Zaznacz cały

_delay_ms(1.7); 
możesz:

Kod: Zaznacz cały

_delay_us(1700); 
w ten sposób nie korzystasz z liczb zmiennoprzecinkowych (wydłużenie kodu), o których wspomniał tymon_x.

Awatar użytkownika
tymon_x
-
Posty: 64
Rejestracja: 14 wrz 2010, 16:48
Lokalizacja: Gdańsk

Post autor: tymon_x » 30 mar 2012, 8:39

I żeby nie być górnolotny, masz dokumentacje do AVR-libc, to z niej korzystaj:
www.nongnu.org/avr-libc
AVR-libc pisze:In order for these functions to work as intended, compiler optimizations must be enabled, and the delay time must be an expression that is a known constant at compile-time. If these requirements are not met, the resulting delay will be much longer (and basically unpredictable), and applications that otherwise do not use floating-point calculations will experience severe code bloat by the floating-point library routines linked into the application.
PS.
Istnieje jeszcze coś takiego jak Timer... taki hardware "ficzer" większości uC.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 30 mar 2012, 19:28

O jednak ktoś pisze;-) nie zaglądałem bo na poczcie nie było wiadomości. Właśnie siedziałem i szukałem rozwiązania i znalazłem takie problemy na forach. Po prostu nie wiedziałem jak wygenerować taki przebieg jak poniżej i kombinowałem.. Bo jak to zrobić timerami i kontrolować szerokość impulsu..
Załączniki
telegram.gif
(9.19 KiB) Pobrany 8242 razy

Awatar użytkownika
tymon_x
-
Posty: 64
Rejestracja: 14 wrz 2010, 16:48
Lokalizacja: Gdańsk

Post autor: tymon_x » 30 mar 2012, 19:50

Dawid2379 pisze: Bo jak to zrobić timerami i kontrolować szerokość impulsu..
Timer i przerwania... ładnie i fajnie można to zrobić. Podaj jeszcze na jakim uC chcesz to zrobić, bo w uC ATMELa są proste timery (subiektywna ocena -> do kitu ). Najlepiej jakbyś chociaż miał 16-bitowy, żeby nie skakać jak głupi co w przerwanie (via prosty 8-bitowy). Zapomnij o takich głupich funkcjach jak delay, przede wszystkim marnują cenny czas uC.

Na początek pomigaj diodką z pomocą timer'a i przerwań, jak zaczynasz zabawę w uC AVR.

Awatar użytkownika
kayron
Użytkownik
Posty: 2090
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 30 mar 2012, 20:12

Ciekawa odpowiedz kolegi wyżej, proste, nie proste, zależy jaki AVR ? Ogólnie temat sterowania serwami był już wielokrotnie wałkowany na forum, nawet z opisami algorytmów sterujących opartych o Timer/y.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 30 mar 2012, 20:16

Dioda już migałem:-) Nie wiem ale widziałem dużo programów i fajne rzeczy można robić bez timerów, dużo razy tez słyszałem ze najlepiej robić to wszystko na timerach i przerwaniach he:-) Nie chce tu tez marudzić na forum wiec kombinuje i kombinuje na końcu zostaje mi forum i tak i tak. Zresztą nie potrzebuję profesjonalnego programu. Mam Tiny2313 i Mege16

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 30 mar 2012, 20:19

Program już napisałem do sterowania dwoma serwami za pomocą przycisków, opierał się na timerach i głównie zmiennych
, i szczerze bardzo ładnie się sterowało. Oczywiście przyznam ze cześć kodu jest zgapiona. Teraz chciałem pójść dalej, sterować droga radiowa serwami więc kodowanie i dekodowanie.

Awatar użytkownika
kayron
Użytkownik
Posty: 2090
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 30 mar 2012, 20:20

No Tiny2313 w zupełności wystarczy, do jak to nazwałeś fajnie profesjonalnego programu. Właśnie na takim CPU, był temat sterownia 5-cioma servami.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 30 mar 2012, 20:27

Hmm nie znalazłem, zaznaczam ze chodzi tu o przesłanie danych sterowania np. dwóch serw jednym kanałem radiowym, wiec chciałem napisać najpierw kod do nadajnika, potem martwiłbym się kodem do odbiornika. Ogólnie ma to wyglądać jak na powyższym rysunku. I nie wiedziałem jak to zrealizować na TIMERACH/PRZERWANIACH bo nawet nie miałem podglądu kogoś kodu, nic nie znalazłem, jak to zrobić aby sterować kilkoma serwami poprzez jeden kanał i kontrolować szerokość impulsu.
Ostatnio zmieniony 30 mar 2012, 20:48 przez Dawid2379, łącznie zmieniany 1 raz.

Awatar użytkownika
tymon_x
-
Posty: 64
Rejestracja: 14 wrz 2010, 16:48
Lokalizacja: Gdańsk

Post autor: tymon_x » 30 mar 2012, 20:40

kayron pisze:Ciekawa odpowiedz kolegi wyżej, proste, nie proste, zależy jaki AVR ?
A co tu niby ciekawego, dla mnie nie są ciekawe.
Dawid2379 pisze:Proszę bo nie znalazłem
Postaraj się samemu coś naskrobać, zrób Sobie schemat blokowy jakby taki program miał wyglądać. Najlepszy przyjaciel to kawałek papieru i ołówek ! Rozrysuj Sobie przebieg i zobacz co ile ma skakać i co zmieniać. Wszyscy chcą gotowce, a jak już ruszysz baniak, to nie będą Ci już potrzebne.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 30 mar 2012, 20:59

Mam myśl, ale dla podpowiedzi na jednym kanale PWM dałoby rade to zrobić?

ODPOWIEDZ