Dag mensen!!

Ik heb een probleem en ik hoop dat jullie mij daar mij kunnen helpen. Ik ben zoals jullie al aan de title kunnen zien een atmega32L aan het programmeren. De bedoeling van de atmel is dat ie wat sensoren in gaat lezen die vervolgens de waardes naar de computer door sturen (in vorm van letters).
Maar wat het programma niet doet is het reageren op de ingangen :@
Misschien een foutej in mn programma??

Programma:
-----------------------------------------------------------
#include <mega32.h>
#include <stdio.h>
#include <delay.h>

void main(void)
{

// Input/Output Ports initialization
// Port A initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
PORTA=0x00;
DDRA=0x80;

// Port B initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=P State1=P State2=P State3=P State4=P State5=P State6=P State7=P
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
GICR|=0x00;
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;

while (1)
{
delay_ms(100);

// Hier worden de ingangen voor de sensors benoemd en de bij behorende letters

if(PORTA == 0x01) //Geeft letter m
putchar(0x6D);

else if(PORTA == 0x02) //Geeft letter n
putchar(0x6E);

else if(PORTA == 0x04) //Geeft letter o
putchar(0x6F);

else if(PORTA == 0x08) //Geeft letter p
putchar(0x70);

// Hier wordt de uitgang voor de klep gedefinieerd

if (UDR !=0)
{
PORTA |= 0x80;
delay_ms(2000);
PORTA &= 0x7F; //0x80^0xFF;
UDR==0;
}
}
}

-----------------------------------------------------------

De communicatie is goed! En dat laatste gedeelte van het programma werk wel (het inlezen van een willekeurige karakter).

Alvast bedankt voor jullie reacties!!

je zegt dus dat dit stukje niet goed werkt


if(PORTA == 0x01) //Geeft letter m 
putchar(0x6D); 

else if(PORTA == 0x02) //Geeft letter n 
putchar(0x6E); 

else if(PORTA == 0x04) //Geeft letter o 
putchar(0x6F); 

else if(PORTA == 0x08) //Geeft letter p 
putchar(0x70); 

ik weet niet precies wat de bedoeling is van die if-statements. maar je controleerd hier dus de hele waarde van PORTA en niet een individueele bit.
if(PORTA == 0x02) is dus if(PORTA == 00000010)
misschien wil je wel dit if(PORTA == xxxxxx1x). klopt het wel, dan zit het denk ik in je putchar functie. die moet je hier dan ff posten.

verder moet UDR==0; (laaste regel) dit zijn: UDR = 0;
maar aangezien dat al werkt zal het wel niet uitmaken.


if(PORTA == 0x01) //Geeft letter m 
putchar(0x6D); 

else if(PORTA == 0x02) //Geeft letter n 
putchar(0x6E); 

else if(PORTA == 0x04) //Geeft letter o 
putchar(0x6F); 

else if(PORTA == 0x08) //Geeft letter p 
putchar(0x70); 

Het zal zo ook niet lukken om meerdere knoppen tegelijk in te drukken, die dan ook gedetecteerd worden. Daarvoor zou je losse if opdrachten moeten geven.

Als je een poort wilt inlezen moet je wel het input register gebruiken. Dus in dit geval PINA i.p.v. PORTA.

Verder zie ik je onnodig veel zaken met 0 initializeren. Zoals bijv. de timers. Dat is niet nodig, want die registers staan standaard al op 0.

Op 23 december 2005 18:08:12 schreef Marcel:
Als je een poort wilt inlezen moet je wel het input register gebruiken. Dus in dit geval PINA i.p.v. PORTA.

Verder zie ik je onnodig veel zaken met 0 initializeren. Zoals bijv. de timers. Dat is niet nodig, want die registers staan standaard al op 0.

ja natuurlijk |:-( stom, je moet het PINA register gebruiken op een poort in te lezen.

ok om maar ff een voorbeeldje te posten dan:

Om pin A0 in te lezen:
if (PINA & 0x01)
{
//doe code
}

Verder nog een tip:
Als je een poort gaat initialiseren, initialiseer dan eerst de data direction en pas daarna een waarde naar het register schrijven. Dus:
DDRA = 0x80;
PORTA = 0x00;
Dit is een stuk veiliger :)

Op 23 december 2005 20:14:57 schreef Zundapp47:
ok om maar ff een voorbeeldje te posten dan:

Om pin A0 in te lezen:
if (PINA & 0x01)
{
//doe code
}

Verder nog een tip:
Als je een poort gaat initialiseren, initialiseer dan eerst de data direction en pas daarna een waarde naar het register schrijven. Dus:
DDRA = 0x80;
PORTA = 0x00;
Dit is een stuk veiliger :)

Bedank voor je/jullie reacties! Ik ben er inmiddels achter wat het probleem was.. De ingangen die "zweefden". Heb dit opgelost door deze ingangen met een vrij hoge weerstand aan ground te koppelen. Ben hier achter gekomen door met mn multimeter te gaan meten(heeft een hoge inwendige weerstand). Tevens gelijk de code aangepast om alleen naar een ingang per keer te kijken en niet naar de hele Akant.

Nieuwe code voor inlezen ingang:
if((PINA & 0x01) != 0)

Maar ik had nog wel even een vraagje...
Als ik de uitgang voor de tweede keer hoog heb gemaakt door een karakter te sturen blijft de uitgang schommelen tussen de 3 en 5 volt. Na een reset van de controller doet ie het wel weer maar heb het liever dat het automatisch gaat. Ik gebruik de volgende code daarvoor:

if (UDR !=0)
{
PORTA |= 0x80;
delay_ms(2000);
PORTA &= 0x7F; //0x80^0xFF; // Alles met een 1 vermedigvuldigen behalve het laatste bitje(ook een reset)
UDR==0;

Ik denk dat de UDR==0 geen zin heeft of niet werkt. Ik wil dus dat het data register(UDR) weer gewist wordt. Iemand nog goeie ideeen?

Hoi Elmer,

Als je nog ooit vaker last hebt van zwevende ingangen kun je ook proberen de interne pull-up weerstanden van de atmega32 te activeren (poort als input defineren en dan hoog maken, bijv DDRA=0x00; PORTA=0xFF; )

Ik snap alleen niet echt wat je met deze code doet:
if (UDR !=0)
{
PORTA |= 0x80;
delay_ms(2000);
PORTA &= 0x7F;
UDR==0;
}

Zoiezo werkt UDR==0; nooit want dit is een statement en geen commando. Het zou dan UDR = 0; moeten zijn.
Maar als je de UART gebruikt, word volgens mij meteen na het verzenden van een karakter dit UDR register gecleared. Weet ik niet zeker hoor maar ik heb het register nog nooit hoeven leeg te maken.

Welke uitgang gaat schommelen tussen de 3-5V? Is dat poort A7? Of doet je UART raar?

Op 24 december 2005 18:12:20 schreef Zundapp47:
Hoi Elmer,

Als je nog ooit vaker last hebt van zwevende ingangen kun je ook proberen de interne pull-up weerstanden van de atmega32 te activeren (poort als input defineren en dan hoog maken, bijv DDRA=0x00; PORTA=0xFF; )

Ik snap alleen niet echt wat je met deze code doet:
if (UDR !=0)
{
PORTA |= 0x80;
delay_ms(2000);
PORTA &= 0x7F;
UDR==0;
}

Zoiezo werkt UDR==0; nooit want dit is een statement en geen commando. Het zou dan UDR = 0; moeten zijn.
Maar als je de UART gebruikt, word volgens mij meteen na het verzenden van een karakter dit UDR register gecleared. Weet ik niet zeker hoor maar ik heb het register nog nooit hoeven leeg te maken.

Welke uitgang gaat schommelen tussen de 3-5V? Is dat poort A7? Of doet je UART raar?

Dit laaste stukje code werkt niet helemaal lekker. Wat het doet is een uitgang hoogmaken voor 2 sec (als de UDR ongelijk is aan 0) en vervolgens resetten. Als ik voor de eerste keer een karakter verzend is er niks aan de hand. Maar als ik voor de 2e keer een karakter verzend blijft de uitgang hoog!! Het is echt een programma foutje. Ik ben nog niet echt ervaren hiermee dus als iemand een goed iedee heeft...

De code:

while (1)
{

// Hier worden de ingangen voor de sensors benoemd

if((PINA & 0x01) != 0) //Stuurt letter "m" door als pin 22 ongelijk aan 0 is
putchar(0x6D);

else if((PINA & 0x02) != 0) //Stuurt letter "n" door als pin 23 ongelijk aan 0 is
putchar(0x6E);

else if((PINA & 0x04) != 0) //Stuurt letter "o" door als pin 24 ongelijk aan 0 is
putchar(0x6F);

else if((PINA & 0x08) != 0) //Stuurt letter "p" door als pin 25 ongelijk aan 0 is
putchar(0x70);

// Hier wordt de uitgang voor de klep aangestuurd
if (UDR !=0) // Als het dataregister ongelijk is aan 0
{
PORTA |= 0x80; //Set uithang hoog
delay_ms(500); //Wacht 2 sec.
PORTA &= 0x7F; //0x80^0xFF; //Set de uitgang weer op 0
UDR |=0; // Cleared het data register
}

}

}

Verzend je dat karakter naar de controller of vanuit de controller? Is dit je complete code? Wat moet het precies doen? Zoals het er nu uit ziet zet je controller elke keer PA7 voor 500ms hoog wanneer de uart een karakter heeft ontvangen.

Deze code heeft in elk geval geen effect


UDR |= 0;

1 OF 0 blijft 1
0 OF 0 blijft 0

Het is helemaal niet nodig zijn om dat register op 0 te zetten

Overigens is UDR een speciaal geval. Bij het uitlezen lees je altijd het ontvangstregister van de controller. Bij het schrijven, schijf je naar het zendregister. Je kan dus niet teruglezen wat je geschreven hebt. Je kan zo ook niet controlleren of je data verzonden is.

Verder is dit leesbaarder


PORTA |= 0x80; //wat is 0x80?

PORTA |= (1 << PA7); //dit is in 1 oogopslag duidelijk

De bitshift wordt door je compiler uitgevoerd, niet door je controller. Dus het heeft geen invloed op je performance.