Sida 1 av 2
Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 15:20:30
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;
}
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 15:25:40
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 )
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 15:36:49
av Gimbal
return 1 inne i while-loopen blir väl inte så bra heller...
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 16:25:28
av snigelen
Korken skrev:Skriva en etta till ett DDR-register sätter den som ingång
Du menar utgång?
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 17:07:11
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
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;
}
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 17:22:21
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" ?
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 19:11:35
av jesper
Då "anropet" är:
int main(void)
då måste ett värde returneras för att kompilatorn ska bli nöjd.
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 19:18:05
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.
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 19:22:11
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...
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 23:15:05
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"...
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 23:33:22
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.
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 23:40:28
av jesper
Jo, det bör man ju göra. Om det går. Vissa kompilatorer VILL ha int main().
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 21 april 2011, 23:42:53
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.
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 22 april 2011, 13:46:58
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å.
Re: Nybörjare på AVR. Hjälp med C kod
Postat: 22 april 2011, 14:08:11
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.