Skip to content
Snippets Groups Projects
Commit 79153605 authored by Peter Gerwinski's avatar Peter Gerwinski
Browse files

Vorbereitung 9.11.2023

parent a1957e1b
Branches
Tags
No related merge requests found
Showing
with 1975 additions and 0 deletions
%.elf: %.c
avr-gcc -Wall -Os -mmcu=atmega328p $< -o $@
%.hex: %.elf
avr-objcopy -O ihex $< $@
download:
./download.sh
#include <avr/io.h>
int main (void)
{
DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0xff;
PORTA = 0x1f;
PORTB = 0x10;
PORTD = 0x10;
PORTC = 0xfc;
while (1);
return 0;
}
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
uint8_t counter = 1;
uint8_t leds = 0;
ISR (TIMER0_COMP_vect)
{
if (counter == 0)
{
leds = (leds + 1) % 8;
PORTC = leds << 4;
}
counter++;
}
void init (void)
{
cli ();
TCCR0 = (1 << CS01) | (1 << CS00);
TIMSK = 1 << OCIE0;
sei ();
DDRC = 0x70;
}
int main (void)
{
init ();
while (1)
; /* do nothing */
return 0;
}
port=$(ls -rt /dev/ttyACM* | tail -1)
echo avrdude -P $port -c arduino -p m328p -U flash:w:$(ls -rt *.hex | tail -1)
avrdude -P $port -c arduino -p m328p -U flash:w:$(ls -rt *.hex | tail -1) 2>/dev/null
File added
This diff is collapsed.
\babel@toc {german}{}\relax
\beamer@sectionintoc {3}{Bibliotheken}{3}{0}{1}
\beamer@subsectionintoc {3}{4}{Callbacks}{3}{0}{1}
\beamer@subsectionintoc {3}{5}{Projekt organisieren: make}{5}{0}{1}
\beamer@sectionintoc {4}{Hardwarenahe Programmierung}{10}{0}{2}
\beamer@subsectionintoc {4}{1}{Bit-Operationen}{10}{0}{2}
\beamer@subsubsectionintoc {4}{1}{1}{Zahlensysteme}{10}{0}{2}
\beamer@subsubsectionintoc {4}{1}{2}{Bit-Operationen in C}{12}{0}{2}
\beamer@subsectionintoc {4}{2}{I/O-Ports}{14}{0}{2}
\beamer@subsectionintoc {4}{3}{Interrupts}{17}{0}{2}
\beamer@subsectionintoc {4}{4}{volatile-Variable}{19}{0}{2}
File added
% hp-musterloesung-20231109.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Peter Gerwinski
%
% This document is free software: you can redistribute it and/or
% modify it either under the terms of the Creative Commons
% Attribution-ShareAlike 3.0 License, or under the terms of the
% GNU General Public License as published by the Free Software
% Foundation, either version 3 of the License, or (at your option)
% any later version.
%
% This document is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this document. If not, see <http://www.gnu.org/licenses/>.
%
% You should have received a copy of the Creative Commons
% Attribution-ShareAlike 3.0 Unported License along with this
% document. If not, see <http://creativecommons.org/licenses/>.
% README: Text-Grafik-Bibliothek, Mikrocontroller, LED-Blinkmuster
\documentclass[a4paper]{article}
\usepackage{pgscript}
\renewcommand{\breath}{\bigskip}
\begin{document}
\section*{Hardwarenahe Programmierung\\
Musterlösung zu den Übungsaufgaben -- 9.\ November 2023}
\exercise{Text-Grafik-Bibliothek}
Schreiben Sie eine Bibliothek für "`Text-Grafik"' mit folgenden Funktionen:\vspace*{-\medskipamount}
\begin{itemize}
\item
\lstinline|void clear (char c)|\\
Bildschirm auf Zeichen \lstinline|c| löschen,\\
also komplett mit diesem Zeichen (z.\,B.: Leerzeichen) füllen
\item
\lstinline|void put_point (int x, int y, char c)|\\
Punkt setzen (z.\,B.\ einen Stern (\lstinline{*}) an die Stelle $(x,y)$ "`malen"')
\item
\lstinline|char get_point (int x, int y)|\\
Punkt lesen
% \item
% \lstinline|void fill (int x, int y, char c, char o)|\\
% Fläche in der "`Farbe"' \lstinline|o|,
% die den Punkt \lstinline|(x, y)| enthält,
% mit der "`Farbe"' \lstinline|c| ausmalen
\item
\lstinline|void display (void)|\\
das Gezeichnete auf dem Bildschirm ausgeben
\end{itemize}
\goodbreak
Hinweise:\vspace*{-\medskipamount}
\begin{itemize}
\item
Eine C-Bibliothek besteht aus (mindestens)
einer \file{.h}-Datei und einer \file{.c}-Datei.
\item
Verwenden Sie ein Array als "`Bildschirm"'.
Vor dem Aufruf der Funktion \lstinline|display()| ist nichts zu sehen;\\
alle Grafikoperationen erfolgen auf dem Array.
\item
Verwenden Sie Präprozessor-Konstante,
z.\,B.\ \lstinline{WIDTH} und \lstinline{HEIGHT},\\
um Höhe und Breite des "`Bildschirms"' festzulegen:
\begin{lstlisting}[gobble=8]
#define WIDTH 72
#define HEIGHT 24
\end{lstlisting}
\item
Schreiben Sie zusätzlich ein Test-Programm,
das alle Funktionen der Bibliothek benutzt,\\
um ein hübsches Bild (z.\,B.\ ein stilisiertes Gesicht -- "`Smiley"')
auszugeben.
\end{itemize}
\points{8}
\solution
Siehe die Dateien \gitfile{hp}{2023ws/20231109}{textgraph.c} und \gitfile{hp}{2023ws/20231109}{textgraph.h} (Bibliothek)
sowie \gitfile{hp}{2023ws/20231109}{test-textgraph.c} (Test-Programm).
Diese Lösung erfüllt zusätzlich die Aufgabe,
bei fehlerhafter Benutzung (Koordinaten außerhalb des Zeichenbereichs)
eine sinnvolle Fehlermeldung auszugeben,
anstatt unkontrolliert Speicher zu überschreiben und abzustürzen.
Das Schlüsselwort \lstinline{static}
bei der Deklaration der Funktion \lstinline{check_coordinates()}
bedeutet, daß diese Funktion nur lokal (d.\,h.\ innerhalb der Bibliothek)
verwendet und insbesondere nicht nach außen
(d.\,h.\ für die Benutzung durch das Hauptprogramm) exportiert wird.
Dies dient dazu, nicht unnötig Bezeichner zu reservieren
(Vermeidung von "`Namensraumverschmutzung"').
Man beachte die Verwendung einfacher Anführungszeichen (Apostrophe)
bei der Angabe von \lstinline{char}-Kon"-stanten (\lstinline{'*'})
im Gegensatz zur Verwendung doppelter Anführungszeichen
bei der Angabe von String-Konstanten
(String = Array von \lstinline{char}s, abgeschlossen mit Null-Symbol).
Um das einfache Anführungszeichen selbst als \lstinline{char}-Konstante anzugeben,
ist ein vorangestellter Backslash erforderlich: \lstinline{'\''} ("`Escape-Sequenz"').
Entsprechendes gilt für die Verwendung doppelter Anführungszeichen
innerhalb von String-Konstanten:
\lstinline{printf ("Your name is: \"%s\"", name);}
\exercise{Mikrocontroller}
\begin{minipage}[t]{10cm}
An die vier Ports eines ATmega16-Mikrocontrollers sind Leuchtdioden angeschlossen:
\begin{itemize}
\item
von links nach rechts an die Ports A, B, C und D,
\item
von oben nach unten an die Bits Nr.\ 0 bis 7.
\end{itemize}
Wir betrachten das folgende Programm (\gitfile{hp}{2023ws/20231109}{aufgabe-2.c}):
\begin{lstlisting}[gobble=6]
#include <avr/io.h>
int main (void)
{
DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0xff;
PORTA = 0x1f;
PORTB = 0x10;
PORTD = 0x10;
PORTC = 0xfc;
while (1);
return 0;
}
\end{lstlisting}
\end{minipage}\hfill
\begin{minipage}[t]{3cm}
\strut\\[-\baselineskip]
\includegraphics[width=3cm]{leds.jpg}
\end{minipage}
\vspace*{-3cm}
\strut\hfill
\begin{minipage}{11.8cm}
\begin{itemize}
\item[(a)]
Was bewirkt dieses Programm? \points{4}
\item[(b)]
Wozu dienen die ersten vier Zeilen des Hauptprogramms? \points{2}
\item[(c)]
Was würde stattdessen die Zeile \lstinline{DDRA, DDRB, DDRC, DDRD = 0xff;} bewirken?
\points{2}
\item[(d)]
Schreiben Sie das Programm so um,
daß die durch das Programm dargestellte Figur spiegelverkehrt erscheint. \points{3}
\item[(e)]
Wozu dient das \lstinline{while (1)}? \points{2}
\item
Alle Antworten bitte mit Begründung.
\end{itemize}
\end{minipage}
\solution
\begin{itemize}
\item[(a)]
\textbf{Was bewirkt dieses Programm?}
\newcommand{\x}{$\bullet$}
\renewcommand{\o}{$\circ$}
\begin{minipage}[t]{0.75\textwidth}\parskip\smallskipamount
Es läßt die LEDs in dem rechts abgebildeten Muster aufleuchten,\\
das z.\,B.\ als die Ziffer 4 gelesen werden kann.
(Das Zeichen \x\ steht für eine leuchtende, \o\ für eine nicht leuchtende LED.)
Die erste Spalte (Port A) von unten nach oben gelesen (Bit 7 bis 0)\\
entspricht der Binärdarstellung von \lstinline{0x1f}: 0001\,1111.
Die dritte Spalte (Port C) von unten nach oben gelesen (Bit 7 bis 0)\\
entspricht der Binärdarstellung von \lstinline{0xfc}: 1111\,1100.
Die zweite und vierte Spalte (Port B und D) von unten nach oben gelesen\\
(Bit 7 bis 0) entsprechen der Binärdarstellung von \lstinline{0x10}: 0001\,0000.
Achtung: Die Zuweisung der Werte an die Ports erfolgt im Programm\\
\emph{nicht\/} in der Reihenfolge A B C D, sondern in der Reihenfolge A B D C.
\end{minipage}\hfill
\begin{minipage}[t]{0.15\textwidth}
\vspace*{-0.5cm}%
\begin{tabular}{cccc}
\x & \o & \o & \o \\
\x & \o & \o & \o \\
\x & \o & \x & \o \\
\x & \o & \x & \o \\
\x & \x & \x & \x \\
\o & \o & \x & \o \\
\o & \o & \x & \o \\
\o & \o & \x & \o \\
\end{tabular}
\end{minipage}
\item[(b)]
\textbf{Wozu dienen die ersten vier Zeilen des Hauptprogramms?}
Mit diesen Zeilen werden alle jeweils 8 Bits aller 4 Ports
als Output-Ports konfiguriert.
\item[(c)]
\textbf{Was würde stattdessen die Zeile \lstinline{DDRA, DDRB, DDRC, DDRD = 0xff;} bewirken?}
Der Komma-Operator in C bewirkt, daß der erste Wert berechnet
und wieder verworfen wird und stattdessen der zweite Wert weiterverarbeitet wird.
Konkret hier hätte das zur Folge,
daß \lstinline{DDRA}, \lstinline{DDRB} und \lstinline{DDRC}
gelesen und die gelesenen Werte ignoriert werden;
anschließend wird \lstinline{DDRD} der Wert \lstinline{0xff} zugewiesen.
Damit würde also nur einer von vier Ports überhaupt konfiguriert.
Da es sich bei den \lstinline{DDR}-Variablen
um \lstinline{volatile}-Variable handelt,
nimmt der Compiler an, daß der Lesezugriff schon irgendeinen Sinn hätte.
Der Fehler bliebe also unbemerkt.
\item[(d)]
\textbf{Schreiben Sie das Programm so um,
daß die durch das Programm dargestellte Figur spiegelverkehrt erscheint.}
Hierzu vertauschen wir die Zuweisungen
an \lstinline{PORTA} und \lstinline{PORTD}
sowie die Zuweisungen
an \lstinline{PORTB} und \lstinline{PORTC}:
\begin{lstlisting}[gobble=8]
PORTD = 0x1f;
PORTC = 0x10;
PORTA = 0x10;
PORTB = 0xfc;
\end{lstlisting}
Damit ergibt sich eine Spiegelung an der vertikalen Achse.
Alternativ kann man auch an der horizontalen Achse spiegeln.
Dafür muß man die Bits in den Hexadezimalzahlen umdrehen:
\begin{lstlisting}[gobble=8]
PORTA = 0xf8;
PORTB = 0x08;
PORTD = 0x08;
PORTC = 0x3f;
\end{lstlisting}
Die Frage, welche der beiden Spiegelungen gewünscht ist,
wäre übrigens \emph{auch in der Klausur zulässig}.
\item[(e)]
\textbf{Wozu dient das \lstinline{while (1)}?}
Mit dem \lstinline{return}-Befehl am Ende des Hauptprogramms
gibt das Programm die Kontrolle an das Betriebssystem zurück.
Dieses Programm jedoch läuft auf einem Mikrocontroller,
auf dem es kein Betriebssystem gibt.
Wenn das \lstinline{return} ausgeführt würde,
hätte es ein undefiniertes Verhalten zur Folge.
Um dies zu verhindern, endet das Programm in einer Endlosschleife,
mit der wir den Mikrocontroller anweisen,
nach der Ausführung des Programms \emph{nichts mehr\/} zu tun
(im Gegensatz zu: \emph{irgendetwas Undefiniertes\/} zu tun).
\end{itemize}
\exercise{LED-Blinkmuster}
Wir betrachten das folgende Programm für einen ATmega32-Mikro-Controller
(Datei: \gitfile{hp}{2023ws/20231109}{aufgabe-3.c}).
\begin{minipage}[t]{7cm}
\begin{lstlisting}[gobble=6]
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
uint8_t counter = 1;
uint8_t leds = 0;
ISR (TIMER0_COMP_vect)
{
if (counter == 0)
{
leds = (leds + 1) % 8;
PORTC = leds << 4;
}
counter++;
}
\end{lstlisting}
\end{minipage}\hfill\begin{minipage}[t]{8.5cm}
\begin{lstlisting}[gobble=6]
void init (void)
{
cli ();
TCCR0 = (1 << CS01) | (1 << CS00);
TIMSK = 1 << OCIE0;
sei ();
DDRC = 0x70;
}
int main (void)
{
init ();
while (1)
; /* do nothing */
return 0;
}
\end{lstlisting}
\end{minipage}
An die Bits Nr.\ 4, 5 und 6 des Output-Ports C des Mikro-Controllers sind LEDs angeschlossen.\\
Sobald das Programm läuft, blinken diese in charakteristischer Weise:
\begin{quote}
\newcommand{\tdn}[1]{\raisebox{-2pt}{#1}}
\begin{tabular}{|c|c|c|c|}\hline
\tdn{Phase} & \tdn{LED oben (rot)} & \tdn{LED Mitte (gelb)} & \tdn{LED unten (grün)} \\[2pt]\hline
1 & aus & aus & an \\\hline
2 & aus & an & aus \\\hline
3 & aus & an & an \\\hline
4 & an & aus & aus \\\hline
5 & an & aus & an \\\hline
6 & an & an & aus \\\hline
7 & an & an & an \\\hline
8 & aus & aus & aus \\\hline
\end{tabular}
\end{quote}
Jede Phase dauert etwas länger als eine halbe Sekunde.
Nach 8 Phasen wiederholt sich das Schema.
Erklären Sie das Verhalten des Programms anhand des Quelltextes:
\vspace{-\medskipamount}
\begin{itemize}\itemsep0pt
\item[(a)]
Wieso macht das Programm überhaupt etwas,
wenn doch das Hauptprogramm nach dem Initialisieren lediglich eine Endlosschleife ausführt,
in der \emph{nichts} passiert?
\points{1}
\item[(b)]
Wieso wird die Zeile \lstinline|PORTC = leds << 4;| überhaupt aufgerufen,
wenn dies doch nur unter der Bedingung \lstinline|counter == 0| passiert,
wobei die Variable \lstinline|counter| auf 1 initialisiert,
fortwährend erhöht und nirgendwo zurückgesetzt wird?
\points{2}
\item[(c)]
Wie kommt das oben beschriebene Blinkmuster zustande?
\points{2}
\item[(d)]
Wieso dauert eine Phase ungefähr eine halbe Sekunde?
\points{2}
\item[(e)]
Was bedeutet "`\lstinline|ISR (TIMER0_COMP_vect)|"'?
\points{1}
\end{itemize}
\goodbreak
Hinweis:
\vspace{-\medskipamount}
\begin{itemize}\itemsep0pt
\item
Die Funktion \lstinline|init()| sorgt dafür, daß der Timer-Interrupt Nr.\ 0 des Mikro-Controllers
etwa 488mal pro Sekunde aufgerufen wird.
Außerdem initialisiert sie die benötigten Bits an Port C als Output-Ports.
Sie selbst brauchen die Funktion \lstinline|init()| nicht weiter zu erklären.
\end{itemize}
\solution
\begin{itemize}\itemsep0pt
\item[(a)]
\textbf{Wieso macht das Programm überhaupt etwas,
wenn doch das Hauptprogramm nach dem Initialisieren lediglich eine Endlosschleife ausführt,
in der \emph{nichts} passiert?}
Das Blinken wird durch einen Interrupt-Handler implementiert.
Dieser wird nicht durch das Hauptprogramm,
sondern durch ein Hardware-Ereignis (hier: Uhr) aufgerufen.
\item[(b)]
\textbf{Wieso wird die Zeile \lstinline|PORTC = leds << 4;| überhaupt aufgerufen,
wenn dies doch nur unter der Bedingung \lstinline|counter == 0| passiert,
wobei die Variable \lstinline|counter| auf 1 initialisiert,
fortwährend erhöht und nirgendwo zurückgesetzt wird?}
Die vorzeichenlose 8-Bit-Variable \lstinline{counter} kann nur
Werte von 0 bis 255 annehmen; bei einem weiteren
Inkrementieren springt sie wieder auf 0 (Überlauf),
und die \lstinline{if}-Bedingung ist erfüllt.
\item[(c)]
\textbf{Wie kommt das oben beschriebene Blinkmuster zustande?}
In jedem Aufruf des Interrupt-Handlers wird die Variable
\lstinline{leds} um 1 erhöht und anschließend modulo 8 genommen.
Sie durchläuft daher immer wieder die Zahlen von 0 bis 7.
Durch die Schiebeoperation \lstinline{leds << 4} werden die 3 Bits
der Variablen \lstinline{leds} an diejenigen Stellen im Byte
geschoben, an denen die LEDs an den Mikro-Controller
angeschlossen sind (Bits 4, 5 und 6).
Entsprechend durchläuft das Blinkmuster immer wieder
die Binärdarstellungen der Zahlen von 0 bis 7
(genauer: von 1 bis 7 und danach 0).
\item[(d)]
\textbf{Wieso dauert eine Phase ungefähr eine halbe Sekunde?}
Der Interrupt-Handler wird gemäß Hinweis 488mal pro Sekunde aufgerufen.
Bei jedem 256sten Aufruf ändert sich das LED-Muster.
Eine Phase dauert somit $\frac{256}{488} \approx 0.52$ Sekunden.
\item[(e)]
\textbf{Was bedeutet "`\lstinline|ISR (TIMER0_COMP_vect)|"'?}
Deklaration eines Interrupt-Handlers für den Timer-Interrupt Nr.\ 0
\end{itemize}
\end{document}
File added
% hp-uebung-20231109.pdf - Exercises on Low-Level Programming / Applied Computer Sciences
% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Peter Gerwinski
%
% This document is free software: you can redistribute it and/or
% modify it either under the terms of the Creative Commons
% Attribution-ShareAlike 3.0 License, or under the terms of the
% GNU General Public License as published by the Free Software
% Foundation, either version 3 of the License, or (at your option)
% any later version.
%
% This document is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this document. If not, see <http://www.gnu.org/licenses/>.
%
% You should have received a copy of the Creative Commons
% Attribution-ShareAlike 3.0 Unported License along with this
% document. If not, see <http://creativecommons.org/licenses/>.
% README: Text-Grafik-Bibliothek, Mikrocontroller, LED-Blinkmuster
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
\thispagestyle{empty}
\section*{Hardwarenahe Programmierung\\
Übungsaufgaben -- 9.\ November 2023}
Diese Übung enthält Punkteangaben wie in einer Klausur.
Um zu "`bestehen"', müssen Sie innerhalb von 80 Minuten
unter Verwendung ausschließlich zugelassener Hilfsmittel
14 Punkte (von insgesamt \totalpoints) erreichen.
\exercise{Text-Grafik-Bibliothek}
\begin{minipage}[t]{0.45\textwidth}
Schreiben Sie eine Bibliothek für "`Text-Grafik"' mit folgenden Funktionen:\vspace*{-\medskipamount}
\begin{itemize}
\item
\lstinline|void clear (char c)|\\
Bildschirm auf Zeichen \lstinline|c| löschen,\\
also komplett mit diesem Zeichen\\
(z.\,B.: Leerzeichen) füllen
\item
\lstinline|void put_point (int x, int y, char c)|\\
Punkt setzen (z.\,B.\ einen Stern (\lstinline{*})\\
an die Stelle $(x,y)$ "`malen"')
\item
\lstinline|char get_point (int x, int y)|\\
Punkt lesen
% \item
% \lstinline|void fill (int x, int y, char c, char o)|\\
% Fläche in der "`Farbe"' \lstinline|o|,
% die den Punkt \lstinline|(x, y)| enthält,
% mit der "`Farbe"' \lstinline|c| ausmalen
\item
\lstinline|void display (void)|\\
das Gezeichnete auf dem Bildschirm\\
ausgeben
\end{itemize}
\points{8}
\end{minipage}\hfill
\begin{minipage}[t]{0.45\textwidth}
\strut\\[-1.2cm]
Hinweise:\vspace*{-\medskipamount}
\begin{itemize}
\item
Eine C-Bibliothek besteht aus (mindestens)
einer \file{.h}-Datei und einer \file{.c}-Datei.
\item
Verwenden Sie ein Array als "`Bildschirm"'.
Vor dem Aufruf der Funktion \lstinline|display()| ist nichts zu sehen;
alle Grafikoperationen erfolgen auf dem Array.
\item
Verwenden Sie Präprozessor-Konstante,
z.\,B.\ \lstinline{WIDTH} und \lstinline{HEIGHT},
um Höhe und Breite des "`Bildschirms"' festzulegen, z.\,B.:
\begin{lstlisting}[gobble=8]
#define WIDTH 72
#define HEIGHT 24
\end{lstlisting}
\item
Schreiben Sie zusätzlich ein Test-Pro\-gramm,
das alle Funktionen der Bibliothek benutzt,
um ein hübsches Bild (z.\,B.\ ein stilisiertes Gesicht -- "`Smiley"')
auszugeben.
\end{itemize}
\end{minipage}
\exercise{Mikrocontroller}
\begin{minipage}[t]{10cm}
An die vier Ports eines ATmega16-Mikrocontrollers sind Leuchtdioden angeschlossen:
\begin{itemize}
\item
von links nach rechts an die Ports A, B, C und D,
\item
von oben nach unten an die Bits Nr.\ 0 bis 7.
\end{itemize}
Wir betrachten das folgende Programm (\gitfile{hp}{2023ws/20231109}{aufgabe-2.c}):
\begin{lstlisting}[gobble=6]
#include <avr/io.h>
int main (void)
{
DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0xff;
PORTA = 0x1f;
PORTB = 0x10;
PORTD = 0x10;
PORTC = 0xfc;
while (1);
return 0;
}
\end{lstlisting}
\end{minipage}\hfill
\begin{minipage}[t]{3cm}
\strut\\[-\baselineskip]
\includegraphics[width=3cm]{leds.jpg}
\end{minipage}
\vspace*{-3cm}
\strut\hfill
\begin{minipage}{11.8cm}
\begin{itemize}
\item[(a)]
Was bewirkt dieses Programm? \points{4}
\item[(b)]
Wozu dienen die ersten vier Zeilen des Hauptprogramms? \points{2}
\item[(c)]
Was würde stattdessen die Zeile \lstinline{DDRA, DDRB, DDRC, DDRD = 0xff;} bewirken?
\points{2}
\item[(d)]
Schreiben Sie das Programm so um,
daß die durch das Programm dargestellte Figur spiegelverkehrt erscheint. \points{3}
\item[(e)]
Wozu dient das \lstinline{while (1)}? \points{2}
\item
Alle Antworten bitte mit Begründung.
\end{itemize}
\end{minipage}
\exercise{LED-Blinkmuster}
Wir betrachten das folgende Programm für einen ATmega32-Mikro-Controller
(Datei: \gitfile{hp}{2023ws/20231109}{aufgabe-3.c}).
\begin{minipage}[t]{7cm}
\begin{lstlisting}[gobble=6]
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
uint8_t counter = 1;
uint8_t leds = 0;
ISR (TIMER0_COMP_vect)
{
if (counter == 0)
{
leds = (leds + 1) % 8;
PORTC = leds << 4;
}
counter++;
}
\end{lstlisting}
\end{minipage}\hfill\begin{minipage}[t]{8.5cm}
\begin{lstlisting}[gobble=6]
void init (void)
{
cli ();
TCCR0 = (1 << CS01) | (1 << CS00);
TIMSK = 1 << OCIE0;
sei ();
DDRC = 0x70;
}
int main (void)
{
init ();
while (1)
; /* do nothing */
return 0;
}
\end{lstlisting}
\end{minipage}
An die Bits Nr.\ 4, 5 und 6 des Output-Ports C des Mikro-Controllers sind LEDs angeschlossen.\\
Sobald das Programm läuft, blinken diese in charakteristischer Weise:
\begin{quote}
\newcommand{\tdn}[1]{\raisebox{-2pt}{#1}}
\begin{tabular}{|c|c|c|c|}\hline
\tdn{Phase} & \tdn{LED oben (rot)} & \tdn{LED Mitte (gelb)} & \tdn{LED unten (grün)} \\[2pt]\hline
1 & aus & aus & an \\\hline
2 & aus & an & aus \\\hline
3 & aus & an & an \\\hline
4 & an & aus & aus \\\hline
5 & an & aus & an \\\hline
6 & an & an & aus \\\hline
7 & an & an & an \\\hline
8 & aus & aus & aus \\\hline
\end{tabular}
\end{quote}
Jede Phase dauert etwas länger als eine halbe Sekunde.
Nach 8 Phasen wiederholt sich das Schema.
Erklären Sie das Verhalten des Programms anhand des Quelltextes:
\vspace{-\medskipamount}
\begin{enumerate}[\quad(a)]
\item
Wieso macht das Programm überhaupt etwas,
wenn doch das Hauptprogramm nach dem Initialisieren lediglich eine Endlosschleife ausführt,
in der \emph{nichts} passiert?
\points{1}
\item
Wieso wird die Zeile \lstinline|PORTC = leds << 4;| überhaupt aufgerufen,
wenn dies doch nur unter der Bedingung \lstinline|counter == 0| passiert,
wobei die Variable \lstinline|counter| auf 1 initialisiert,
fortwährend erhöht und nirgendwo zurückgesetzt wird?
\points{2}
\item
Wie kommt das oben beschriebene Blinkmuster zustande?
\points{2}
\item
Wieso dauert eine Phase ungefähr eine halbe Sekunde?
\points{2}
\item
Was bedeutet "`\lstinline|ISR (TIMER0_COMP_vect)|"'?
\points{1}
\end{enumerate}
Hinweis:
\vspace{-\medskipamount}
\begin{itemize}\itemsep0pt
\item
Die Funktion \lstinline|init()| sorgt dafür, daß der Timer-Interrupt Nr.\ 0 des Mikro-Controllers
etwa 488mal pro Sekunde aufgerufen wird.
Außerdem initialisiert sie die benötigten Bits an Port C als Output-Ports.
Sie selbst brauchen die Funktion \lstinline|init()| nicht weiter zu erklären.
\end{itemize}
\begin{flushright}
\textit{Viel Erfolg!}
\end{flushright}
\makeatletter
\immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
\makeatother
\end{document}
../common/io-ports-and-interrupts.pdf
\ No newline at end of file
../common/leds.jpg
\ No newline at end of file
../common/logo-hochschule-bochum-cvh-text-v2.pdf
\ No newline at end of file
../common/logo-hochschule-bochum.pdf
\ No newline at end of file
../common/pgscript.sty
\ No newline at end of file
../common/pgslides.sty
\ No newline at end of file
#include <stdio.h>
#include "textgraph.h"
int main (void)
{
clear (' ');
put_point (-5, 10, 'X');
for (int i = 17; i < 23; i++)
put_point (i, 5, '*');
put_point (15, 6, '*');
put_point (14, 7, '*');
put_point (13, 8, '*');
put_point (13, 9, '*');
put_point (14, 10, '*');
put_point (15, 11, '*');
for (int i = 17; i < 23; i++)
put_point (i, 12, '*');
put_point (24, 11, '*');
put_point (25, 10, '*');
put_point (26, 9, '*');
put_point (26, 8, '*');
put_point (25, 7, '*');
put_point (24, 6, '*');
put_point (18, 8, 'O');
put_point (21, 8, 'O');
put_point (17, 10, '`');
for (int i = 18; i < 22; i++)
put_point (i, 10, '-');
put_point (22, 10, '\'');
put_point (13, 42, 'Y');
printf ("get_point (%d, %d): '%c'\n", 13, 9, get_point (13, 9));
printf ("get_point (%d, %d): '%c'\n", 14, 9, get_point (14, 9));
printf ("get_point (%d, %d): '%c'\n", 94, 9, get_point (94, 9));
display ();
return 0;
}
#include <stdio.h>
#include "textgraph.h"
char buffer[HEIGHT][WIDTH];
void clear (char c)
{
for (int y = 0; y < HEIGHT; y++)
for (int x = 0; x < WIDTH; x++)
buffer[y][x] = c;
}
static int check_coordinates (int x, int y, char *function)
{
if (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT)
return 1;
else
{
fprintf (stderr, "coordinates (%d,%d) out of range in %s\n", x, y, function);
return 0;
}
}
void put_point (int x, int y, char c)
{
if (check_coordinates (x, y, "put_point"))
buffer[y][x] = c;
}
char get_point (int x, int y)
{
if (check_coordinates (x, y, "get_point"))
return buffer[y][x];
else
return 0;
}
void display (void)
{
for (int y = 0; y < HEIGHT; y++)
{
for (int x = 0; x < WIDTH; x++)
printf ("%c", buffer[y][x]);
printf ("\n");
}
}
#ifndef TEXTGRAPH_H
#define TEXTGRAPH_H
#define WIDTH 40
#define HEIGHT 20
extern void clear (char c);
extern void put_point (int x, int y, char c);
extern char get_point (int x, int y);
extern void display (void);
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment