hallo,

ik zit met een probleempje, ik moet een robotje maken, voor school, die objecten kan ontwijken. Het detecteren van de objecten gebeurd via infrarood en op de ingang van mijn µC krijg ik een logische 1 of 0. Ik heb dus 2 infrarood detectors zitten op de ingangs print. Ik wil dit gaan verwerken met een µC zodanig dat ik 2 H bruggen kan aansturen. 1 voor de sturing en 1 voor de motoren.

Nu mijn vraag gaat hem namalijk over het programma:

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


void init()
{
  
  DDRD = (1<<PD5); // PORTB PB0-PB6 als uitgang
  
  DDRB |= (1<<PB2)|(1<<PB3)|(1<<PB4); // PB0 en 1 als ingang, PB2 tot 4 als uitgang
  DDRB |= (PB0<<1)|(PB1<<1);

}

int main()
{
	switch( PCINT0)
  	 {
		case (1):
			switch (PCINT1)
			{
				case (1):
				PB4 == 1;
  				PB3 == 0;
  				PB2 == 0;
  				PD5 == 0;
				_delay_ms(1);
				break;

				case (0):
				PB4 == 1;
  				PB3 == 0;
  				PB2 == 1;
  				PD5 == 0;
				_delay_ms(1);
				break;

				default:
				break;
			}
		break;
		
		case (0):
			switch (PCINT1)
			{
				case (1):
				PB4 == 0;
  				PB3 == 1;
  				PB2 == 1;
  				PD5 == 0;
				_delay_ms(1);
				break;

				case (0):
				PB4 == 1;
  				PB3 == 0;
  				PB2 == 0;
  				PD5 == 1;
				_delay_ms(1);
				break;

				default:
				break;
			}
			break;

		default:
		break;
	}	
	
}

Ik kan dit stukje programma perfect gaan compilen naar hex, maar wanneer ik dit in mijn attiny 2313 probeer te blazen dan zegt mijn programma: The contents of the hex file doesn't fit in de device.

Aan wat kan dit liggen? zijn er nog andere manieren om een pauze in te lassen in C?

MVG

Mathias Deneire
Radeloze C leek :)

Het lijkt mij een vrij eenvoudig programma dat makkelijk in een AT2313 moet passen... misschien met andere compiler flags compileren (optimse for size)?

Mijn oog viel trouwens op:


// ...
PD5 == 1; 
// ...

Die conditie is natuurlijk vrij zinloos zo; ik neem aan dat je "PD5 = 1;" bedoeld?

ik moet op mijn uitgang een logische 1 kunnen krijgen

PB4 == 1;
PB3 == 0;
PB2 == 0;
PD5 == 1;

zijn mijn uitgangen.

Op 26 maart 2008 11:44:17 schreef KaRaMBa:
misschien met andere compiler flags compileren (optimse for size)?

Hoe doe je dit in avr studio?

[Bericht gewijzigd door Henry S. op (45%)]

Ik bedoelde dat je "==" gebruikt waar je eigenlijk "=" bedoeld (je test voor gelijkheid, in plaats van dat je een waarde toekent)...

Ik heb geen enkele ervaring met AVR studio, dus daar kan ik je helaas niet mee helpen...

Hoi Neire,

PORTB is de "gewenste uitgangs waarde". PINB is de "huidige gemeten waarde". Allebij 8 bits tegelijk. Om het makkelijk te maken, heeft de compiler "PB4" gedefinieerd als "4". Zo kan je dan om PB4 (de pen) hoog te maken,

PORTB |= (1 << PB4); 

doen.

Jou code

PB4 == 1;

vergelijkt de waarde 4 met de waarde 1, constateert dat die NIET gelijk zijn (false, 0) en doet daarna met de waarde 0 niks.

Verder zet je na te roepen dat PB1 en PB0 inputs moeten worden, deze ineens toch als outputs. (in de functie "init()")

Ik weet dat AVR studio op avr-gcc gebaseerd is, maar ik weet verder niks van AVR studio, dus daar kan ik je niet mee helpen.

@neire: moet je niet ergens F_CPU definieren als je _delay_ms wil gebruiken?
Naast het vervangen van "==" door "=" kan je beter pinnen hoog maken met


PORTB |= (1 << PB1);

en laag maken met


PORTB &= ~(1 << PB1);

Op 26 maart 2008 12:20:49 schreef rew:

Verder zet je na te roepen dat PB1 en PB0 inputs moeten worden, deze ineens toch als outputs. (in de functie "init()")

Ik weet dat AVR studio op avr-gcc gebaseerd is, maar ik weet verder niks van AVR studio, dus daar kan ik je niet mee helpen.

Hoe definieer je dan je inputs?

Op 26 maart 2008 12:26:32 schreef pros:
@neire: moet je niet ergens F_CPU definieren als je _delay_ms wil gebruiken?
Naast het vervangen van "==" door "=" kan je beter pinnen hoog maken met


PORTB |= (1 << PB1);

en laag maken met


PORTB &= ~(1 << PB1);

Ok, bedankt voor de tips :d zit al heel wat verder :)

nu is dit mijn progje:


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


void init()
{
  
  DDRD = (1<<PD5); // PORTB PB0-PB6 als uitgang
  
  DDRB |= (1<<PB2)|(1<<PB3)|(1<<PB4); // PB0 en 1 als ingang, PB2 tot 4 als uitgang
  DDRB |= (PB0<<1)|(PB1<<1);

}



int main()
{
	switch( PB0)
  	 {
		case (1):
			switch (PB1)
			{
				case (1):
				PORTB |= (1 << PB4);
  				PORTB |= ~(1 << PB3);
				PORTB |= ~(1 << PB2);
  				PORTD |= ~(1 << PD5);
				_delay_ms(1);
				break;

				case (0):
				PORTB |= (1 << PB4);
  				PORTB |= ~(1 << PB3);
				PORTB |= (1 << PB2);
  				PORTD |= ~(1 << PD5);
				_delay_ms(1);
				break;

				default:
				break;
			}
		break;
		
		case (0):
			switch (PB1)
			{
				case (1):
				PORTB |= (1 << PB4);
  				PORTB |= ~(1 << PB3);
				PORTB |= ~(1 << PB2);
  				PORTD |= (1 << PD5);
				_delay_ms(1);
				break;

				case (0):
				PORTB |= (1 << PB4);
  				PORTB |= ~(1 << PB3);
				PORTB |= ~(1 << PB2);
  				PORTD |= (1 << PD5);
				_delay_ms(1);
				break;

				default:
				break;
			}
			break;

		default:
		break;
	}	
	
}

maar krijg nu nog enkele warnings, oa van die F-CPU:

- Waring FCPU not defined for util/delay.h ( zoals je zei dus)
- warning, compiler optimizations disabled, functions from <util/delay.h> won't work as designed"

alvast bedankt voor de hulp !!

[Bericht gewijzigd door Henry S. op (70%)]

Na een reset zijn alle I/O-pinnen automatisch ingangen; die kan je dus sowieso uitlezen. Forceren kan, door het betreffende bit in DDRx laag te maken.
Niet met "DDRB |= (PB0<<1)|(PB1<<1);" maar met "DDRB &= ~((PB0<<1)|(PB1<<1));"

Als de ATtiny2313 op 1MHz daait, zet je --voor de includes-- "#define F_CPU 1000000UL"

[Bericht gewijzigd door pros op (15%)]


/* Copyright (c) 2002, Marek Michalkiewicz
   Copyright (c) 2004,2005,2007 Joerg Wunsch
   Copyright (c) 2007  Florin-Viorel Petrov
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.

   * Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.

   * Neither the name of the copyright holders nor the names of
     contributors may be used to endorse or promote products derived
     from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE. */

/* $Id: delay.h,v 1.5 2007/10/28 23:25:56 joerg_wunsch Exp $ */

#ifndef _UTIL_DELAY_H_
#define _UTIL_DELAY_H_ 1

#include <inttypes.h>
#include <util/delay_basic.h>

