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

[atmega8][c][93c86] pętla się nie kończy

Master Dragon 28 Lis 2009 10:52 1572 21
  • #1 7318336
    Master Dragon
    Poziom 12  
    Mam problem mianowicie korzystając z biblioteki dołączonej poniżej próbuję zapisać kilka sektorów jeden po drugim bo dane są troszeczkę długawe.

    Robię to przez pętle for o tak (przykład jeśli chodzi o pętle)
    
    ee93_we();
    for(i=0;i<=100;i++)
    {
        ee93_write(i,0x00); //zapisuje zerami
    }
    ee93_wd();
    


    i po takiej pętli program zeruje mi cały eeprom
    próbowałem już w pętlach for, do while, while i zawsze tak samo a jak ręcznie wpisze zamiast (i) kilka adresów to zapisze je normalnie.

    
    ee93_we();
    ee93_write(0,0x00); //zapisuje zerami
    ee93_write(1,0x00); 
    ee93_write(2,0x00);
    ...
    ee93_write(100,0x00); 
    ee93_wd();
    



    I nie wiem co jest przyczyną, dodam że używam WINAVR.
  • #2 7318442
    __Maciek__
    Poziom 20  
    IMHO jest ok ale spróbuj.

    for(i=0;i<101;i++) { } ;
  • #3 7318451
    Master Dragon
    Poziom 12  
    Też nie działa. Zepnij dwie atmegi przez microwire i popatrz co się dzieje jak wysyłają do siebie dane.
  • #4 7318461
    __Maciek__
    Poziom 20  
    no to jeszcze inaczej .... Zamiast
    ee93_write(i,0x00); //zapisuje zerami
    wrzuć np zmianę stanu leda .... i oczekiwanie .... i zmniejsz ... liczę kroków ...

    PORTX ^= _BV(Y) ;
    _delay_ms(500);

    Nie zniszczysz EEproma próbami, i sprawdzisz czy problem faktycznie leży po stronie pętli. ( wg. mnie nie ) .

    Nie napisałeś na jakiej zmiennej i pracujesz .... możesz spróbować zastosować zmienną lokalną o ile tego nie robisz ....

    
    /* Beep */ 
    
    #include "beep.h"
    #include <avr/io.h>
    #include <util/delay.h>
    
    void beep(unsigned int cycles, unsigned int freq) 
    {
    	unsigned int i,j;
    	for(i=0;i<cycles;i++)
    	{
    	buzer_port |= _BV(buzer_nr);
    	for(j=0;j<freq;j++){_delay_us(1);};
    	buzer_port &= ~_BV(buzer_nr);
    	for(j=0;j<freq;j++){_delay_us(1);};
    	}
    	return;
    }
  • #5 7318479
    Master Dragon
    Poziom 12  
    Mam to zrobione tak
    
    unsigned short int i; //ponieważ adress w tym eepromie jest 11bitowy [lokalna]
    
    if(!(PINC & _BV(6))) //sprawdzenie czy przycisk wciśnięty
    {
      _delay_ms(30);
      if(!(PINC & _BV(6))) //sprawdzenie czy przycisk wciśnięty
      {
       PORTB &=~ _BV(5) //zgaszenie diody
       ee93_we();
           for(i=0;i<=100;i++)
          {
              ee93_write(i,0x00)
          }
       ee93_wd(); 
       PORTB |= _BV(5) //oświecenie diody
      }
    }
    


    Jak się wkurzę to chyba zepnę dwie atmegi rzeby odebrać te dane i sprawdzić co tam lata.
  • #6 7318564
    __Maciek__
    Poziom 20  
    Jesteś pewien tego kodu ?? Wydaje mi się że nie jest on poprawny.
    Sporo zależy od stanu innych pinów na porcie C.
    if(!(PINC & _BV(6))) //sprawdzenie czy przycisk wciśnięty 


    Ja bym to zrobił tak :

    
    
    // bit_is_clear(PINX,NR);
    // bit_is_set(PINX,Nr);
    
    if bit_is_clear(PINC,6) {
      _delay_ms(30);
      if bit_is_clear(PINC,6) {
      PORTB &=~_BV(5);
      ee93_we();
          unsigned int i; // może być nawet char bo interesujący cię zakres to 100,
                             // ale jeśli funkcja wymaga int więc może być konieczne rzutowanie typów.
           for(i=0;i<=100;i++)
          {
              ee93_write(i,0x00) ;
          }
      ee93_wd();
      PORTB |= _BV(5) ;
     }
    } 


    Pomijając fakt iż to co wkleiłeś nie ma średników wszędzie tam gdzie potrzeba ...
  • #7 7318697
    mirekk36
    Poziom 42  
    Witam,

    Ja bym na twoim miejscu zrobił prosty test, który na pewno dużo by ci wyjaśnił i mógłbyś wyciągnąć wnioski co robisz nie tak:

    ee93_we(); 
    for(i=0;i<100;i++) 
    { 
        ee93_write(i,i); 
    } 
    ee93_wd();


    a po tym sprawdź sobie jak wygląda zawartość pamięci ;) nie sądzisz, że to dużo ci powie? Wg tego powinieneś mieć zapisane po kolei 100 komórek i po kolei będą w nim liczby od 0 do 100 prawda ? ..... a co będzie w kolejnych? - sam zobaczysz ;)
  • #8 7319666
    Master Dragon
    Poziom 12  
    mirekk36 zrobiłem tak jak mówisz i wysłałem jeszcze przez uart zmienne i pokazało to co jest określone w pętli czyli od 0 do 100 a w pamięci zapisał wszytko pętlami od 0 do 100. __Maciek__ to że średników brakuje to moje nie dopatrzenie bo przepisywałem. I nie wiem ćoś jest według mnie pamięć odbiera funkcje zapisz wszystko ale dlaczego się tak dzieje. A co do poleceń bit_is_set chyba to jest to samo co PORTX & _BV(X) bo to akurat wyczytałem z informacji o makro _BV a bit_is_clear to jest (!(PORTX & _BV(X)))
  • #9 7320282
    mirekk36
    Poziom 42  
    Tak wracając do poprzedniej kwestii, czy będzie taki kod:

    if bit_is_clear(PINC,6)


    czy taki

    if(!(PINC & _BV(6)))


    czy taki

    if( !( PINC & (1<<6) ) )


    to zawsze będzie to dobrze napisane i tak samo zadziała ;) więc nie mart wię tym.

    A test z zapisem od 0 do 100 chyba sporo wyjaśnił ;) bo:

    1. jak widzisz pętla się kończy ;) - to chyba jasny wniosek czyli wszystko z nią jest ok

    2. za to jak widać pętla wykonuje się ogromną i co gorsza niekontrolowaną ilość razy.

    Więc błędu musisz szukać dokładnie poza pętlą tzn wynika z tego, że kod wywołuje ją wiele razy
  • #10 7320527
    __Maciek__
    Poziom 20  
    Z tego wynika że problemem może być właśnie kod wymieniony przez kolegę mirekk36,
    Od siebie dodam że też miałem kiedyś podobny problem, i po zmianie z
    if( !( PINC & (1<<6) ) )

    na
    if bit_is_clear(PINC,6)

    wszystko zaczęło funkcjonować jak należy. ( pomimo iż jedno i drugie to to samo. )
    Źródła problemu nie znam. Wiem tylko że wtedy zmiana pomogła, więcej nie wnikałem.

    Oczywiście może być jeszcze pomyłka w kwestii Hardware - tj błędna interpretacja naciśnięcia przycisku - wtedy wystarczy zmienić warunek.
  • #11 7320705
    mirekk36
    Poziom 42  
    __Maciek__ ---> proponuję ci w takich przypadkach gdy masz wątpliwości czy różni się kod

    if( !( PINC & (1<<6) ) ) lub if(!(PINC & _BV(6)))
    od

    if bit_is_clear(PINC,6)


    zajrzeć do kodu wynikowego w asemblerze - plik *.lss po kompilacji i zobaczyć sobie, że obydiw instrukcje dokładnie tak samo się kompilują , albo zajrzeć do makra _BV i zobaczyć co do czego ono jest "rozwijane" przez kompilator. Nie mówię tego po to żeby się czepiać - tak tylko podpowiadam - bo to raczej nie było twoim problemem.
  • #12 7320922
    Master Dragon
    Poziom 12  
    I wracam do punktu wyjścia bo w takim przypadku widzę że nie którzy nie zajrzeli nawet w biblioteki przypuszczałem że błąd może nie leżeć po stronie pętli i dla tego zamieściłem te biblioteki.

    A tak w ogóle jak kod może wywołać ta pętle skoro ona wywołuję to funkcje a ta wychodzi jedynie po za swoje ramy do peli delay i przesłania bitu a z stamtąd już donikąd. Albo za mało siedzę w c albo coś nie rozumiem.

    Panowie mam znalazłem:D:D:D:D:D:D:D:D gdzie jest ustawiony adres jako unsigned char bo cykl powtarza się co 255 0xFF może pomożecie to znaleźć bo ja już przeglądam 7 raz i dalej nie widze.
  • #13 7321006
    mirekk36
    Poziom 42  
    Master Dragon napisał:
    ....
    A tak w ogóle jak kod może wywołać ta pętle skoro ona wywołuję to funkcje a ta wychodzi jedynie po za swoje ramy do peli delay i przesłania bitu a z stamtąd już donikąd. Albo za mało siedzę w c albo coś nie rozumiem


    Sorki ale czytając to powyżej to chyba po troszku i jedno i drugie. Ale nie martw się każdy na początku miewa różne problemy ;)

    Zamiast podawać tu do jakiejś analizy jakieś tam biblioteki - pokaż lepiej cały fragment swojego kodu jak ty to robisz i jak korzystasz z tych bibliotek. I nie pisz, że twój kod nie wywołuje tej pętli - bo chyba sam się już zapętlasz.

    Pokaż swoją funkcję main i co w niej robisz po kolei jeśli chodzi o to programowanie pamięci - to może uda się podpowiedzieć ci gdzie robisz tego "byka"
  • #14 7321090
    Master Dragon
    Poziom 12  
    Proszę cały main.c
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include "93eeprom.h"
    #include "uart.h"
    
    int main(void)
    {
     	unsigned short int i;
    	
    	DDRC |= _BV(5);//definicja portu dla diody
    	PORTC &=~ _BV(5);//definicja portu dla diody
    	DDRD &=~ (_BV(6)|_BV(5)|_BV(7));//definicja klawiszy
    	PORTD |= (_BV(6)|_BV(5)|_BV(7));//definicja klawiszy
    	
    	UART_init();		//inicjacja usart
    	
    	eeprom_93_init(); 	//inicjacja portu
    	
    	while(ee93_chip != 11)
    	{
    		PORTC ^= _BV(5);
    		_delay_ms(1000);
    	}
    	
    	PORTC |= _BV(5); //zapalenie diody
    	while(ee93_chip == 11)
    	{
    		if(!(PIND & _BV(6)))
    		{
    			_delay_ms(30);
    			if(!(PIND & _BV(6)))
    			{
    				PORTC &=~ _BV(5);
    				ee93_we();
    				for(i=0;i<=100;i++)
    				{
    					ee93_write(i,0x00);
    				}
    			}
    			ee93_wd();
    			PORTC |= _BV(5);
    		}
    	
    		if(!(PIND & _BV(5)))
    		{
    			_delay_ms(30);
    			if(!(PIND & _BV(5)))
    			{
    				PORTC &=~ _BV(5);
    				for(i=0;i<=0x7FF;i++)
    				{
    					UART_putchar(ee93_read(i));
    				}
    			}
    			PORTC |= _BV(5);
    		}
    		
    		if(!(PIND & _BV(7)))
    		{
    			_delay_ms(30);
    			if(!(PIND & _BV(7)))
    			{
    				PORTC &=~ _BV(5);
    				ee93_we();
    				for(i=0;i<=0x7FF;i++)
    				{
    				ee93_write(i,0x31);
    				}
    			}
    			ee93_wd();
    			PORTC |= _BV(5);
    		}
    	}
    }
    
  • #15 7321153
    michalko12
    Specjalista - Mikrokontrolery
    A na jakiej podstawie twierdzisz że pętla nie kończy się?

    To
    DDRD &=~ _BV(6)|_BV(5)|_BV(7);  //definicja klawiszy 

    zmień na
    DDRD &=~ (_BV(6)|_BV(5)|_BV(7));  //definicja klawiszy

    bo teraz masz
    DDRD &=(~ _BV(6)) | _BV(5) | _BV(7);  //definicja klawiszy 
  • #16 7321172
    Master Dragon
    Poziom 12  
    Może źle się wyraziłem raczej to było założenie. Ale po wyniku odczytu z eeprom
    wygląda to tak że kasuje bity od 0 do 100 dochodzi do 255 i kasuje odnowa. wiec problem siedzi w zmiennych tylko trzeba to terazznaleść.
  • #17 7321236
    michalko12
    Specjalista - Mikrokontrolery
    Master Dragon napisał:
    Może źle się wyraziłem raczej to było założenie. Ale po wyniku odczytu z eeprom
    wygląda to tak że kasuje bity od 0 do 100 dochodzi do 255 i kasuje odnowa. wiec problem siedzi w zmiennych tylko trzeba to terazznaleść.


    Nie wiem, nic nie mogę zrozumiec z tego co piszesz, chyba już późno.

    Bajty nie bity, kasowanie to ustawianie na 0xFF, a tego
    Cytat:
    od 0 do 100 dochodzi do 255 i kasuje odnowa
    całkowicie nie rozumiem.
  • #18 7321258
    Master Dragon
    Poziom 12  
    To wytłumaczę to tak. Tak jak w pętli jesst to wskazane zapisuje bity od 0 do 100 potem zostawia pamięć nie ruszoną do 255 i znowu zapisuje 100 bajtów i znowu do 255 nie tknięte i tak w kółko aż do końca pamięci.
  • #19 7321375
    mirekk36
    Poziom 42  
    michalko12 napisał:

    Nie wiem, nic nie mogę zrozumiec z tego co piszesz, chyba już późno.


    nie , nie za bardzo można czasem zrozumieć autora dlatego, nie dlatego że jest późno tylko dlatego, że coś nam pan autor delikatnie mówiąc "dziwnie pisze" ;) bez urazy

    no bo po raz kolejny tłumacząc pisze znowu:

    Master Dragon napisał:
    Tak jak w pętli jesst to wskazane zapisuje bity od 0 do 100 potem zostawia pamięć nie ruszoną do 255


    żeby za chwilę npisać:

    Master Dragon napisał:
    ...... i znowu zapisuje 100 bajtów i znowu do 255 nie tknięte i tak w kółko aż do końca pamięci.


    no ale dobra - teoretycznie można uznać to za literówkę - tyle tylko, że jeśli kolega autor tak samo podchodzi do pisania tego programu jak sposobu opisywania problemu to zapewne nie zwraca uwagi w ogóle na warningi podczas kompilacji. Robisz jakieś mega dziwne kombinacje ze zmienną i w pętli nadając jej różnorodne typy brane z sufitu a tymczasem jak zajrzy się już do tej twojej biblioteki to widać w nagłówku funkcji jak BYK, że zmienna określająca adres powinna być 16-to bitowa.

    u08 ee93_write(u16 address,u08 datawrite)


    czy nie widzisz typu u16 ??? czyli inaczej zapisując uint16_t ????

    nie mówię, że to rozwiąże twój problem bo na pewno następuje niejawne i poprawne rzutowanie typów przez kompilator w efekcie końcowym ale biorąc pod uwagę słowa z nagłówka tego pliku z funkcjami:

    Cytat:
    // NOTE: This code is currently below version 1.0, and therefore is considered
    // to be lacking in some functionality or documentation, or may not be fully
    // tested
    . Nonetheless, you can expect most functions to work.


    to nie chcąc się wdrażać teraz w analizę ew błędów tych bibliotek czy też tego co nie zostało przetestowane - to choinka wie co w tym całym kodzie się dzieje.

    Podejrzewam, że szybciej byś sam napisał sobie swoje proste funkcje do obsługi tej pamięci na podstawie jej PDF'a.

    Zresztą ta cała funkcja ee93_write jest jakaś deczko dziwna - choć może się mylę bo naprawdę nie chce mi się teraz dogłębnie analizować sposobu zapisu do tej pamięci.

    Jednak wynika z niej jasno, że w zasadzie skoro zwraca parametr, który może być albo ZERO albo JEDEN to wynika z tego, że i ty powinieneś ten parametr sprawdzać przy jej wywołaniu żeby wiedzieć czy nie nastąpił jakiś zdaje się dziwny TimeOut gdy zwracane jest ZERO.
  • Pomocny post
    #20 7321739
    michalko12
    Specjalista - Mikrokontrolery
    Master Dragon napisał:
    To wytłumaczę to tak. Tak jak w pętli jesst to wskazane zapisuje bity od 0 do 100 potem zostawia pamięć nie ruszoną do 255 i znowu zapisuje 100 bajtów i znowu do 255 nie tknięte i tak w kółko aż do końca pamięci.


    Podmień te dwie funkcje z tej biblioteki. Błędem w tej bibliotece jest używanie makr "bit_is_set()" do sprawdzania stanu bitu, ponieważ makro jest przeznaczone do sprawdzania stanu bitów w 8 bitowych rejestrach specjalnych.

    Poważnie, pomyśl o napisaniu tej biblioteki od początku bo ta ma więcej takich przypadłości i jest napisana niezbyt optymalnie. Jest bo jest i to z błędami.

    u08	ee93_read(u16 address)
    {
    	u08 data;
    	ee93_cs_h;
    	ee93_mosi_h;
    	clock();
    	clock();
    	ee93_mosi_l;
    	clock();
    	address <<= 16-ee93_chip;	
    
    	for(u08 x = 0; x < ee93_chip ;  x++)
    	{
    		if(address & 0x8000)		
    			ee93_mosi_h;
    		else
    			ee93_mosi_l;
    
    		address <<= 1;
    
    		if(x < (ee93_chip-1))
    			clock();		
    		else
    		{
    			delay;
    			ee93_sck_h;
    			delay;
    			if(bit_is_set(ee93_pin,ee93_miso))
    				ee93_error = 1;
    			ee93_sck_l;
    			delay;
    		}
    	}
    	data = ee93_r_byte();
    	ee93_cs_l;
    
    	return data;
    
    }

    /////////////////////////////////////////////////////////////////////////////
    u08 ee93_write(u16 address,u08 datawrite)
    {
    	unsigned long loop=0;
    	ee93_cs_h;
    	ee93_mosi_h;
    	clock();
    	ee93_mosi_l;
    	clock();
    	ee93_mosi_h;
    	clock();
    	address <<= 16-ee93_chip;	
    
    	for(u08 x = 0; x < ee93_chip ;  x++)
    	{
    		if(address & 0x8000)		
    			ee93_mosi_h;
    		else
    			ee93_mosi_l;
    
    		address <<= 1;
    		clock();		
    	}
    	ee93_w_byte(datawrite);
    	ee93_cs_l;
    
    	delay;
    	ee93_cs_h;
    	while(bit_is_clear(ee93_pin,ee93_miso))
    	{
    		loop++;
    		if(loop == 200000)
    			return 0;
    	}
    	ee93_cs_l;	
    
    	return 1;
    }
  • Pomocny post
    #21 7321837
    mirekk36
    Poziom 42  
    Wg mnie, w tej funkcji write , szczególnie dziwny, na pierwszy rzut oka jest ten fragment

       ee93_cs_h; 
       while(bit_is_clear(ee93_pin,ee93_miso)) 
       { 
          loop++; 
          if(loop == 200000) 
             return 0; 
       } 
       ee93_cs_l;  


    ta funkcja może się bardzo różnie zachowywać gdy bedzie działać np na procku z taktowaniem 1MHz albo na procku z taktowaniem 16MHz.

    w pierwszym przypadku uzyskujemy timeout czyli return 0 po czasie ok 200ms a w drugim przypadku czas ok 12ms !!! (no, chyba, że ten czas jest zawsze krótszy niż powiedzmy 10ms to ok - ale mało to jakoś wszystko zoptymalizowane i przemyślane)

    trzeba by więc sprawdzić jaki czas jest potrzebny wg noty PDF tej pamięci na zapis. Bo wygląda to tak jakby funkcja została napisana i dostosowana do procka o jakiejś tam określonej wartości taktowania (wskazuje na to ta stała 200000 ) a nic nie jest o tym wspomniane w części opisowej na górze pliku - więc drogi użytkowniku tych funkcji - martw się sam i sam rozwiązuj problemy jeśli coś nie zadziała
  • #22 7322253
    Master Dragon
    Poziom 12  
    No wreszcie panowie oto mi chodziło co w tej bibliotece autor nie prze widział czyli napisał bibliotekę i przetestował ją na chip od 93C46 do 93C56 a nie sprawdził pozostałych bo te które wypisałem są adresowane 7 i 8 bitow.

    A co do bitów i bajtów to literówka zawsze miałem z tym problem przekręcałem.

    Dziękuje panowie za wszystko teraz już wiem że wystarczy poprawić element wysyłania adresu. A tak najbardziej dziękuje tobie mirekk36, michalko12.

    :D:D:D:D:D:D:D:D:D:D:D:D:D:D

    Temat zamknięty chyba że ktoś chce jeszcze coś dodać
REKLAMA