Dies ist eine alte Version des Dokuments!


2. Sound und Timer

Nach dieser Lektion sollten Sie:

  1. wissen, wie man im Atmel Studio eine Puls-Signal ausgibt
I. Vorarbeiten
  1. Laden Sie folgende Datei herunter:
II. Analyse des fertigen Programms
  1. Initialisieren des Programms
    1. Öffnen Sie SimulIDE und öffnen Sie dort mittels simulide_open.jpg die Datei 2_sound.simu
    2. Laden Sie 2_sound.hex als firmware auf den 328 Chip
  2. Betrachtung der neuen Komponenten
    1. In der Simulation sind nun neben der LED weitere Komponenten zu sehen, die im Folgenden erklärt werden sollen
      1. ein Display Hd44780
      2. zwei Frequenzmesser, mit der Anzeige 0Hz
      3. ein Lautsprecher mit Schalter
      4. ein Oszilloskop
    2. Starten Sie die Simulation
      1. Wenn Sie die Lautsprecher des PCs aktiv haben, werden Sie ein Knacken (und ggf. Brummen) vernehmen. Dies rührt von der unvollständigen Simulation her. Wenn Sie den den Schalter vor dem Lautsprecher schließen, so sollten Sie - zusätzlich zum Knacken - einen aufsteigenden und abfallenden Ton hören. Es ist möglich, dass dieser nach wenigen Sekunden aufhört, auch das ist eine Eigenschaft der unvollständigen Simulation.
      2. Am Frequenzmesser ist dennoch zu sehen, dass ein Signal mit Frequenzen zwischen $375...1600Hz$ ausgegeben wird.
      3. Im Gegensatz dazu scheint das Oszilloskopbild still zu stehen und keine variierende Frequenz anzuzeigen. Um dies zu beheben, sollte am Oszilloskop der Haken bei Aut bzw. Auto entfernt werden. Nun ist eine Einstellung der x- und y-Werte über die Drehregler möglich.
      4. Die LED zeigt nun an, ob es sich um einen Aufsteigenden oder abfallenden Ton handelt
      5. Das Display zeigt zusätzlich an, welches Experiment geladen ist
    3. Das Programm zu diesem Hexfile soll nun erstellt werden
II. Eingabe in Atmel Studio
  1. öffnen Sie Atmel Studio
  2. legen Sie ein neues „GCC C Executable Project“ mit dem Namen 2_sound für einen ATmega328 an
  1. Eingabe und Kompilieren des Code
    1. Ersetzen Sie den vorhandenen Code, durch den rechts stehenden Code
    2. Kompilieren Sie den Code durch Build » Build solution
    3. Im unteren Teil des Fensters sollte nun die Ausgabe des Kompilers sichtbar werden. Diese sollte ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ========== lauten
  2. Auswählen der hex-Datei
    1. im Atmel Studio finden Sie rechts im Fenster den „Solution Explorer“
    2. gehen Sie dort im Solution Explorer zu Solution » Einfuehrung_v01 » Output Files
    3. klicken Sie mit rechter Maustaste auf Einfuehrung_v01.hex und wählen Sie Pfad und Name aus
III. Ausführung in Simulide
  1. Öffnen Sie SimulIDE (unter …\bin\simulide.exe)
    1. links in SimulIDE sollten Sie den Komponenten Browser finden. Wählen Sie dort Micro»AVR»atmega»atmega328
    2. Ziehen Sie den Eintrag atmega328 per Drag and Drop in den Arbeitsbereich (rechter, beiger Teil des Fensters)
    3. Es sollte nun ein Chip names atmega328-1 dargestellt sein
  2. Erstellen der Ausgangsschaltung
    1. Im Programm wurde im auf PortD das 6bit angesprochen. Entsprechend soll auch hier am Port D der Ausgang 6 genutzt werden. Am Chip ist dieser mit D6 gekennzeichnet
    2. Fügen Sie eine LED (im Komponenten Browser über Output LED) und ein Massepotential ein (Sources Ground)
    3. Die Komponenten können mit dem Kontextmenu (Rechtsklick) gedreht und gespiegelt werden. Außerdem ist mit der Auswahl von Properties im Kontextmenu die Änderung von
    4. Verbinden Sie die LED mit Masse und mit Port D6. Achten Sie auf die richtige Richtung der LED. Die Verbindungen lassen sich dadurch erstellen, dass auf ein Komponenten-Pin geklickt wird und die Linie zu einem nächsten Komponenten-Pin gezogen wird.
  3. Flashen der Software
    1. Klicken Sie rechts auf den Microcontroller und wählen Sie Load firmware
    2. Fügen Sie hier den Pfad und Name des oben erstellten Einfuehrung_v01.hex ein und öffnen Sie dieses
  4. Starten der Simulation
    1. klicken Sie im Menu den Power-on Button
    2. Die Simulation startet
  5. Bugfixing
    1. vermutlich ist bei Ihnen zu sehen, dass die Diode nicht gleichmäßig an und aus dargestellt wird. Dies ist kein Fehler des Simulationsprogramms. Es wurde noch eine wichtige Komponente vergessen, welche immer bei der Verwendung von diskreten LEDs verwendet werden muss. Fügen Sie diese ein und Testen Sie die Schaltung nochmal


