-
        

Ergebnis 1 bis 4 von 4

Thema: ATMEGA16 + STK500 - Lauflicht

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.09.2005
    Beiträge
    102

    ATMEGA16 + STK500 - Lauflicht

    Anzeige

    Hallo,
    vermutlich ist es ein einfacher Fehler, doch zunächst mein Quelltext:

    Code:
    #include <avr/io.h>
    #include <avr/delay.h>
     
    void main(){
      DDRB = 0xFF; // Alle Pins sind Output
      PORTB = 0xFF; // Alle LEDs ausschalten
     
      // Hier möchte ich z.B. um 2 nach links shiften
     
      PORTB &= (0<<2);
     
     
      // Restlicher Code nicht mehr relevant [...]

    Mein Problem ist das shiften.

    Wenn ich in PortB alles auf 1 setze, sind alle LEDs ausgeschaltet.
    Nun möchte ich die dritte Lampe einschalten.
    Dementsprechend müsste ich ja an die Stelle eine 0 schreiben wohingegend der Rest weiterhin 1 bleibt.

    1111 1111 vorher
    1111 1011 shift 0<<2
    ---------- logisches &
    1111 1011


    Mein PortB müsste also nach der Operation dem shiften
    PortB so 1111 1011 aussehen.

    Doch alle LEDs bleiben einfach an.

    Hat jemand eine Idee?


    Danke
    Kesandal

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.381
    jein ^^

    du schiebst eine 0 um 2 stellen nach links ...

    (0<<2) == 0b0000000_0_ -> 0b00000_0_00

    da kannst du nullen schieben so viel wie du willst ^^

    die operation die du suchst ist das negieren '~'

    PortX = PortX & ~(1<<2)

    ~(1<<2) == 0b0000000_1_ -> 0b00000_1_00 -> 0b11111_0_111

    EDIT: Nur nachträglich zur Erklärung, beim shiften wird der Inhalt der Variable (in dem Falle eine 0, die 8 Stück Nullbits entspricht) um die angegebene Zahl Stellen nach Links bzw. Rechts verschoben, und freiwerdende Stellen werden mit weiteren Nullen aufgefüllt (immer). Daher muss man um einzelne Bits aus einer anderen Zahl zu löschen, erst die entsprechenden Stellen über SHIFT und ODER Operationen auf 1 setzen und dann die ganze Zahl negieren und mit UND die Bits aus der Zielzahl so ausmaskieren.

    Wenn ich mehrere Bits löschen will, sieht das dann so aus:

    PortX &= ~( (1<<2) | (1<<4) | (1<<7) );

    alternativ ginge auch

    PortX &= ~(37<<2);

    aber so verliert man schnell die Übersicht!
    Geändert von Ceos (19.05.2011 um 14:30 Uhr)
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.09.2005
    Beiträge
    102
    Hallo,
    danke für Deine Antwort.

    Ich habe das Lauflicht nun so gelöst:

    Code:
    for(counter=0;counter<8;counter++){
       tmp = ~PORTB;
       tmp = 1<<counter;
       PORTB = ~tmp ;
    }
    Damit läuft das Lauflicht zumindest schonmal von rechts nach links.

    Von links nach rechts klappt es aber nicht.

    Kann es sein, dass es nicht möglich ist nach rechts zu shiften?

    Mein Ansatz als Test war der folgende:

    Code:
    PORTB = 0xFF;
     
    tmp = ~PORTB;
    tmp = (1>>2); 
    PORTB = ~tmp;
    Damit müsste das doch eigentlich klappen...
    Ergebnis: alle LEDs sind aus.

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.381
    das Ergebnis bei dir ist auch nur logisch, eine Dezimale 1 entspricht 0b0000000_1_, wenn du jetzt nach rechts schiebst, fällt die 1 ins Nirvana und alles steht wieder auf 0

    was du brauchst wäre in dem Fall 0b_1_0000000 -> 0x80 -> (128>>n)

    ich geb dir mal ein beispiel für ein Lauflicht, bei dem man einfach die LED direkt manipuliert und nicht erst übern Counter geht!

    Code:
    #define LEFT 1
    #define RIGHT 2
    ...
    PORTB = 1;
    unsigned char direction  = LEFT;
    while(1)
    {
       if(PORTB == 0x80) direction = RIGHT;
       else if (PORTB == 0x01) direction = LEFT;
       else {
           if(direction == RIGHT) PORTB = (PORTB>>1);
           if(direction == LEFT) PORTB = (PORTB<<1);
           'PAUSE' // es gibt in der delay.h eine wait_ms(long) funktion mit der du millisekundenlange Pausen einbauen kannst, würde ich bei mehr Erfahrung durch eine timergesteuerte Variable ersetzen!
       }
    }
    so haste n Knight-Rider-Licht
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

Ähnliche Themen

  1. Atmega16, STK500: Switch X gedrückt => LED X soll leuchten
    Von Kesandal im Forum ARM - 32-bit-Mikrocontroller-Architektur
    Antworten: 1
    Letzter Beitrag: 28.04.2011, 21:44
  2. STK500, Atmega16, UART, AVR Studio4
    Von Jimmy83 im Forum C - Programmierung (GCC u.a.)
    Antworten: 35
    Letzter Beitrag: 14.04.2010, 09:38
  3. Lauflicht
    Von Matze0001 im Forum Elektronik
    Antworten: 31
    Letzter Beitrag: 18.08.2009, 18:33
  4. Assembler Beispielprogramm fürs STK500 (ATmega16)
    Von KartoffeL im Forum Assembler-Programmierung
    Antworten: 1
    Letzter Beitrag: 14.06.2007, 14:15
  5. ATmega16 und STK500
    Von andkut im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 15.01.2005, 16:57

Berechtigungen

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