LCD mit Schieberegister
Hier befindet sich ein Programmierbeispiel einer LCD-Steuerung mit Schieberegister für den Raspberry Pi mit C++11 und WiringPi.
Das Programm kann direkt auf dem Raspberry Pi erstellt werden.
Das Schieberegister 74HC595
An den Ausgängen wird der Strom des Netzteils des Raspberry Pi (in der Regel 2,5 A) und nicht dessen Prozessorstrom (50 mA) benutzt, so dass etwas stärkere Verbraucher angeschlossen werden können. Mit dem Prozessorstrom können nämlich nur drei LEDs gleichzeitig zum Leuchten gebracht werden, wie man mit dem Ohmschen Gesetz berechnen kann, aber mit einem oder mehreren hintereinandergeschalteten 74HC595s viel mehr.
Die Anzeige
Aufbau der Schaltung
Raspberry Pi an 74HC595
Raspberry Pi | 74HC595 |
---|---|
GPIO 0 | DS |
GPIO 1 | STCP |
GPIO 2 | SHCP |
5 V | Vcc, MR |
GND | OE, GND |
LCD an 74HC595
LCD | 74HC595 | |
---|---|---|
i | Qi | für 0 <= i <= 7 |
Raspberry Pi an das LCD
Eine der Kathoden K wird über einen 220 Ω Widerstand mit GND des Raspberry Pi verbunden.
Download
Sie können den Quellcode des Programms herunterladen und auf dem Raspberry Pi entpacken. Falls Sie dort den Qt Creator installiert haben, können Sie damit das Programm erstellen und ausführen.Aber Sie brauchen kein Qt, es geht auch in der Shell mit
g++ main.cpp -o lcd -O2 -lwiringPi
./lcd
Es werden in einer Endlosschleife die hexadezimalen Ziffern mit einer Animation angezeigt, Abbruch mit Strg + C.
Quellcode
Hier befinden sich die Qt Projektdatei und der C++ Quellcode.
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
unix:!macx: LIBS += -L$$PWD/usr/lib/ -lwiringPi
HEADERS += \
binary.h
#include <iostream>
#include <wiringPi.h>
#include "binary.h"
static const int DS {0};
static const int STCP {1};
static const int SHCP {2};
u_char round[] = {1_b, 10_b, 100_b, 1000_b, 1.0000_b, 10.0000_b};
u_char digits[] = {11.1111_b, 110_b, 101.1011_b, 100.1111_b, 110.0110_b,
110.1101_b, 111.1101_b, 111_b, 111.1111_b, 110.1111_b,
111.0111_b, 111.1100_b, 11.1001_b, 101.1110_b, 111.1001_b, 111.0001_b};
void init()
{
for (int pin: {DS, STCP, SHCP}) {
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
}
inline void pulse(int pin)
{
digitalWrite(pin, HIGH);
delay(1);
digitalWrite(pin, LOW);
}
inline void sipo(u_char data)
{
for (int i {0}; i != 8; ++i) {
digitalWrite(DS, (0x80 & (data << i)) ? HIGH : LOW);
pulse(SHCP);
}
pulse(STCP);
}
void goRound()
{
for (u_char d: round) {
sipo(d);
delay(40);
}
}
void showDigits()
{
bool showPoint {false};
for (u_char d: digits) {
sipo(d | (showPoint ? 1000.0000_b : 0));
showPoint = !showPoint;
delay(500);
}
}
int main()
{
if (wiringPiSetup() == -1) return 1;
init();
while (true) {
goRound();
goRound();
showDigits();
}
return 0;
}
#ifndef BINARY_H
#define BINARY_H
typedef unsigned char u_char;
constexpr u_char twoPow(int n) {
return n > 0 ? 2*twoPow(n-1) : 1;
}
template<char...> struct binaryHelper;
template<char c> struct binaryHelper<c> {
static_assert(c == '0' || c == '1', "keine Binärziffer");
static constexpr u_char value() { return c - '0'; }
};
template<char c, char... tail> struct binaryHelper<c, tail...> {
static_assert(c == '.' || c == '0' || c == '1', "keine Binärziffer");
static_assert(((sizeof...(tail) + 1) % 5) || c == '.',
"die Zahl muss in mit '.' getrennte Viererblöcke unterteilt sein");
static constexpr u_char value() {
return (c == '.' ? 0 : (c - '0')*twoPow(sizeof...(tail) - sizeof...(tail)/5))
+ binaryHelper<tail...>::value();
}
};
template<char... chars> constexpr u_char operator"" _b() {
return binaryHelper<chars...>::value();
}
#endif // BINARY_H
Darstellung einer 8-Bit Zahl in Binärschreibweise und in Viererblöcken
0b1011011
oder hexadezimal als 0x5b
speichern. Ich finde das Umformen der Binärzahl in eine Hexadezimalzahl und umgekehrt anstrengend, und bei der Binärdarstellung hätte ich gerne eine Unterteilung in Viererblöcke. Daher benutze ich binary.h, damit der Compiler mit 8-Bit Binärzahlen in zwei Viererblöcken zurechtkommt. Damit kann ich statt 0b1011011
oder 0x5b
das lesbarere 101.1011_b
schreiben.
Leider können wir nicht
101.1011b
(ohne Unterstrich) benutzen, da das Suffix b
in C++ reserviert ist.