Sie sollten sich nach der Übung die ersten Kenntnisse mit dem Umgang der Umgebung angeeignet haben. Zum Festigen des der Fähigkeiten bieten sich folgende Aufgaben an:

Aufgaben
  1. Welche Vorgaben für die Softwareentwicklung wurden verletzt, trotzdem das Programm lauffähig ist? (Interrupts werden erst in späteren Übungen erklärt)
  2. Wie könnte ein Ampel-Licht-Abfolge oder Lauflicht aus 4 Dioden erstellt und programmiert werden? Welche Optimierungen könnten im Code vorgenommen werden? Welche Komponente in SimulIDE kann genutzt werden? Wie kann die Farbe der LEDs geändert werden?
  3. Lesen Sie auf Mikrocontroller.net im Kapitel Warteschleifen die „erste Seite“, also bis:
Abhängig von der Version der Bibliothek verhalten sich die Bibliotheksfunktionen etwas unterschiedlich.
main.c
  1. /*=============================================================================
  2.  
  3. Experiment 2: Sound-Generator
  4. ============= ===============
  5.  
  6. Dateiname: 2_Sound.c
  7.  
  8. Autoren : Peter Blinzinger
  9. Prof. G. Gruhler (Hochschule Heilbronn, Fakultät T1)
  10. D. Chilachava (Georgische Technische Universität)
  11.  
  12. Version: 1.2 vom 01.05.2020
  13.  
  14. Hardware: MEXLE2020 Ver. 1.0 oder höher
  15. AVR-USB-PROGI Ver. 2.0
  16.  
  17. Software: Entwicklungsumgebung: AtmelStudio 7.0
  18. C-Compiler: AVR/GNU C Compiler 5.4.0
  19.  
  20. Funktion: Auf dem kleinen Lautsprecher des MiniMEXLE-Boards (Buzzer)
  21. wird ein sirenenartiger Sound ausgegeben. Zwischen den auf-
  22. und absteigenden Tönen bleibt die Frequenz kurz stabil.
  23. Die Frequenz wird mit dem Timer 0 (im CTC-Mode) erzeugt und
  24. direkt über den Output-Compare-Pin im Toggle-Mode ausgegeben.
  25.  
  26. Displayanzeige: +----------------+
  27. |- Experiment 2 -|
  28. | Creating Sound |
  29. +----------------+
  30.  
  31. Tastenfunktion: keine
  32.  
  33. Jumperstellung: Schalter muss fuer den Buzzer betätigt sein
  34.  
  35. Fuses im uC: CKDIV8: Aus (keine generelle Vorteilung des Takts)
  36.  
  37. Header-Files: lcd_lib_de.h (Library zur Ansteuerung LCD-Display Ver. 1.3)
  38.  
  39. =============================================================================*/
  40.  
  41. // Deklarationen ==============================================================
  42.  
  43. // Festlegung der Quarzfrequenz
  44. #ifndef F_CPU // optional definieren
  45. #define F_CPU 12288000UL // MiniMEXLE mit 12,288 MHz Quarz
  46. #endif
  47.  
  48. // Include von Header-Dateien
  49. #include <avr/io.h> // I/O Konfiguration (intern weitere Dateien)
  50. #include <util/delay.h> // Definition von Delays (Wartezeiten)
  51. #include "lcd_lib_de.h" // Funktionsbibliothek zum LCD-Display
  52.  
  53. // Konstanten
  54. #define MIN_PER 59 // minimale Periodendauer in "Timerticks"
  55. #define MAX_PER 255 // maximale Periodendauer in "Timerticks"
  56. #define WAIT_TIME 2000 // Wartezeit zwischen Flanken in ms
  57.  
  58. // Makros
  59. #define SET_BIT(PORT, BIT) ((PORT) |= (1 << (BIT))) // Port-Bit Setzen
  60. #define CLR_BIT(PORT, BIT) ((PORT) &= ~(1 << (BIT))) // Port-Bit Loeschen
  61. #define TGL_BIT(PORT, BIT) ((PORT) ^= (1 << (BIT))) // Port-Bit Toggeln
  62.  
  63. // Funktionsprototypen
  64. void initDisplay(void); // Initialisierung Display und Startanzeige
  65. void initPorts(void); // Initialisierung der I/O-Ports
  66. void initTimer(void); // Timer 0 initialisieren (Soundgenerierung)
  67. void init(void); // generelle Initialisierungsfunktion
  68.  
  69. // Hauptprogramm ==============================================================
  70. int main()
  71. {
  72. init(); // Ports und Timer 0 initialisieren
  73. initDisplay(); // Display aktivieren
  74.  
  75. while(1) // Start der unendlichen Schleife
  76. {
  77. for (OCR0A=MAX_PER; OCR0A>MIN_PER; OCR0A--) // Frequenz erhöhen
  78. {
  79. _delay_ms(10); // in Schritten von 10ms
  80. }
  81. _delay_ms(WAIT_TIME); // Wartezeit hohe Frequenz
  82. TGL_BIT(PORTB,DDB0);
  83.  
  84. for (OCR0A=MIN_PER; OCR0A<MAX_PER; OCR0A++) // Frequenz absenken
  85. {
  86. _delay_ms(10); // in Schritten von 10 ms
  87. }
  88. _delay_ms(WAIT_TIME); // Wartezeit niedrige Frequenz
  89. TGL_BIT(PORTB,DDB0);
  90. } // Ende der unendlichen Schleife
  91. }
  92.  
  93. // Funktionen =================================================================
  94.  
  95. // Initialisierung der I/O-Ports
  96. void initPorts()
  97. {
  98. DDRB |= (1<<DDB0); // Port B, Pin 0 (zur LED) auf Ausgang
  99. DDRD |= (1<<DDD5); // Port D, Pin 5 (zum Buzzer) auf Ausgang
  100. }
  101.  
  102. // Intialisierung des Timers 0 fuer Sounderzeugung
  103. void initTimer()
  104. {
  105. TCCR0A = (1<<WGM01) |(1<<COM0B0); // CTC Mode waehlen
  106. TCCR0B = (1<<CS01 | 1<<CS00); // Timer-Vorteiler /64
  107.  
  108. OCR0A = MAX_PER; // Start mit tiefstem Ton
  109. }
  110.  
  111. // Initialisierung der Display-Anzeige
  112. void initDisplay() // Start der Funktion
  113. {
  114. lcd_init(); // Initialisierungsroutine aus der lcd_lib
  115.  
  116. lcd_gotoxy(0,0); // Cursor auf 1. Zeile, 1. Zeichen
  117. lcd_putstr("- Experiment 2 -"); // Ausgabe Festtext: 16 Zeichen
  118.  
  119. lcd_gotoxy(1,0); // Cursor auf 2. Zeile, 1. Zeichen
  120. lcd_putstr(" Creating Sound "); // Ausgabe Festtext: 16 Zeichen
  121.  
  122. } // Ende der Funktion
  123.  
  124. // Generelle Initialisierungsfunktion
  125. void init()
  126. {
  127. initPorts(); // Ports auf Ausgang schalten
  128. initTimer(); // Timer zur Sounderzeugung starten
  129. }

Abb. ##: einfache Diodenschaltung in SimulIDE microcontrollertechnik:simulide_einfache_diodenschaltung.png