-
        

Ergebnis 1 bis 8 von 8

Thema: Pins zu virtuellem Port in C zusammenfassen

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2007
    Ort
    Kornwestheim (kWh)
    Beiträge
    1.118

    Pins zu virtuellem Port in C zusammenfassen

    Anzeige

    Ich nutze WinAVR mit GCC und möchte verschiedene Pins (aus verschiedenen Ports) zu einem virtuellen neuen Port zusammenfassen.

    In Bascom geht ja sowas (PORTX), aber in C hab ich leider noch nix gefunden.

    Mit sehr umständlichen Unterfunktionen würde das wohl auch gehen, aber das kostet zu viel Rechenzeit und Speicherplatz.

    Kennt ihr da nen Trick?
    Gruß, AlKi

    Jeder Mensch lebt wie ein Uhrwerk, wie ein Computer programmiert...
    ==> UMPROGRAMMIEREN!

    Kubuntu

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.380
    die register sind mit den defines von PORTA - PORTX ja schon vorgegeben im AVR-Studio, du müsstest theoretisch nur
    PORTA |= BV(PA1); zum setzen und
    PORTA &= ~BV(PA1); zum löschen verwenden
    aber von dieser punktartigen notation musst du leider abweichen
    ich find aber folgende code-schnipsel ganz sinnvoll ^^
    Code:
    #define SETBIT(x,n) ((x) |= (1L << (n))) 
    #define CLEARBIT(x,n) ((x) &= ~(1L << (n)))
    #define GETBIT(x,n) ((x) & (1L << (n))) // gibt ne 0 oder einen wert > 0
    
       ...
       SETBIT(PORTA,1);
       CLEARBIT(PORTA,1);
    
       if (GETBIT(PORTA,1) == 0) DoSth();
       else if (GETBIT(PORTA,1) > 0) DoSthOther();
       ...

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Ich denke mal es geht dabei um Eingänge.

    Ich lege dazu eine Variable an, in die ich die gewünschten Ports mit logischen verknüpfungen und Verschiebeoperationen reinschiebe.


    Code:
    // Pin C 0...3 Low Byte, Pin D 0...3 High Byte
    volatile unsined char uc_input;
    uc_input = (PIND&0b00000111); // High Wert einlesen und maskieren
    uc_input = (uc_imput<<3);     // High Wert an den richtigen Platz schieben
    uc_input = uc_input|(PINC&0b00000111); // Low Wert einlesen und maskieren
    Das sollte der C-Compiler mit ein paar Assembler Befehlen umsetzen können.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2007
    Ort
    Kornwestheim (kWh)
    Beiträge
    1.118
    ich glaube, ich habe wohl ein bischen zuwenig angegeben.

    Ich wollte damit einen virtuellen Port aus vielen verschiedenen Pins zusammenstellen und als Ausgang, wenn möglich aber auch als Eingang nutzen.

    Ich glaube, dass das suf etwas wie den codeschnipsel von dir, wkrug, herauslaufen wird.

    beim Schreiben kann ich das auch mit 8 verschiedenen Bitpositionen machen, ich muss mir davor nur die passenden Masken 'zusammenstellen'.
    und eben jeh nach dem Bitpositionen setzen oder löschen. Hab ich da richtig gedacht?


    und damit auch bekannt ist, wozu ich das nutzen will: ich will auch in C LCDs komplett unabhängig anschließen (wenn ich zum Beispiel vom einen Port ADCs , vom nächsten UART nutzen und die ISP-Anschlüsse trotzdem freihalten will)
    Gruß, AlKi

    Jeder Mensch lebt wie ein Uhrwerk, wie ein Computer programmiert...
    ==> UMPROGRAMMIEREN!

    Kubuntu

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von robocat
    Registriert seit
    18.07.2006
    Beiträge
    935
    wenn du die fleury lcd lib verwendest, kann man die ports/pins frei wählen. bei grafik-lcds bräuchtest du eine andere lib, aber vielleicht kann man sich das schema der wählbaren PINs bei fleury "abgucken".

    gruesse

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2007
    Ort
    Kornwestheim (kWh)
    Beiträge
    1.118
    Fleury hat es wohl mit dem " BV(... " gemacht.
    Was bedeutet das eigentlich???
    ist ja sonst ganz normales Bitsetzen oder löschen...

    (ich weiß leider nicht, wie ich danach suchen sollte, die Sufus hier und im Wiki sagen nix)
    Gruß, AlKi

    Jeder Mensch lebt wie ein Uhrwerk, wie ein Computer programmiert...
    ==> UMPROGRAMMIEREN!

    Kubuntu

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von robocat
    Registriert seit
    18.07.2006
    Beiträge
    935
    aus "WinAVR-20070525/doc/avr-libc/avr-libc-user-manual/FAQ.html#faq_use_bv":
    What is all this _BV() stuff about?
    When performing low-level output work, which is a very central point in microcontroller programming, it is quite common that a particular bit needs to be set or cleared in some IO register. While the device documentation provides mnemonic names for the various bits in the IO registers, and the AVR device-specific IO definitions reflect these names in definitions for numerical constants, a way is needed to convert a bit number (usually within a byte register) into a byte value that can be assigned directly to the register. However, sometimes the direct bit numbers are needed as well (e. g. in an SBI() instruction), so the definitions cannot usefully be made as byte values in the first place.

    So in order to access a particular bit number as a byte value, use the _BV() macro. Of course, the implementation of this macro is just the usual bit shift (which is done by the compiler anyway, thus doesn't impose any run-time penalty), so the following applies:

    _BV(3) => 1 << 3 => 0x08

    However, using the macro often makes the program better readable.

    "BV" stands for "bit value", in case someone might ask you.

    Example: clock timer 2 with full IO clock (CS2x = 0b001), toggle OC2 output on compare match (COM2x = 0b01), and clear timer on compare match (CTC2 = 1). Make OC2 (PD7) an output.

    TCCR2 = _BV(COM20)|_BV(CTC2)|_BV(CS20);
    DDRD = _BV(PD7);
    kurzgesagt macht BV also aus einer pin-nr (0-7, PD7 = 7 zB) einen bytewert (byte-value 0-255), also aus 0,1,2,3,4..7 wird 1,2,4,8..128, also alles kein hexenwerk.

    übrigens wusste ich das selbst nicht so genau, und habe die FAQ grade erst entdeckt. lohnt sich sicher, da mal reinzugucken.

    gruesse

    EDIT: hier findet man die faq online: http://www.nongnu.org/avr-libc/
    EDIT2: und ja, ich programmiere schon länger und bins inzwischen gewohnt, include-verzeichnisse nach hinweisen zu durchwühlen

    EDIT3:
    Jeder Mensch lebt wie ein Uhrwerk, ...
    ... die meisten ticken nicht ganz richtig
    (keinesfalls persönlich gemeint, ist mir nur grade so eingefallen)

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2007
    Ort
    Kornwestheim (kWh)
    Beiträge
    1.118
    Danke!

    dann raff ich jetzt auch, wie der das gemacht hat:
    Code:
           ...
              /* output high nibble first */
            LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN);
            LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN);
            LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN);
            LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);
        	if(data & 0x80) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
        	if(data & 0x40) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
        	if(data & 0x20) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
        	if(data & 0x10) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
    halt geguckt, ob das bit in der Variable gesetzt ist ( logische &-Verknüpfung) und dann den dementsprechenden Pin vom Portxyz gesetzt oder nicht.
    ok, sowas hatte ich schon im Kopf, mir ist die lib bloß etwas zu kompliziert will mir was einfacheres schreiben, und gleichzeitig nen haufen lernen.
    Gruß, AlKi

    Jeder Mensch lebt wie ein Uhrwerk, wie ein Computer programmiert...
    ==> UMPROGRAMMIEREN!

    Kubuntu

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •