ATmega16: Rotace bitu přes všechny porty

Ahoj

Mam na vsech pinech MCU zapojeny ledky.Chci aby mi ctyri rozvicene ledky rotovali stale dokola,Takovi had ktreprojede pres vsechny porty a kdyz bude zajzdet do konce zacne se obevovat na zacatku.
Napsal sem tento ktery mi pri odkrokovavani funguje dobre.Rotaci sleduju v simulatoru od AVR studia.Ovsem kdyz sleduju ledky v aplikaci tak se chovaji jinak.Pri prechod z PortuA na Port B mi ledky na portu A zmizej ve stavu 0xf0 a pak se zacnou postupne obevovat po jedny na portu B.Pak dou dobre a kdyz to dojede na konec ledky jakoby zajedou a pak se naraz obevi na zacatku.nevim si rady.Tady je kod:

#include <avr/io.h>
#include <util/delay.h>

//Konstanta spozdeni
#define TIME 200

int main ()
{
// inicializace mcu

DDRA |= 0xFF; // port A jako vystup
DDRB |= 0xFF; // port B jako vystup
DDRC |= 0xFF; // port C jako vystup
DDRD |= 0xFF; // port D jako vystup

// Pocatecni stav ledek

PORTA |= 0x0F;
PORTB |= 0x00;
PORTC |= 0x00;
PORTD |= 0x00;

//definice promenych
char Sreg; // Slouzi k ulozeni SREGu
char pom=1;//pomocna promena pro prikaz switch,urcuje s jakym portem se rotuje

// main loop
for(;:wink:
{

Sreg=SREG;
_delay_ms (TIME);//spozdeni pro zobrazeni stavu ledek
SREG=Sreg;

switch (pom)
{

 case (1):{        	  
             PORTA *=2; //posun
             if (SREG & 0x02) ;// tady mi to detekuje zda posunujicise bity nevyjeli z rozsahu portu
             else
             { 
	            PORTB *=2;  //tady probiha presun bitu do nasledujiciho portu
                PORTB |= 0x01;
                if (PORTA==0) pom=2; //dokud se predchazejici port nevyprazdni,pak se promena zmeni a de se na dalsi port		  
             } 	  	     
	      };break;  
	 
 case (2):{        	  
             PORTB *=2;             
             if (SREG & 0x02) ;
             else
             { 
	           PORTC *=2;
               PORTC |= 0x01;           
               if (PORTB==0) pom=3; 		  
             }
          };break;  


case (3):{        	  
            PORTC *=2;         
            if (SREG & 0x02) ;
            else
            { 
	          PORTD *=2;
              PORTD |= 0x01; 
              if (PORTC==0) pom=4; 		  
            }	  	     
	     };break;  
	
	    
case (4):{        	  
            PORTD *=2;
            if (SREG & 0x02) ;
            else
            { 
	           PORTA *=2;
               PORTA |= 0x01;        
               if (PORTD==0) pom=1; 		  
            }		  	     
	     };break;  

}

}
return 0;

}

:arrow_right: administrator: přejmenováno z "ATmega16: Rotace bitu"

Moc jsem tvůj kód nestudoval, můžeš ale kdyžtak zkusit trochu jednodušší:

[code]unsigned long svetlo = 1; // 32 bit promenna

for(;:wink:
{
if(svetlo & 0x80000000)
{
// nejvyssi bit je 1 -> vysunuti 1 a na zacatek nova
svetlo <<= 1;
svetlo |= 1;
}
else
{
// nejvyssi bit je 0 -> jen posun
svetlo <<= 1;
}
PORTA = (unsigned char)svetlo;
PORTB = (unsigned char)(svetlo >> 8);
PORTC = (unsigned char)(svetlo >> 16);
PORTD = (unsigned char)(svetlo >> 24);
_delay_ms (200);
}
[/code]

Paradni elegantni reseni,rotovat rovnou 32bit promenou a pak je jen rozsoupavat na porty :smiley: Diky!!! Ale sakra!Kdyz dam rotovat 4 diody dela mi to to samy.Soft je spravne muj i tvuj.Nechapu.Pro jednu diodu to funguje taky oboje ale pro vic uz ne.Nechapu,nechapu… du to zapojeni projet rucne,budu si hrat na MCU… ale pak uz nevim…

Kdyz rucne rozsvitim napriklad prvni posledni diodu tak ok.Softwarove ne.Pro jednu diodu OK.Ale jakmile dam vic diod(4).Tak pri prechodu z PORTA na PORTB to pri stavu PORTA==0xf0 skoci rovnou do stavu PORTB==1 a had pak postupne vylejza.Pri prechodu z PORTD do PORTA je to naopak.Had postupne zmizi a pak se na PORTA obevi rovnou celej(PORTA==0x0f) a rotuje si dal pak normalne.

Megu16 tu nemám, takže to nemůžu vyzkoušet, ale není mi jasný, proč by se to mělo chovat tak zmateně, v simu to chodí dobře :frowning:. Zkus cvičně dát před světlo “volatile”, případně poladit optimalizace.

No ono se to zas tak pomatene nechova,naka pravidelnost tam je!V zapojeni asi logicka chyba teda nebude.V softu taky ne… Je mozny zeho zas nak pretezuju??taky se to chvalo divne s urcitou pravidelnosti,kdyz sem rozsvitil vsechny led bez odporu tak mi nesvitil B a D port prave!Volatile sem skousel,jak dal optimalizovat netusim…

Skusil sem to rotovat pro dva bajty akorat.Promenou sem nechal 32bit.Mezi PORTA a PORTB se to chovalo stejne spatne.Mezi PORTB a PORTC se to chovalo stejne dobre dokonce to pekne rotovalo dokola.Da se z toho neco vydedukovat??

V nastavení projektu jdou poladit optimalizace. Je tam na výběr O0-O3 a Os. O0 je bez optimalizací, O1 jsou nějaký základní, O2 je snad minimalizace velikosti kódu, O3 maximalizace rychlosti bez ohledu na kód a Os by měl bejt kompromis mezi O2 a O3.

Pokud z procesoru nesaješ víc jak 200mA/mcu, 100mA/port nebo 40mA/pin, tak by s tebou měl mluvit.

UF problem vyresen!!! Chyba v zapojeni.Mel sem vsechny 32 diod uzemenejch pres jeden odpor.To bylo ale spatne.Musel sem to rozdelit na 16 a 16.Pak uz to slape.Mel sem udelat na plosnak rovnou kazdy diode jeden odpor a bylo by po starostech!!! Nedokazu si ale porad vysvetlit proc to tak nejde.

Víc diod na 1 odpor? to si děláš srandu? V elektrotechnice máš asi opravdu trochu mezery co :slight_smile:.
Předpokládám, že nebyly všechny stejný barvy. Takže ti např. na jednom pinu svítila červená. Odpor zajistil, aby na ní byl takový úbytek, který jí vyhovuje - tedy něco kolem 2V. Jesli jsi měl na dalším portu třeba zelené, nebo jiné s vyšším napětím, tak se nemohly rozsvítit, dokud ona červená nezhasla. Když se tak stalo, pak se rozsvítily. Když dáš společný odpor pro víc diod, tak ten proud, který odporem projde se musí mezi diody rozdělit (pokud jsou na stejné napětí), s vyšším počtem diod ti tedy bude klesat jas. Proto se dává každé diodě odpor vlastní. Druhá možnost je použít obvod s proudovým výstupem pro takové věci určený. Nicméně odpory jsou jedndušší, nepotřebují vlastní napájení a snáz se routují :wink:.

Pro přístě: dávej pls ke svým výtvorům i schéma :wink:

NE sou vsechny stejny a navic potrebuju vzdycky jen ctyry,takze s poklesem jasu si hlavu nelamu!Schema uz sem tu resil i stebou nedavno,tak sem myslel ze si budes pamatovat:) Nechapu proc procesoru vadilo ze to melo spolecnej jeden odpor zemnici.Ted sem tom rozedelil ze kazdej port ma svuj zemnici odpor jeden a slape to!Priste uz dam ale poctive ke kazdy ledce odpor slibuju :slight_smile: