Hallo,

Ik ben voor het eerst bezig om een AVR micro controller te programmeren met C.
Nu wil ik een schakelaar inlezen.
Maar hiervoor moet ik de hele pin inlezen alle 8 de bits. Nu kan ik nog niet bepalen of dat enne pinnetje nu hoog of laag is. Hoe kan ik dit doen? Het is vast een hele domme vraag maar ik kom er niet uit.

En ik wil 8 bit’s inlezen maar deze zitten niet allemaal op de zelfde pin lijn A of B. dit van wegen de pin bezetting. Ik heb dit geprobeerd met #Define maar dit werkt ook niet helemaal lekker. Heeft hier iemand nog een tip voor.

Alvast bedankt

Je kunt het ingelezen byte AND-en met een waarde waarvan het bitje dat je wilt zien op '1' staat. Als dat true is, dan is die ene input '1'. Zo kun je ook meerdere ingangen in 1 keer testen.


  if (PINB & _BV (PB5)) {
     ... 

Als die schakelaar nog een naam heeft, bijvoorbeeld UP:


  #define S_UP PB5
  ...
  if (PINB & _BV (S_UP)) {
     ...

En ik wil 8 bits inlezen maar deze zitten niet allemaal op de zelfde pin lijn A of B. dit van wegen de pin bezetting. Ik heb dit geprobeerd met #Define maar dit werkt ook niet helemaal lekker. Heeft hier iemand nog een tip voor.

Als die pinnen enigzins gegroepeerd staan, bv. PB0 ... PB3 en PD2 ... PD5, kan je het zo doen:


unsigned char input;

input = ((PINB & 0x0F) | ((PIND << 2) & 0xF0);

De 4 laagste bits van PORTB komen dan onveranderd in je variabele terecht. PD2 ... PD5 schuiven eerst 2 plaatsen naar links, en komen in bit4 ... bit7 te staan.

Als de pinnen helemaal verspreid liggen, zit er weinig anders op dan pin-voor-pin te testen, en aan de hand daarvan een bit in je variabele hoog of laag te maken.

Ben jij helderziend of zo?

Ik moet 8 bits op PC0-3 en PB2-5 in de gaten houden, en had het gisteren geprogrammeerd als "dan maar zestien", maar eigenlijk is het zo veel mooier. Thanks. (ik had me niet gerealiseerd dat ik ze WEL aansluitend had aangesloten).

een tijdje geleden ben ik ook begonnen met AVR-GCC.
www.mikrocontroller.net was hierbij een grote steun, de voornaamste dingen heb ik tesamen met enkele voorbeelden samengevat in een pdf-file.

Mail me als je deze wenst te onvangen.

Edit(1):

wil je ook 'standaard-c' leren dan vind ik deze gratis compiler ook goed om C-programma's te compilen.
Devcpp-4.9.9.2 ( zowel voor C++ als C )

Edit(2):

de pdf-file met een voorlopige samenvatting van AVR-Gcc is hier nu te vinden onder Oefeningen in AVR-Gcc.
Ik zal deze regelmatig updaten.

[Bericht gewijzigd door Erelce op (19%)]

Hallo,

Het is gelukt ik kan nu ider poortje arpart inlezen. Omdat een druk knop is en de uitvoering maar 1 keer moet worden uitgevoed als de drukknop word ingedrukt. Hiervoor heb ik dit stukje code gemaakt.


//Switch functie
    LSwF=SwF;				//LastSwitchFunctie is SwitchFunctie

	if((PINH&0x01)!=0)		//PinH0 is ongelijk aan 0
	{
	  SwF=1;			//Switch is 1
	}	
	else
	{
	  SwF=0;			//Switch is 0
	}

	if(LSwF!=SwF && SwF==1)		//wanneer LSwF onglijk is aan SwF en SwF is 1 dan  
	{
	  Functie=(Functie + 1)%3;	//Verhoog Functie met 1 wanneer functie 2 is dan word functie 0
	}

hiermee word de functie maar 1 keer verhoogt. Maar kan dit ook makelijker?

Hallo Vink,

Enkele bedenkingen.

if((PINH&0x01)!=0)

Wil ook zeggen dat (PINH & 0x01) == 1.

Ik vraag me ook af waarom je de IF structuur daar überhaupt gebruikt. Kan je niet veel eenvoudiger SwF = (PINH & 0x01) gebruiken?

Functie=(Functie + 1)%3;	//Verhoog Functie met 1 wanneer functie 2 is dan word functie 0

Zoals het er nu staat, wordt functie pas 0 als functie 3 wordt. Wil je functie 0 maken zal je %2 moeten toepassen. Rest (modulo) van 2/2 = 0 rest van 2/3 = 2.

mvg

Theo

buckfast_beekeeper, Funtie wordt eerst geincrementeerd. Vink doet het juist.
Als Funtie = 2
Functie = (2+1) % 3 = 0

Hangt er van af wat vink bedoeld met

wanneer functie 2 is

. Was functie 2 en wordt ze geïncrementeerd. Dan klopt het inderdaad. Uit de commentaar kan je alleszins niet opmaken wat de hoogste waarde van Functie kan zijn.

mvg

Theo

Ja ik bedoelde het als 0,1,2,0,1,enz.
Om die code korter te maken ga ik nu voor kijken.

swf en lswf zijn ALTIJD gelijk, dat doe je nl zelf bovenin de functie. De laatste if haalt dus niet zoveel uit lijkt me.

[edit]hmm, ik zit niet op te letten. Klopt wel. Sry. Design style verschil zullen we maar zeggen :-)

[Bericht gewijzigd door flipflop op (30%)]

Na

LSwF=SwF;

maakt vink SwF nog 1 of 0. De If heeft dus wel degelijk zin.

mvg

Theo

Ik heb net nog alle Quoten na gelezen maar als ik het goed begrijp dan kan ik het niet kortermaken.

Het kan korter, als je de raad van buckfast_beekeeper opvolgt:


    LSwF = SwF;					//LastSwitchFunctie is SwitchFunctie
    SwF = (PINH & 0x01);

    if ((LSwF != SwF) && (SwF == 1)) {	//wanneer LSwF onglijk is aan SwF en SwF is 1 dan  
	Functie = (Functie + 1) % 3;		//Verhoog Functie met 1 wanneer functie 2 is dan word functie 0
    }

Nog een kleine optimalisatie zie ik zo:


LSwF=SwF;
SwF = PINH&0x01;
if(LSwF==0 && SwF==1) {     //wanneer LSwF onglijk is aan SwF en SwF is 1 dan  
  Functie=(Functie + 1)%3;  //Verhoog Functie met 1 wanneer functie 2 is dan word functie 0
}

Je test of swf==1. Als lswf dan ongelijk swf moet zijn, dan is dat eigenlijk lswf==0. Past meestal wat beter in de instructieset (simpele bittest ipv aan compare van twee bits). Is minimaal, maar toch.

Nu ben ik veder bezig met het programmeren en nu kan ik porta niet instellen als uitgang (dit kan gewoon heb dit al vaker gedaan in asembli) maar nu werkt het niet met C???

dit is wat ik doen:

DDRA=0x07;
en
PORTA=0x07;

maar wanneer ik nu eenLEDje erop zet doet hij niks??

DDRA |= (1<<PA0) | (1<<PA1) | (1<<PA2);

Zou moeten werken.

DDRA |= 0x07; //Heb ik niet getest maar zou volgens mij ook kunnen werken

Edit: werkt niet correct. Heb het net getest

[Bericht gewijzigd door buckfast_beekeeper op (15%)]

Nee dat is het hem ook niet als ik hem simuleer doet hij het wel maar op de STK500 niet.


DDRA=0x07;
PORTA=0x07;

Werkt wel, maar ga niet op PA7 testen! Het is PA0, PA1 en PA2 die je als uitgang schakelt en hoog maakt.

Op 24 januari 2010 14:30:12 schreef pros:


DDRA=0x07;
PORTA=0x07;

Werkt wel, maar ga niet op PA7 testen! Het is PA0, PA1 en PA2 die je als uitgang schakelt en hoog maakt.

Nee dat heb ik ook niet gedaan want moest 9 uitgangen hebben en die heb ik toen netjes op pin 1 t/m 9 gemaakt.

Edit: zou het in de fuses kunnen zitten?

Als je een fabrieksnieuwe ATmega32 hebt, moet je met de fuses de JTAG-functie uitschakelen om PORTC helemaal als gewone I/O-poort te gebruiken. Maar bij de doorsnee-avr komen er geen fuses aan te pas.

Het is gelukt. Na wat meten kwam ik erachter dar PA0 en PA1 het wel doen maar PA2 waar de reset op zit die doet hij niet. pas als je bij de fuses de resetdisabel aan vink dan pas doet hij het. alleen kan je nu de controller niet meer via de isp programeren.