/** \file */
/** \defgroup util_delay <util/delay.h>: Convenience functions for busy-wait delay loops
    \code
    #define F_CPU 1000000UL  // 1 MHz
    //#define F_CPU 14.7456E6
    #include <util/delay.h>
    \endcode

    \note As an alternative method, it is possible to pass the
    F_CPU macro down to the compiler from the Makefile.
    Obviously, in that case, no \c \#define statement should be
    used.

    The functions in this header file are wrappers around the basic
    busy-wait functions from <util/delay_basic.h>.  They are meant as
    convenience functions where actual time values can be specified
    rather than a number of cycles to wait for.  The idea behind is
    that compile-time constant expressions will be eliminated by
    compiler optimization so floating-point expressions can be used
    to calculate the number of delay cycles needed based on the CPU
    frequency passed by the macro F_CPU.

    \note In order for these functions to work as intended, compiler
    optimizations <em>must</em> be enabled, and the delay time
    <em>must</em> be an expression that is a known constant at
    compile-time.  If these requirements are not met, the resulting
    delay will be much longer (and basically unpredictable), and
    applications that otherwise do not use floating-point calculations
    will experience severe code bloat by the floating-point library
    routines linked into the application.

    The functions available allow the specification of microsecond, and
    millisecond delays directly, using the application-supplied macro
    F_CPU as the CPU clock frequency (in Hertz).

*/

#if !defined(__DOXYGEN__)
static inline void _delay_us(double __us) __attribute__((always_inline));
static inline void _delay_ms(double __ms) __attribute__((always_inline));
#endif

#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
# define F_CPU 1000000UL
#endif

#ifndef __OPTIMIZE__
# warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
#endif

/**
   \ingroup util_delay

   Perform a delay of \c __us microseconds, using _delay_loop_1().

   The macro F_CPU is supposed to be defined to a
   constant defining the CPU clock frequency (in Hertz).

   The maximal possible delay is 768 us / F_CPU in MHz.

   If the user requests a delay greater than the maximal possible one,
   _delay_us() will automatically call _delay_ms() instead.  The user
   will not be informed about this case.
 */
void
_delay_us(double __us)
{
	uint8_t __ticks;
	double __tmp = ((F_CPU) / 3e6) * __us;
	if (__tmp < 1.0)
		__ticks = 1;
	else if (__tmp > 255)
	{
		_delay_ms(__us / 1000.0);
		return;
	}
	else
		__ticks = (uint8_t)__tmp;
	_delay_loop_1(__ticks);
}


/**
   \ingroup util_delay

   Perform a delay of \c __ms milliseconds, using _delay_loop_2().

   The macro F_CPU is supposed to be defined to a
   constant defining the CPU clock frequency (in Hertz).

   The maximal possible delay is 262.14 ms / F_CPU in MHz.

   When the user request delay which exceed the maximum possible one,
   _delay_ms() provides a decreased resolution functionality. In this
   mode _delay_ms() will work with a resolution of 1/10 ms, providing
   delays up to 6.5535 seconds (independent from CPU frequency).  The
   user will not be informed about decreased resolution.
 */
void
_delay_ms(double __ms)
{
	uint16_t __ticks;
	double __tmp = ((F_CPU) / 4e3) * __ms;
	if (__tmp < 1.0)
		__ticks = 1;
	else if (__tmp > 65535)
	{
		//	__ticks = requested delay in 1/10 ms
		__ticks = (uint16_t) (__ms * 10.0);
		while(__ticks)
		{
			// wait 1/10 ms
			_delay_loop_2(((F_CPU) / 4e3) / 10);
			__ticks --;
		}
		return;
	}
	else
		__ticks = (uint16_t)__tmp;
	_delay_loop_2(__ticks);
}

#endif /* _UTIL_DELAY_H_ */

dit staat in het stukje code van util/delay.h

is dit normaal?

een paar op merkingen:

1- Je vergeet je init scriptje op te roepen.


