PD = PA i en ATMega32, C

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

PD = PA i en ATMega32, C

Inlägg av Virr3 »

Hejsan.

Jag skulle vilja ha lite hjälp med lite C programering till min ATMega32. Jag tror inte att detta är något speciellt svårt problem för någon av er. Men iallafall.

Det jag vill göra för det första är heltenkelt få samma utsignal på porta som insignalen på port D. detta är jag lite problem med fakiskt. Det tycker ni väl att det är ingen match. Det kan väl vem som helst göra? jag tyckte så med, tills de att jag provat nu ett tag. detta gör mig väldigt förvirrad. Först tänkte jag simpelt bara PORTD=PORTA i en while loop. Men icke sa nicke. hepp tänkte jag. Sen satte jag ett 10k motstånd mot jord som pulldown, för att utgången inte skulle bli "flytande"(?).

Men alltså, inget av detta fungerar alls.

Jag undrar lite varför? vad är det som jag gör galet? behöver nästan inte skriva koden eller? detär som jag skrev innan PORTD=PORTA; i en while.

Har satt Porta som utgång (DDRA = 0xFF;) och sen PortD som ingång (DDRD = 0x00;)

Skulle vara jättesnällt ifall någon berättade för mig hur det funkar, och varför det inte funkar som jag gör nu :)
Användarvisningsbild
karlstedt
EF Sponsor
Inlägg: 966
Blev medlem: 14 oktober 2003, 16:55:23
Ort: Lund
Kontakt:

Inlägg av karlstedt »

PORTx = PINx;

EDIT: Då du läser av en port så måste du läsa PINx, inte PORTx.
Sen måste du såklart initiera portarna korrekt.
Senast redigerad av karlstedt 15 februari 2006, 16:56:30, redigerad totalt 2 gånger.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jag antar att du har ett program som i enkelthet ser ut som följer:

Kod: Markera allt

void main(void)
  {
  DDRA = 0xFF; // Blir då input
  DDRD = 0x00; // Blir då output
  while(1)
    {
    PORTD = PORTA;
    }
  }
Om det inte fungerar får du kanske testa att byta "PORTD = PORTA;" mot "PORTD++;", detta vill få den att räkna upp som en idiot, har du ett oscilloskop kan du se pulserna.
Lägger du in en räkna-loop ("for unsigned int Counter = 0;Counter < 65500;Counter++);") kan du sänka hastigheten en del.

På detta sätt kan du kolla att du verkligen har kontroll över PORTD och att den biten fungerar. Fungerar det inte har du ett problem med PORTD och fungerar det får du kolla PORTA och vad som får den att strejka.....ska man stänga av AD-ingångar osv.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> PORTD=PORTA
> PORTA som utgång... PORTD som ingång

Är det inte något som är fel här ?
Virror
Inlägg: 1025
Blev medlem: 28 april 2004, 11:03:14
Ort: Göteborg
Kontakt:

Inlägg av Virror »

Borde väll vara så här?

Kod: Markera allt

void main(void) 
  { 
  DDRA = 0xFF; // Blir då input 
  DDRD = 0x00; // Blir då output 
  while(1) 
    { 
    PORTD = PINA; 
    } 
  } 
Användarvisningsbild
björn
EF Sponsor
Inlägg: 2570
Blev medlem: 29 mars 2004, 23:09:55

Inlägg av björn »

PORTD=PORTA; ska fungera, precis som icecap skrev.
Användarvisningsbild
björn
EF Sponsor
Inlägg: 2570
Blev medlem: 29 mars 2004, 23:09:55

Inlägg av björn »

sodjan skrev:> PORTD=PORTA
> PORTA som utgång... PORTD som ingång

Är det inte något som är fel här ?
Ser inte helt rätt ut nej :) kan ju inte sätta ingång=utgång...
monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Inlägg av monstrum »

Ja visst. PORTD = PORTA fungerar utmärkt. Men man läser inte det fysiska värdet på port A, utan snarare var man innan har satt den till. Så PORTD = PINA ska det vara.

Sen behöver du inte använda externa motstånd. Sätt bara PORTD=0xff så drar du igång interna pull-ups på ingångarna.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

Åh, Tackar ödmjukast :)

Så skjönt att få det att fungera nu:) Felet va de med PORT och PIN.

Ledsen, hade skrivit fel där sodjan, skulle givet vis vara tvärt om.

men, tack allasammans för all hjälp.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

Nu tänkte jag göra så att försöka få avr:en att räkna tio pulser och sen ska en lampa lysa sen ska tio pulser till komma och då ska lampan släckas osv.

detta funkade givet vis inte.

koden jag gjorde ser ut såhär:

Kod: Markera allt

#include <avr/io.h>

uint8_t counter = 0;
int main(void)
   {

   PORTA = 0x00;
   DDRA  = 0xFF;
   
   DDRD  = 0x00;
   PORTD = 0x00;
   
   PORTA = 0x00;
	while(1)
		{
		
			if(PIND ^=  _BV(PD1))
			{
				counter++;
			}
			if(counter == 10)
			{
				PORTA=0xFF;
			}
			if(counter == 20)
			{
				PORTA=0x00;
				counter=0;
			}
		
		}

}
Resultatet blir att lampan lyser hela tiden. Det är väl ingenting som begränsar hur långa/korta pulserna får/måste vara?

Kollar man riktigt noga kan man se att lysdioden blinkar lite medans jag skickar ut några pulser, men då får man kolla väldigt noga.

Någon som kan visa vart felet är? varför det blir fel och hur jag ska göra för att få det rätt.
monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Inlägg av monstrum »

Hur skickar du ut pulserna? Om det är med något mekaniskt så kommer du får bra många fler pulser än en enstaka eftersom kontakter alltid studsar.

Dessutom finns det inget som begränsar så att du bara räknar varje puls en gång. Tänk på att processorn hinner räkna ganska långt även under väldigt korta tider.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

hittils har det bara varit mänskig faktor som spelat in.

Men, jag tycker ändå att den någon gång ska sluta lysa. Oddsen för att den ska lysa nästan hela tiden som den gör nu är ganska låga...

men, ska testa att köra 50hz och se vad som händer...
Användarvisningsbild
karlstedt
EF Sponsor
Inlägg: 966
Blev medlem: 14 oktober 2003, 16:55:23
Ort: Lund
Kontakt:

Inlägg av karlstedt »

Kan du förklara med ord vad du tror att denna rad gör?

Kod: Markera allt

if(PIND ^=  _BV(PD1)) 
monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Inlägg av monstrum »

Ja, det är galet.

Du menar troligtvis:

Kod: Markera allt

if( PIND != _BV(PD1) )
Alltså, påståendet är sant om bit 1 på pinD är noll.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

Om jag inte är fel ute så betyder "(PIND ^= _BV(PD1)" byta värde på portd pi1.

Jag vet inte om det ska vara så, eller om det går att använda den i en if-sats så som jag gör. Men, jag kommer inte på något bättre sätt att lösa det på.

Alltså, det jag vill göra är att räkna pulser, tex. vid tio pulser lyser lampan, efter nästa tio så är den släkt.

Testat med 50hz. ingen större inverkan. lysdioden lös. Blinkade möjligtvis väldigt väldigt snabbt.
Skriv svar