\documentclass[11pt,a4paper]{article}
\usepackage[ansinew]{inputenc}
\usepackage[margin=2.5cm,nohead]{geometry}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{wasysym}
\usepackage{ngerman,latexsym,alltt,graphicx,textcomp}
\usepackage[bookmarks, colorlinks=false, pdftitle={MRT II Praktikumsprotokoll},
pdfauthor={Fabian Kurz, http://fkurz.net/}, pdfsubject={Phasenanschnitt}, pdfkeywords={TU Dresden, Praktikum, Mikrorechentechnik}, linkbordercolor={1 1 1}]{hyperref}
\date{18. April 2005}
\author{Gruppe 50:\\Marcel~Junige, Fabian~Kurz\\Martin~Laabs, Lars Lindenmüller}
\title{Praktikumsprotokoll Mikrorechentechnik II --\\
"`Echtzeitsteuerung eines Wechselstromstellers\\mit einem Mikrocontroller"'}
\begin{document}
\setcounter{secnumdepth}{4}
\maketitle
\tableofcontents
\newpage
\section{Aufgabenstellung}
Aufgabe des Praktikums war die Realisierung eines Wechselstromstellers mit
Hilfe eines Mikrocontrollers. Dieser arbeitet nach dem Prinzip des
Phasenanschnitts: Der Wechselspannung wird erst nach Erreichen eines einstellbaren
Steuerwinkels $\alpha$ durch Z\"unden eines Triacs eingeschaltet. Es
ergibt sich ein von $\alpha$
abh\"angiger Effektivwert der Spannung, der der Beziehung
\begin{equation}
U_{\mathrm{eff}} = U \cdot \sqrt{\frac{1}{\pi}
\int\limits_{\vartheta=\alpha}^{\pi}\left(\sqrt 2 \sin \vartheta\right)^2
\,d\vartheta} = U \cdot \sqrt{\frac 1 {\pi} \left(\pi - \alpha - \frac 1 2
\sin(2\alpha)\right)}
\end{equation}
folgt. Sobald der notwendige Haltestrom des Triacs unterschritten wird sperrt
dieser wieder. Bei rein ohmscher Last erfolgt dies unmittelbar vor dem
Spannungsnulldurchgang, jedoch treten in der Praxis meist ohmsch-induktive
Lasten (Lampen, Motoren, \ldots) auf, bei denen der Stromverlauf gegen\"uber
dem Spannunsgverlauf zeitlich verschoben ist. Der minimale Steuerwinkel
$\alpha$ wird durch die \"Uberlappung des Stromes in die n\"achste Halbwelle 
begrenzt.

Bild \ref{block} stellt die Versuchsanordnung schematisch dar. Am 
Mikrokontroller sind Strom- und Spannungsdurchgangssensoren sowie ein Ausgang
zur Z\"undung des Triacs angeschlossen. Zus\"atzlich sind zwei Taster zur
Einstellung des Phasenwinkels und zwei LEDs als Statusanzeige vorhanden. Im
Versuch wurde als ohmsc-induktive Last eine Gl\"uhbirne benutzt.

\begin{figure}
\center
\begin{picture}(300,170)
\put(50,60){\circle{20}}
\put(50,59){\makebox(0,0)[c]{$\sim$}}
\put(20,65){\makebox(0,0)[c]{$230\,\mathrm V$}}
\put(20,54){\makebox(0,0)[c]{$50\,\mathrm{Hz}$}}
\multiput(50,10)(0,60){2}{\line(0,1){40}}
\put(50,10){\line(1,0){200}}
\put(250,60){\circle{20}}
\multiput(250,10)(0,60){2}{\line(0,1){40}}
\put(243,53){\line(1,1){14}}
\put(243,67){\line(1,-1){14}}
\put(50,110){\line(1,0){100}}
\multiput(130,95)(60,0){2}{\line(0,1){30}}
\multiput(130,95)(0,30){2}{\line(1,0){60}}
\put(150,110){\circle*{2}}
\put(150,110){\line(2,1){20}}
\put(170,110){\line(1,0){80}}
\put(80,10){\circle{3}}
\put(90,110){\circle{3}}
\put(80,11.5){\line(0,1){143.5}}
\put(90,111.5){\line(0,1){33.5}}
\put(80,155){\vector(1,0){30}}
\put(90,145){\vector(1,0){20}}
\multiput(110,135)(100,0){2}{\line(0,1){30}}
\multiput(110,135)(0,30){2}{\line(1,0){100}}
\put(160,135){\vector(0,-1){10}}
\put(160,150){\makebox(0,0)[c]{Mikrocontroller}}
\put(160,85){\makebox(0,0)[c]{elektronischer Schalter}}
\put(265,60){\makebox(0,0)[l]{Lampe}}
\end{picture}
\label{block}
\caption{Schematische Darstellung des Wechselstromstellers}
\end{figure}

\newpage

\section{Zeitgraph}

Zur Verdeutlichung der Funktionsweise wurde der zeitliche Verlauf aller relevanten Signale des Wechselstromstellers in
Abbildung \ref{zeitgraph} f\"ur einen Einstellwinkel $\alpha$ von
$45\,^{\circ}$ und eine ohmsch-induktive Last dargestellt. 

Die vier Signale sind von oben
nach unten: Ausgang des Strom-Nulldurch\-gangs\-detektors ($U_{I=0}$),
Ausgang des Spannungs-Nulldurchgangsdetek\-tors ($U_{I=0}$), Z\"undsignal des
Triacs ($U_{\mathrm{Triac}}$), Ausgangsstrom ($I_a$) und Ausgangsspannung
($U_a$).

Bez\"uglich der Echtzeitanforderung handelt es sich um "`weiche"' Echtzeit, da
das Verpassen eines Z\"undimpulses oder Nulldurchgangs i.d.R. lediglich zu
einem verminderten Nutzen, nicht jedoch zu einem Totalausfall oder einer
Besch\"adigung des Systems f\"uhrt; nach einer Halbwelle wird wieder
synchronisiert.

\vspace*{2cm}

\begin{figure}[h]
\begin{picture}(425,330)
\put(25,15){\vector(1,0){400}}
\multiput(30,13)(40,0){10}{\line(0,1){4}}
\put(30,5){\makebox(0,0)[c]{$0\,\mathrm{ms}$}}
\put(70,5){\makebox(0,0)[c]{$10\,\mathrm{ms}$}}
\put(110,5){\makebox(0,0)[c]{$20\,\mathrm{ms}$}}
\put(150,5){\makebox(0,0)[c]{$30\,\mathrm{ms}$}}
\put(190,5){\makebox(0,0)[c]{$40\,\mathrm{ms}$}}
\put(230,5){\makebox(0,0)[c]{$50\,\mathrm{ms}$}}
\put(270,5){\makebox(0,0)[c]{$60\,\mathrm{ms}$}}
\put(310,5){\makebox(0,0)[c]{$70\,\mathrm{ms}$}}
\put(350,5){\makebox(0,0)[c]{$80\,\mathrm{ms}$}}

\put(14,80){$U_a$}
\put(30,25){\vector(0,1){65}}
\put(25,55){\vector(1,0){400}}
\multiput(30,53)(40,0){10}{\line(0,1){4}}

\multiput(0,0)(160,0){2}{
\put(50,55){\line(0,1){22.5}}
\qbezier(50,77.5)(60,85)(70,85)
\qbezier(70,85)(90,85)(110,55)
\qbezier(110,55)(115.5,47)(120,42)
\put(120,55){\line(0,-1){13}}

\put(130,55){\line(0,-1){22.5}}
\qbezier(130,32.5)(140,25)(150,25)
\qbezier(150,25)(170,25)(190,55)
\qbezier(190,55)(195.5,63)(200,68)
\put(200,68){\line(0,-1){13}}
}


\put(14,160){$I_a$}
\put(30,105){\vector(0,1){65}}
\put(25,135){\vector(1,0){400}}
\multiput(30,133)(40,0){10}{\line(0,1){4}}

\multiput(0,0)(160,0){2}{
\qbezier(50,135)(63,155)(80,155)
\qbezier(80,155)(102,155)(120,135)

\qbezier(130,135)(143,115)(160,115)
\qbezier(160,115)(182,115)(200,135)
}

\put(0,215){$U_{\mathrm{Triac}}$}
\put(30,185){\vector(0,1){40}}
\put(25,190){\vector(1,0){400}}
\multiput(30,188)(40,0){10}{\line(0,1){4}}
\thicklines\multiput(50,190)(80,0){4}{\line(0,0){25}}\thinlines

\put(0,270){$U_{U=0}$}
\put(30,240){\vector(0,1){40}}
\put(25,245){\vector(1,0){400}}
\multiput(30,243)(40,0){10}{\line(0,1){4}}

\multiput(0,0)(80,0){5}{\multiput(30,245)(2,0){2}{\line(0,1){25}}}
\multiput(32,270)(80,0){4}{\line(1,0){78}}

\put(0,325){$U_{I=0}$}
\put(30,295){\vector(0,1){40}}
\put(25,300){\vector(1,0){400}}
\multiput(30,298)(40,0){10}{\line(0,1){4}}

\multiput(0,55)(80,0){3}{\multiput(120,245)(10,0){2}{\line(0,1){25}}}
\multiput(50,325)(80,0){4}{\line(1,0){70}}
\put(50,300){\line(0,1){25}}
\end{picture}
\label{zeitgraph}
\caption{Zeitgraph der Signale am Wechselstromsteller}
\end{figure}


\newpage

\section{Programmablaufplan}



\begin{figure}[h]
%\begin{minipage}{8cm}
\center
\begin{picture}(255,450)
\put(80,20){\vector(1,0){55}}
\put(80,20){\line(0,1){20}}
\multiput(135,5)(70,0){2}{\line(0,1){30}}
\multiput(135,5)(0,30){2}{\line(1,0){70}}
\put(170,12){\makebox(0,0){LEDs l\"oschen}}
\put(170,27){\makebox(0,0){Triac z\"unden}}
\put(205,20){\line(1,0){20}}
\put(225,20){\line(0,1){400}}
\put(225,420){\vector(-1,0){145}}
\multiput(80,40)(-25,25){2}{\line(1,1){25}}
\multiput(80,40)(25,25){2}{\line(-1,1){25}}
\put(80,71){\makebox(0,0)[c]{Strom}}
\put(80,59){\makebox(0,0)[c]{null?}}
\put(75,30){\makebox(0,0)[r]{ja}}
\put(105,65){\line(1,0){30}}
\put(135,65){\line(0,1){35}}
\put(120,63){\makebox(0,0)[t]{nein}}
\put(135,100){\vector(-1,0){55}}
\put(80,110){\vector(0,-1){20}}
\multiput(30,110)(0,20){2}{\line(1,0){100}}
\multiput(30,110)(100,0){2}{\line(0,1){20}}
\put(80,119){\makebox(0,0)[c]{Verz\"ogerung um $\alpha$}}
\multiput(0,0)(0,70){3}{
\put(77,145){\makebox(0,0)[r]{nein}}
\put(80,150){\vector(0,-1){20}}
\multiput(80,150)(-25,25){2}{\line(1,1){25}}
\multiput(80,150)(25,25){2}{\line(-1,1){25}}
}
\put(80,180){\makebox(0,0)[c]{Taster}}
\put(80,168){\makebox(0,0)[c]{2?}}
\put(80,245){\makebox(0,0)[c]{z\"unden?}}
\put(50,253){\makebox(0,0)[r]{ja}}
\put(80,320){\makebox(0,0)[c]{Taster}}
\put(80,308){\makebox(0,0)[c]{1?}}
\put(55,245){\line(-1,0){35}}
\put(20,245){\line(0,-1){145}}
\put(20,100){\vector(1,0){60}}
\multiput(105,175)(0,140){2}{
\put(0,0){\vector(1,0){30}}
\multiput(30,-15)(60,0){2}{\line(0,1){30}}
\multiput(30,-15)(0,30){2}{\line(1,0){60}}
\put(90,0){\line(1,0){15}}
}
\put(140,165){dekr. $\alpha$ } 
\put(140,177){LED 2 ein}
\put(140,305){inkr. $\alpha$ } 
\put(140,317){LED 1 ein}
\put(210,315){\line(0,-1){175}}
\put(210,140){\vector(-1,0){130}}
\put(80,360){\vector(0,-1){20}}
\put(80,391){\makebox(0,0)[c]{Spng.}}
\put(80,379){\makebox(0,0)[c]{null?}}
\multiput(80,430)(0,35){2}{\vector(0,-1){20}}
\multiput(80,360)(-25,25){2}{\line(1,1){25}}
\multiput(80,360)(25,25){2}{\line(-1,1){25}}
\multiput(50,430)(0,15){2}{\line(1,0){60}}
\multiput(50,430)(60,0){2}{\line(0,1){15}}
\put(80,437.5){\makebox(0,0)[c]{Initialisiere}}
\end{picture}
\label{fluss}


\caption{Flußdiagramm}
\end{figure}
%\end{minipage}
%\hfill
%\begin{minipage}{7cm}
Abbildung \ref{fluss} beschreibt den Programmablauf. Am Anfang  werden die
Initialisierungen des Mikrocontrollers vorgenommen: Variablen f\"ur den
Z\"undwinkel und die Verz\"ogerungsschleife werden definiert und initialisiert, 
der Timer kalibriert, die Options-Register f\"ur die IO-Pins gesetzt (um zu
definieren welche Pins Eing\"ange, welche Ausg\"ange sind) etc.

Danach beginnt die Hauptschleife. Es wird der n\"achste
Spannungsnulldurchgang abgewartet. Nachdem dieser erfolgte, werden die Taster
zur Ver\"anderung des Z\"undwinkels $\alpha$ abgefragt und ggf. der Wert
in einer tempor\"aren Variable inkrementiert oder dekrementiert und die
passende LED eingeschaltet. Dabei wird \"uberpr\"uft und sichergestellt, daß der neue Winkel
noch innerhalb des zul\"assigen Bereiches liegt, also kein \"Uberlauf oder
Unterlauf der Variable stattfindet.   

Bevor der Triac gez\"undet werden darf, wird eine Verz\"ogerungsschleife durchlaufen,
deren L\"ange von $\alpha$ abh\"angt. Diese wird jedoch \"ubersprungen, wenn
nach der Abfrage des ersten Tasters (dunkler) bereits die Bedingung zum
Z\"unden gegeben ist. F\"ur den Fall, daß nach der
Verzögerungsschleife immernoch Strom fließt wird noch auf den nächsten
Stromnulldurchgang gewartet bevor letztendlich gezündet wird. 
Nach erfolgter Zündung werden die LEDs ausgeschaltet und das Programm springt 
zur\"uck zum Anfang. Das Programm wiederholt sich nun mit dem eventuell 
ver\"anderten Winkel $\alpha$.
%\end{minipage}
%\end{figure}


\section{Implementierung}

Das Programm wurde in Assembler f\"ur den 16C505 Mikrocontroller geschrieben.
Dieser hat einen sehr \"uberschaubaren Befehlssatz, der jedoch f\"ur diese
Anwendung v\"ollig ausreichend ist. 

\bigskip

\noindent Es folgt der kommentierte Quelltext

\begin{verbatim}
;**********************************************************************
; DATEINAME phasenanschnitt_1.asm
;**********************************************************************
; PROZESSOR PIC 16C505
; PINBELEGUNG
;   Vcc 1-*-14 Vss
;       2   13 Spannungsnulldurchgangserfassung
;       3   12 Stromnulldurchgangserfassung
;       4   11 LED1
;       5   10 LED2
;       6   9  Taster1
; Triac 7   8  Taster2
;**********************************************************************
; Praktikumsversuch     "Echtzeitsteuerung eines Wechselstromstellers 
;                         mit einem PIC Mikrocontroller"
;
; Gruppe 50:            Marcel Junige, Fabian Kurz
;                       Martin Laabs, Lars Lindenmüller
;**********************************************************************
LIST P=16C505             ; Festlegung des verwendeten Prozessors
#include <P16c505.inc>    ; Verwendung von vorgegebenen Variablennamen
                          ; für den Mikrocontroller

;****** Variablen Definitionen ****************************************
wait    equ 08h           ; Hilfsregister für Unterprogramm "warten"
zuend   equ 09h           ; In diesem Register steht der Zündwinkel, 
                          ; absolut, als vielfaches von 38cyc
zneu    equ 0Ah           ; Register für etwaigen neuen Zündwinkel    

;****** BIT Definitionen **********************************************
#DEFINE _Unull PORTB,0      ; Spannungsnulldurchgang
#DEFINE _Inull PORTB,1      ; Stromnulldurchgang
#DEFINE _triac PORTC,3      ; Ansteuerung Triac
#DEFINE _Taster1 PORTC,1    ; dunkler
#DEFINE _Taster2 PORTC,2    ; heller
#DEFINE _LED1 PORTB,2       ; LED1
#DEFINE _LED2 PORTC,0       : LED2

;****** Start Vector **************************************************
    ORG 01FFh ; Reset Adresse
GOTO MAIN
    ORG 0000h ; Start Adresse
GOTO MAIN ; Sprung zum Hauptprogramm

;##### Hauptprogramm ################################################

;****** Initialisiere PIC *********************************************
MAIN
    MOVWF OSCCAL        ; Timer kalibrieren
    CLRWDT              ; Clear Watchdog Timer
    MOVLW b'00000001'
    OPTION              ; setzt OPTION Register mit folgenden Werten
                        ; Bit7 wake-up on pin-change,
                        ; Bit6 weak pull-ups
                        ; Bit5 Timer0 on internal instruction clock,
                        ; Bit3 prescaler to Timer0
                        ; Bit0-2: Prescaler rate 1:4
    MOVLW b'11111011'
    TRIS PORTB          ; Setzt Pins des PortB(RB0..RB5) auf
    MOVLW b'11110110'   ; 1=Input(high-impedance), 0=Output
    TRIS PORTC          ; entsprechend PortC(RC0..RC5)
    CLRF PORTB
    CLRF PORTC

    ;zneu und zuend mit 200 initialisieren
    movlw d'200'
    movwf zneu
    movwf zuend

Nulldurchgang1    ; Zu Beginn auf den Spannungsnulldurchgang synchronisieren.
    btfsc _Unull
    goto Nulldurchgang1
Spannungssync1
    btfss _Unull
    goto Spannungssync1

;****** MAIN *********************************************************
START
    btfsc _Taster1    ; Testen ob Taster1 (dunkler) gedrückt wurde
    goto dunkler      ; Falls ja: "dunkler"-Routine starten
    
    movf zuend,0      ; zuend in akku kopieren (Z-Test) -> falls 0 wird
    btfsc STATUS,Z    ; Z-Flag gesetzt, dann SOFORT zünden
    goto Zuendtriac   ; dadurch minimale Verzögerung (maximale Helligkeit)
    
    btfss _Taster2    ; Testen ob Taster2 (heller) gedrückt wurde
    goto verzoeg      ; Falls nicht: Normale Verzögerungsroutine
    bsf _LED2         ; Falls doch: LED2 an
    decf zneu         ; und zneu um eins erniedrigen, normal weiter
    goto verzoeg      ; Anmerkung: Keine Routine nötig um zu erkennen, ob
                      ; zneu schon 0 ist, wird ja zu Beginn schon gemacht

dunkler
    bsf _LED1         ; LED1 leuchten lassen
    incf zneu         ; zneu incrementieren
    btfsc STATUS,Z    ; Falls Überlauf stattfand
    goto verzoeg      ; nicht weiter
    movlw h'FF'       ; sondern zneu
    movwf zneu        ; mit FFh beschreiben.

verzoeg    
    movf zneu,0       ; neue Phase in Akkumulator schreiben
    movwf zuend       ; und uebernehmen
verzoeg2              ; innere Verzoegerungsschleife
    movf zuend,0      ; Testen, ob schon gezündet werden muss.
    btfsc STATUS,Z    ; Wenn zuend nicht Null ist naechsten Befehl skippen 
    goto Zuendtriac   
    movlw d'6'        
    movwf wait        
    call warten    
    decf zuend        ; zuend decrementieren    
    goto verzoeg2     ; und verzoeg2 erneut aufrufen.
    
Zuendtriac
    btfsc _Inull      ; Sicherheit: Falls noch Strom fließt (_Inull high)
    goto Zuendtriac   ; KEINE Zündung, sonst auf Stromabriss warten. 2cyc 
                      ; Verlust werden in Kauf genommen.
    bsf _triac        ; Setze Zuendimpuls
    movlw d'255'    
    movwf wait        ; warten
    call warten
    bcf _triac        ; Zuendimpuls zuende

Nulldurchgang         ; Am Ende auf den Spannungsnulldurchgang synchronisieren.
    btfsc _Unull
    goto Nulldurchgang
    ; Hier sollte genug Zeit sein eventuell gesetzte LEDs zu löschen (2cyc)
    bcf _LED1
    bcf _LED2
Spannungssync
    btfss _Unull
    goto Spannungssync
    goto START    ; ...und Abarbeitung von oben wiederholen.

; Unterprogramm "warten" realisiert eine einfache Warteschleife
; Der Wert, von dem heruntergezählt werden soll ist in "wait" zu schreiben.
warten            
    decfsz wait,1
    goto warten
    retlw 0h
    END
;**********************************************************************
\end{verbatim}

\section{Zusatzaufgabe}

Als Zusatzaufgabe war ein Programm zu realisieren, welches die angeschlossene
Gl\"uhbirne im Sekundentakt blinken l\"asst. Dazu ließ sich ein Großteil des
Quelltextes der eigentlichen Aufgabe wiederverwenden, mit dem Unterschied daß
eine zusätzliche Variable \texttt{sec} eingef\"uhrt wurde, die von 100 bei
jedem Nulldurchgang herunterz\"ahlt. Falls die Laufvariable bei Null angekommen
ist, wird der Wert f\"ur $\alpha$ zwischen 0 und 255 hin- und hergeschaltet. 

\bigskip

\noindent Im Quelltext muss also bei der Initialisierung noch eingef\"ugt werden:


\bigskip

\hrule
\begin{verbatim}
sec     equ 0Bh     ; Register für 1 sec Blinken 

movlw d'100'        ; Halbwelle = 10ms, 100 * 10ms = 1s
movwf sec
\end{verbatim}
\hrule

\bigskip

Und der Anfang der Hauptschleife nach \texttt{START} wird alles bis
zur Verz\"ogerungsschleife durch folgenden Code ersetzt:

\bigskip

\hrule
\begin{verbatim}
    movf sec,0
    btfsc STATUS,Z  ; Testen, ob sec schon Null ist
    goto toggle     ; wenn ja, toggeln
    decf sec
    goto verzoeg

toggle
    movf zneu,0
    xorlw 0FFh      ; zneu zwischen 0 und 255 toggeln
    movwf zneu
    movlw d'100'    ; und sec neu beschreiben
    movwf sec
\end{verbatim} 
\hrule

\bigskip

Selbstverst\"andlich w\"are das Problem einfacher zu l\"osen, jedoch war das
Programm zum Phasenanschnitt schon vorhanden und somit war die Modifikation der
einfachste Weg.


\section{Probleme}

Das zu Hause vorbereitete Programm zeigte nicht auf Anhieb die gew\"unschte
Funktion. Es stellte sich heraus, daß dies darauf zur\"uckzuf\"uhren war, daß 
bei der \"Ubernahme des neue Z\"undwinkels das Mnemonic \texttt{movwf} falsch
geschrieben war (\texttt{movfw}).  Dies wurde jedoch ungl\"ucklicherweise beim Assemblieren
nicht bem\"angelt und blieb somit vorerst unbemerkt. Die folgende Fehlersuche
gestaltete sich etwas langwierig und es wurden etliche Ver\"anderungen am
Programm gemacht, die sich letztendlich als unn\"otig herausstellten.

Nachdem dieser Fehler jedoch behoben war, funktionierte der Wechselstromsteller
wie gefordert. Durch den w\"ahrend der Fehlersuche eingef\"ugten sehr langen
Z\"undimpuls konnten sogar entgegen den Erwartungen auch sehr kleine
Z\"undwinkel eingestellt werden. Bei einem kurzen Z\"undimpuls ist dies
problematisch, da der notwendige Haltestrom des Triacs eventuell nicht erreicht
wird.



\end{document}