int main(){
    
    //VOER DIE INITIALATIE UIT
    init();
    //NU DE REST
...
de rest

2- Doe die switch weg


switch (PB1)
	{
	case (1):
                     BLABLA
	break;
	case (0):
                     blabla
	break;

	default:
	break;
	}

hier mee



if(PB1){

//hier case 1

}else{

//hier case 0

}

De if methode is iets overzichterlijk

3- Gebruik dezelfde poort voor uitgangen die naar 1zelfde doel gaan bv h-brug of een ledbar


PORTD |= (1 << PB4);
PORTD |= ~(1 << PB3);
PORTD |= ~(1 << PB2);
PORTD |= ~(1 << PD5);
[code]

dit kan nog eenvoudiger

[code]
bijvoorbeeld
PORTD = (1 << PD4) | (1 << PD5);

Hier word telkens portD overschreven
dus moeten we geen nullen setten

Hopelijk heb je hier iets aan.

Robin

edit typo

@neire: Da's even schrikken, niet? :-)

Bij een

_delay_ms(100);

rekent de compiler dat allemaal uit, en komt er gewoon een lusje in de assembly-code te staan, die een aantal maal _delay_loop_2() aanroept.
Edoch, als je het waagt te schrijven

unsigned int delay_time;
// ...
_delay_ms(delay_time);

komt gans dat spul, floating-point bewerkingen inbegrepen, in de assembly-code te staan. Het resultaat is dan waarschijnlijk, dat het programma groter wordt dan het flash-geheugen van de AVR kan bevatten...

Het probleem zit hem puur in die _delay_ms..

Wanneer ik deze weglaat kan ik het programma wel in mijn µC zetten, maar ik blijf een warning krijgen van compiler optimizations disabled.

@pros

Op 26 maart 2008 13:47:52 schreef pros:

als je het waagt te schrijven

kan dit gewoon nog niet oplossen :d
kan het zijn dat een delay te veel plaats in neemt voor de attiny 2313?

edit : heb mijn switch aangepast en nu marcheert ie wel :d bizar spul:p


#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>



void init()
{
  
  DDRD = (1<<PD5); // PORTB PB0-PB6 als uitgang
  
  DDRB |= (1<<PB2)|(1<<PB3)|(1<<PB4); // PB0 en 1 als ingang, PB2 tot 4 als uitgang
  //DDRB |= ~(1<<PB0)|~(1<<PB1);

}


int main()
{
	init();

	switch( PCINT0)
  	 {
		case (1):
			switch (PCINT1)
			{
				case (1):
				PORTB |= (1 << PB4);
  				PORTB &= ~(1 << PB3);
				PORTB &= ~(1 << PB2);
  				PORTD &= ~(1 << PD5);
				_delay_ms(250);
				break;

				case (0):
				PORTB |= (1 << PB4);
  				PORTB &= ~(1 << PB3);
				PORTB |= (1 << PB2);
  				PORTD &= ~(1 << PD5);
				_delay_ms(250);
				break;

				default:
				break;
			}
		break;
	 }

	switch (PCINT1)
	 {
		case (0):
			switch (PCINT1)
			{
				case (1):
				PORTB |= (1 << PB4);
  				PORTB &= ~(1 << PB3);
				PORTB &= ~(1 << PB2);
  				PORTD |= (1 << PD5);
				_delay_ms(250);
				break;

				case (0):
				PORTB |= (1 << PB4);
  				PORTB &= ~(1 << PB3);
				PORTB &= ~(1 << PB2);
  				PORTD |= (1 << PD5);
				_delay_ms(250);
				break;

				default:
				break;
			}
			break;

		default:
		break;
	}	
	
}

nu alleen nog de compiler dinges :(

alvast bedankt voor de info !!

[Bericht gewijzigd door Henry S. op (66%)]

Je compiler-optomalisaties staan toch ingesteld op "size" (-Os)?

Wat is trouwens de bedoeling van

switch(PCINT0) {

? Als je een pin wil lezen, doe het dan bv. zo:


unsigned char pin;

pin = PINB;

switch (pin & (1 << PB0)) {
    case (1 << PB0):    // PB0 = hoog
    // ...
    case 0:             // PB0 = laag
    // ...

Je kunt natuurlijk ook zelf een hard-coded loop maken voor die delay.

Je kunt een loopje schrijven, de gegenereerde assembler code bekijken, en uitrekenen hoe lang iedere iteratie duurt, maar dat lijkt me even een brug te ver.

Wat gemakkelijker is, is het volgende:

volatile unsigned char Counter;

for( Counter = 0; Counter < 0xFFFF; Counter++ );

Die volatile zorgt ervoor dat de compiler het loopje niet weg-optimaliseert (omdat je volgens de compiler niets nuttigs doet). Ik weet niet precies hoeveel instructies dit zijn, maar minimaal een increment en conditionele jump, dus 2 instructies, dus dit loopje duurt minimaal ( 65536 * 2 ) / 16000000 = 0,008192, oftwel 8ms, aangenomen dat je controller op 16MHz loopt. Je kunt de waarde (0xFFFF) natuurlijk veranderen om een kortere delay te maken.

Maak even een loopje dat deze delay 10000 keer of zo uitvoert, en meten even m.b.v. een LEDje op je ontwikkelboard hoe lang hij daar over doet, dan kun je uitrekenen wat (bij benadering) de goede waarde is voor 1ms (of neem gewoon iets als die 1ms toch niet kritisch is).

Natuurlijk is het veel mooier om een timer te programmeren op 1kHz, een interrupt te laten genereren en daarin de rest van de code te zetten.

ok :d we zullen de loop functie eens uitzoeken

Op 26 maart 2008 17:36:13 schreef SparkyGSX:
Natuurlijk is het veel mooier om een timer te programmeren op 1kHz, een interrupt te laten genereren en daarin de rest van de code te zetten.

Dat is idd. de beste aanpak, als de timing precies moet zijn. En het is haast een must, als energiezuinigheid belangrijk is. Dan kan main() op beide oren sleep()'en...

AVR Studio is niet meer dan een veredelde tekst editor voor C met syntax highlighting. Het genereert zelf een Makefile hoewel je ook kan kiezen een eigen Makefile te gebruiken.

Optimalisatie stel je in bij de project opties. Vanuit het menu -> 'Project' -> 'Configuration Options', dan zie je dit scherm.

http://www.uploadarchief.net/files/download/avrstudio4_project_opties.png

Daar stel je de frequentie in, dus geen F_CPU define in je code plaatsen, dat doe je hier. Ook kies je hier de optimalisatie. Meest gangbaar is -Os (optimize for size). Door anderen hier al eerder aangegeven. Grote kans dat je code dan ook gewoon weer past in de AVR. Met optimalisatie kan de code soms wel een factor 5 kleiner worden.

Na het builden kan je altijd zien hoe groot je code is, je ziet dan zoeiets:

AVR Memory Usage
----------------
Device: attiny45

Program:     992 bytes (24.2% Full)
(.text + .data + .bootloader)

Data:         11 bytes (4.3% Full)
(.data + .bss + .noinit)

Dat mag nooit meer dan 100% zijn, dan is het geheugen vol.

Als je een pin wil lezen, doe het dan bv. zo:


unsigned char pin;

pin = PINB;

switch (pin & (1 << PB0)) {
    case (1 << PB0):    // PB0 = hoog
    // ...
    case 0:             // PB0 = laag
    // ...

wat gebeurt hier eigenlijk? want ik kran nog niks dat ik mss inlees op mijn uitgangen zetten, deze staan sowiso op 1.

pin krijgt de waarde van PINB (het ingang register van poort B). Vervolgens wordt er een bitmasker (bitwise and) toegepast zodat alleen bit PB0 overblijft. Dit bit kan alleen aan of uit zijn (1 of 0). Ik zou hier zelf nooit een switch gebruiken. Een switch gebruik je naar mijn mening voor een keuze uit meerdere (meer dan 2) mogelijkheden). Er zijn hier maar twee opties, zelf had ik dan een if else constructie toegepast.

en hoe zou je het moeten schrijven als je wilt werken met IF functie?

sry voor de vele vragen


#include <avr/io.h>

unsigned char pin;
volatile unsigned char Counter;

void init()
{
  
    
  DDRB |= (1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5); // PB0 en 1 als ingang, PB2 tot 4 als uitgang
  //DDRB |= ~(1<<PB0)|~(1<<PB1);

}


int main()
{
  init();


  if ((PB0==1) & (PB1 == 1)) 
    ;{		
	  PORTB |= (1 << PB4);
  	  PORTB &= ~(1 << PB3);
	  PORTB &= ~(1 << PB2);
  	  PORTB &= ~(1 << PB5);
	  //for( Counter = 0; Counter < 0xFFFF; Counter++ );
	 } 
			

  if ((PB0 == 0) & (PB1 == 1))
  	;{
	  PORTB |= (1 << PB4);
  	  PORTB &= ~(1 << PB3);
	  PORTB |= (1 << PB2);
  	  PORTB &= ~(1 << PB5);
	  //for( Counter = 0; Counter < 0xFFFF; Counter++ );
	}			
	

  if ((PB1 == 0) & (PB1 == 0))
	;{
	  PORTB |= (1 << PB4);
  	  PORTB &= ~(1 << PB3);
	  PORTB &= ~(1 << PB2);
  	  PORTB |= (1 << PB5);
	  //for( Counter = 0; Counter < 0xFFFF; Counter++ );
	}

  if ((PB1 == 0) & (PB1 == 0))
	;{
	  PORTB |= (1 << PB4);
  	  PORTB &= ~(1 << PB3);
	  PORTB |= (1 << PB2);
  	  PORTB &= ~(1 << PB5);
	  //for( Counter = 0; Counter < 0xFFFF; Counter++ );
	
	}		
}

heb nu al dit, maar als resultaat dat ik 4 eentjes heb op de uitgang :) toch al ix:p maar niet wat ik wou :d

[Bericht gewijzigd door Henry S. op (86%)]

Met "pin = PINB;" lees je PORTB uit.
Met "pin & (1 << PB0)" maak je alle bits van "pin" laag, behalve bit 0 (tenzij dit al laag was, uiteraard). Vervolgens kan je testen op "(1 << PB0)".

Zelf zou ik die switch() weglaten, en zoiets doen:


    if (bit_is_set(PINB, PINB0)) {  // PB0 hoog?
        // Doe wat...
    } else {                        // PB0 = laag
        // Doe iets anders
    }

Dat komt dichter bij "normale mensentaal".

[Update]
PB0 is altijd 0, net zoals PB1 altijd 1 is.

bestaat er ook zoix als bit_is_not_set?

Uhm... er is wel een not-operatie in C, namenlijk de '!'


if(!bit_is_set(...)) {
  ...
}

Het omgekeerde is "bit_is_clear(PINB, PB0)"
Eigenlijk moet dat zijn: "bit_is_clear(PINB, PINB0)" maar vermits zowel PB0 als PINB0 gedefinieerd zijn als '0', maakt het geen wezenlijk verschil.

Verwar echter PINB niet met PORTB. Dat zijn wel degelijk verschillende zaken!

Ter verduidelijking:


eljudnir/opt/cross/avr/include/avr: grep PORTB io2313.h
#define PORTB   _SFR_IO8(0x18)

eljudnir/opt/cross/avr/include/avr: grep PINB io2313.h
#define PINB    _SFR_IO8(0x16)

eljudnir/opt/cross/avr/include/avr: grep PINB0 io2313.h
#define    PINB0   0

eljudnir/opt/cross/avr/include/avr: grep PB0 io2313.h
#define    PB0     0

[Bericht gewijzigd door pros op (41%)]

#include <avr/io.h>
#include <util/delay.h>
#include <avr/sfr_defs.h>
unsigned char pin;

void init()
{
 
    
  DDRB |= (1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5); // PB0 en 1 als ingang, PB2 tot 4 als uitgang
  //DDRB |= ~(1<<PB0)|~(1<<PB1);

}


int main()
{
  
  pin = PINB;

  init();


  if (bit_is_set(PINB,PIN0&PIN1)) 
    ;{		
	  PORTB |= (1 << PB4);
  	  PORTB &= ~(1 << PB3);
	  PORTB &= ~(1 << PB2);
  	  PORTB &= ~(1 << PB5);
	 
	  _delay_ms(255);
	 } 
			

   if (bit_is_set(PINB,PIN1))
  	;{
	  PORTB |= (1 << PB4);
  	  PORTB &= ~(1 << PB3);
	  PORTB |= (1 << PB2);
  	  PORTB &= ~(1 << PB5);  

	  _delay_ms(255);
	}			
	

   if (bit_is_set(PINB,PIN0))
	;{
	  PORTB |= (1 << PB4);
  	  PORTB &= ~(1 << PB3);
	  PORTB &= ~(1 << PB2);
  	  PORTB |= (1 << PB5);

	  _delay_ms(255);
	}

  if (bit_is_clear(PINB,PIN0 &PIN1))
 	;{
	  PORTB |= (1 << PB4);
  	  PORTB &= ~(1 << PB3);
	  PORTB |= (1 << PB2);
  	  PORTB &= ~(1 << PB5);

	  _delay_ms(255);
	
	}		
}

krijg nu een knipper, lichtje :) PB4: 1, PB2: 1, PB2 : 0 ,PB5 : 1, PB5 : 0, PB2 : 0

snap het al :) domme fout :pif (bit_is_clear(PINB,PIN0 &PIN1)) zet die bit effectief zo zeker?