Bitmanipulation erklärt - I/O mit Atmega328

Опубликовано: 10 Октябрь 2024
на канале: EmbSys
1,415
35

LED Lauflicht aus 5 LEDs, dazu ein sauber entprellter Taster
ganz am Ende der Videobeschreibung: das Codebeispiel:

Die Demos wurden erstellt mit https://www.logic.ly

Timestamps:
00:00 Einführung
00:44 I/O mit Atmega328 - Vergleich Arduino - Direkter Zugriff
03:11 Codebeispiel
03:37 setup()
05:47 I/O mit Atmega328 - Output
07:09 Output im Debugger (Atmel Studio)
09:13 I/O mit Atmega328 - Input
09:40 Input im Debugger (Atmel Studio)
10:25 setup()
11:38 loop()
11:47 walking_leds() - Lauflicht
14:44 toggle_red_LED() - entprellte Taste
16:10 if-else Kurzschreibweise
19:30 Bit umändern mit XOR (Exclusiv Oder)

20:45 Demo Bitmanipulation
21:00 4 Bit Dekodieren
21:31 NOT: Bits invertieren, negieren
22:09 OR: Bits setzen, ODER Operation mit Maske
22:23 AND: Bits löschen, UND Operation mit Maske
25:15 AND: UND Operation mit invertierter Maske (Tilde)
26:40 XOR: Bits umändern, Exklusiv ODER mit Maske
28:24 SHIFT: Maske erzeugen mit Schieberegister


Leider erlaubt Youtube leider keine "spitzen Klammern" in der Videobeschreibung, und meint damit die "größer als" und "kleiner als" Zeichen. Daher habe ich alle diese Zeichen durch eckige Klammern ersetzt.
Wer den Code nutzen möchte muss also
alle 11 Klammern "[" durch "kleiner als" Zeichen und
alle 6 Klammern "]" durch "größer als" Zeichen
ersetzen.

Der Quellcode:
/*********************************************************************
Example: Bit Manipulation
*********************************************************************/

/* Eingebundene Dateien **/
#include [Arduino.h]

/* Deklaration Funktion ****/
void walking_LEDs();
void toggle_red_LED();

/*********************************************************************
Funktion setup
*********************************************************************/
void setup()
{
// PortD: LEDs, pushbutton
DDRD |= 0b11111100; // all LEDs: output
DDRD &= ~0b00000010; // pushbutton: input
PORTD |= 0b00000010; // internal pullup for pushbutton
PORTD &= 0b00000011; // all LEDs off
// ##### 5 green LEDs (walking light)
// # PortD2: red LED
// # PortD1: pushbutton (internal pullup)
// # not used, unchanged
}


/*********************************************************************
Funktion loop
*********************************************************************/
void loop()
{
walking_LEDs();

toggle_red_LED();
}


/*********************************************************************
Toggle red LED
check Pushbutton, debounce and toggle LED when pressed
*********************************************************************/
void toggle_red_LED(){
const uint8_t wait = 5; // debounce time in msec
static uint32_t savedTime = millis();
static enum {RELEASED, PRESSED}
keyState,
oldState = RELEASED;


// read pushbutton once at beginning (active low!)
keyState = (PIND & (1[[PIND1)) ? RELEASED : PRESSED;

// unless being skipped for debounce:
if (millis() ] savedTime + wait) {

// if button pressed
if(keyState == PRESSED && oldState == RELEASED) {
// save time for debounce
savedTime = millis();
// save key state for edge detection
oldState = PRESSED;
// toggle red LED
PORTD ^= (1[[PORTD2);
// PIND = (1[[PORTD2); // 2nd option for toggle
}

// if button released
if(keyState == RELEASED && oldState == PRESSED) {
// save time for debounce
savedTime = millis();
// save key state for edge detection
oldState = RELEASED;
}
}

}


/*********************************************************************
Walking LEDs
let 5 LEDs walk on Port D
*********************************************************************/
void walking_LEDs()
{
const uint16_t wait = 100; // time beween changes
static uint32_t savedTime = millis();
static uint8_t pattern = 0x01; // start with single LED
static enum {LEFT, RIGHT} direction = LEFT;

// if timer ran out
if (millis() ] savedTime + wait) {
savedTime = millis();

switch (direction) {

case LEFT: {
pattern [[= 1;
// check upper limit
if (pattern ]= 0x10) { // 0x10 = 0001 0000
direction = RIGHT;
}
break;
}

case RIGHT: {
pattern ]]= 1;
//check lower limit
if (pattern == 0x01) { // 0x01 = 0000 0001
direction = LEFT;
}
break;
}
}

// transfer pattern to Output (Arduino Pins 3 .. 7)
PORTD &= 0b00000111; // all LEDs off
PORTD |= pattern [[ 3; // output pattern
}
}