Nybörjare på AVR. Hjälp med C kod

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
ekman
Inlägg: 280
Blev medlem: 13 januari 2009, 14:04:35

Nybörjare på AVR. Hjälp med C kod

Inlägg av ekman »

Hej
Jag har precis försökt börja med att programmera en Atmega168 med hjälp av AVRISPII och AVR studio 5.
Jag vill att den läser av Port C - pin 2. Är den Hög så ska den göra Port B - pin 6 Hög.

Jag tror jag har gjort fel i koden:

Kod: Markera allt

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


int main(void)
{
	
	    // DDRB = data direction register for port B. 1 = output 0 = input
		DDRB = 0x40; //Make only pin B6 to an output ( 0100 0000 )
		DDRC = 0x02; //Make only pin C2 to an input ( 0000 0010 )
		
		PORTC = 0x02; //Activate Pullup resistors for C2

		
    while(1)
    {
		// IF PORTC2 is high then..
		if(PINC & (1<<2))
		{
			PORTB = 0x40; // Make PINB6 HIGH
		} 
		else
		{
			PORTB = 0xFF; // Make ALL LOW
		}
		
		return 1;

    }
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av Korken »

Skriva en etta till ett DDR-register sätter den som ingång, så du ska cleara DDRC inte setta som du gör nu.

DDRC = 0x02; //Make only pin C2 to an input ( 0000 0010 )
till
DDRC &= ~0x02; //Make only pin C2 to an input ( DDRC & 1111 1101 )
Gimbal
Inlägg: 8685
Blev medlem: 20 april 2005, 15:43:53

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av Gimbal »

return 1 inne i while-loopen blir väl inte så bra heller...
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av snigelen »

Korken skrev:Skriva en etta till ett DDR-register sätter den som ingång
Du menar utgång?
ekman
Inlägg: 280
Blev medlem: 13 januari 2009, 14:04:35

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av ekman »

Hur funkar detta: DDRC &= ~0x02; ?

Jag sett att dom olika tecknen betyder så här:
| bit OR
& bit AND
~ bit NOT
^ bit EXLUSIVE OR (XOR)
<< bit LEFT SHIFT
>> bit RIGHT SHIFT

Men jag har svårt att förstå endå. ~ inventerar 0x02 (0000 0010) till 1111 11011 ? men vad gör & (AND) ?

Yaay! nu funkar det :D
Hittat faktiskt ett fel själv också. i IF satsen så hade jag skrivit 0xFF när det skulle gå LOW. Så nu ser koden ut så här:

Kod: Markera allt

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


int main(void)
{
	
	    // DDRB = data direction register for port B. 1 = output 0 = input
		DDRB = 0x40; //Make only pin B6 to an output ( 0100 0000 )
		DDRC &= ~0x02; //Make only pin C2 to an input ( DDRC & 1111 1101 )
		
		PORTC = 0x02; //Activate Pullup resistors for C2

		
    while(1)
    {
		// IF PORTC2 is high then..
		if(PINC & (1<<2))
		{
			PORTB = 0x40; // Make PINB6 HIGH
		} 
		else
		{
			PORTB = 0x00; // Make ALL LOW
		}
		
		
    }
	return 0;

}
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av sodjan »

Nu så fungerar det i och för sig, men... :-)

Du har fortfarande en "return" i sluten av main(). Nu så ska koden aldrig
komma dit, men *om* den gjorde det, vart vill du då att den "återvänder" ?
Användarvisningsbild
jesper
Inlägg: 722
Blev medlem: 12 juni 2006, 16:04:08
Ort: Laem Mae Phim, Thailand

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av jesper »

Då "anropet" är:
int main(void)
då måste ett värde returneras för att kompilatorn ska bli nöjd.
Användarvisningsbild
Icecap
Inlägg: 26654
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av Icecap »

Och därför skriver man:
void main(void)

Men det har akademisk intresse och kan som mest spara en byte eller två i programminne.
monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av monstrum »

ekman skrev:Hur funkar detta: DDRC &= ~0x02; ?

Jag sett att dom olika tecknen betyder så här:
| bit OR
& bit AND
~ bit NOT
^ bit EXLUSIVE OR (XOR)
<< bit LEFT SHIFT
>> bit RIGHT SHIFT

