Sida 1 av 2

PD = PA i en ATMega32, C

Postat: 15 februari 2006, 16:36:37
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 :)

Postat: 15 februari 2006, 16:48:04
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.

Postat: 15 februari 2006, 16:52:53
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.

Postat: 15 februari 2006, 16:53:38
av sodjan
> PORTD=PORTA
> PORTA som utgång... PORTD som ingång

Är det inte något som är fel här ?

Postat: 15 februari 2006, 17:36:52
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; 
    } 
  } 

Postat: 15 februari 2006, 21:08:03
av björn
PORTD=PORTA; ska fungera, precis som icecap skrev.

Postat: 15 februari 2006, 21:11:37
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...

Postat: 15 februari 2006, 21:14:52
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.

Postat: 16 februari 2006, 00:57:14
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.

Postat: 16 februari 2006, 23:25:39
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.

Postat: 16 februari 2006, 23:31:36
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.

Postat: 16 februari 2006, 23:34:55
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...

Postat: 16 februari 2006, 23:44:14
av karlstedt
Kan du förklara med ord vad du tror att denna rad gör?

Kod: Markera allt

if(PIND ^=  _BV(PD1)) 

Postat: 16 februari 2006, 23:47:35
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.

Postat: 16 februari 2006, 23:53:26
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.