Men jag har svårt att förstå endå. ~ inventerar 0x02 (0000 0010) till 1111 11011 ? men vad gör & (AND) ?

}
& är ju helt enkelt bitvis OCH. T.ex. 0x44 (01000100) & 0x07 (00000111) blir 0x04 (00000100).

Det vanligaste när man vill ändra enskilda bitar och inte har tillgång till operationer som gör detta direkt är att använda |= och &= tilldelningsoperatorerna.
PORTA |= (1<<3) sätter bit 3 hög, och behåller resterande bitar.
PORTA &= ~(1<<3) dvs PORTA = PORTA & (1111 0111) sätter bit 3 låg och behåller övriga bitars värde.

Edit: Bitfel...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av sodjan »

> Men det har akademisk intresse och kan som mest spara en byte eller två i programminne.

Ja det har ett akademiskt intresse, det har med hur man ser på AVR
som "miljö" där C-programmet exekverar. D.v.s till skillnad till en miljö
där man kanske har ett OS som programmet exekverar i, och där en
return från main mer "makes sense"...
Användarvisningsbild
Icecap
Inlägg: 26654
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av Icecap »

Nja... det är ju ingen AVR-grej, det är en generell µC-grej. Och det är just varför jag alltid skriver main som en void.
Användarvisningsbild
jesper
Inlägg: 722
Blev medlem: 12 juni 2006, 16:04:08
Ort: Laem Mae Phim, Thailand

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av jesper »

Jo, det bör man ju göra. Om det går. Vissa kompilatorer VILL ha int main().
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av sodjan »

> Nja... det är ju ingen AVR-grej,...

Jo, i den *här* tråden... :-)
Men nu var det ju inte det som var poängen.

> Vissa kompilatorer VILL ha int main().

Lite märkligt om en kompilator för mikrokrontrollers kräver det.
På plattformat med ett OS är det väl dock en förutsättning för att
kunna lömna ett exit-status tillbaka till "skalet", men det är inte
rellevant i detta fall.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av jesse »

fel:

DDRC = 0x02; //Make only pin C2 to an input ( 0000 0010 )

pinne 2 är ju 0x04 = 0000 0100 , dvs (1 << 2), inte 0x02.

om du inte ska ha några utgångar på port C behöver du inte skriva till DDRC alls - alla portar är ingångar vid reset som default.

När du ändrade i programmet till:

Kod: Markera allt

 DDRC &= ~0x02; //Make only pin C2 to an input ( DDRC & 1111 1101 )
      PORTC = 0x02; //Activate Pullup resistors for C2
så borde ju alla C-pinnar blivit UTGÅNGAR utom C1. Du lägger dessutom en etta ut på C2. Det blir antagligen kortslutning och en hög ström ut från C2 om du ansluter den till jord.



PORTB = 0xFF; // Make ALL LOW ... Jaha, det såg du själv ja...


>> vad gör AND ???

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

&= fungerar som += fast gör AND istället för PLUS. Detta skriver man om det finns andra bitar i registret som man inte vill ändra på om du ska nollställa en eller flera bitar i ett register.

Motsvarigheten när du ska ettställa bitar är att skriva DDRD |= 0x40;

skriver du DDRC = ~0x04; (utan AND) så kommer alla andra bitar bli utgångar eftersom dom blir ettor. Men om du istället skriver DDRC &= ~0x04; (med AND) så kommer de andra bitarna att behålla sitt gamla värde - bara bit 2 kommer att nollställas. Men eftersom alla bitar i DDRC alltid nollställs vid reset så kommer DDRC i praktiken att fortsätta vara 0x00.

I ditt fall kanske &= räddade din processor från att stekas av kortslutning om du nu har skrivit så. Ingen pinne blir ju utgång då.
monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Re: Nybörjare på AVR. Hjälp med C kod

Inlägg av monstrum »

Jesse: Nu gjorde du nog en tankevurpa. DDRC &= ~0x02 sätter ju inte alla bitar höga. And med inversen av 0000 0010 kommer ju sätta bit 1 (andra biten) till 0.
Skriv svar