Previous Page Table Of Contents Next Page


Bitte beachte die Copyrighthinweise.

La18-ww1

Menüsteuerung mit Microcontroller

1 Aufgabenstellung

· Programmierung einer Menüsteuerung. Über wenige Tasten sollen die Zustände vieler Portleitungen geändert werden können.

2 Prinzip

Es wurde folgendes Menü realisiert:

Nach dem Start befindet man sich im Normalbetrieb (NB).

Durch das Drücken von Enter kommt man in das Menü 1. Mit der Taste kann nun der Zustand der Portleitung geändert (getoggelt) werden.

Durch nochmaliges Drücken von Enter kommt man in das nächste Menü und kann mit der Taste nun den Zustand der nächsten Portleitung ändern.

Hier wurden zwei Menüpunkte realisiert, man könnte diese Struktur natürlich auf viele Menüs bzw. z.B. mit einer dritten Taste auf Untermenüs erweitern. Theoretisch würde über eine Zeitsteuerung auch eine einzelne Taste reichen.

Durch abermaliges Drücken von Enter kommt man wieder in den Normalbetrieb.

3 Schaltung

Es wurde folgende Schaltung aufgebaut (die Werte der Widerstände wurden nicht notiert):

4 Programmierung in Assembler

4.1 Struktogramm

Die ständigen Warteschleifen (DJNZ) dienen der Entprellung der Tasten.

Menu2b.asm

;*********************************************************************

; Editor: Rosenauer Florian @ HTBLA Karlstein, Austria - Waidhofen/Th.

; Datum: 13/Mar/1998 Klasse/Gruppe/Kat.Nr : V-EA/-/--

;*********************************************************************

; Sprache : ASM fuer 80C537

; Programm Nr. : VEA Labor SteG

; Version : 0.11

; Kurzbeschreibung : Menuesteuerung mit MC

;

;

;*********************************************************************

#include 537.inc

Enter .equ P5.0

Taste .equ P5.1

Nb .equ P4.0

Aus1 .equ P4.2

Aus2 .equ P4.3

.org $0000

ljmp Start

Start .org $0100

mov R1,#$FF

clr Nb

jb Enter,Start

setb Nb

Loop djnz R1,Loop

mov R1,#$FF

Loop1 jnb Enter,Loop1

L3 djnz R1,L3

mov R1,#$FF

Weiter jnb Enter,Loop2

jb Taste,Weiter

L djnz R1,L

mov R1,#$FF

L6 jnb Taste,L6

cpl Aus1

ljmp Weiter

Loop2 djnz R1,Loop2

mov R1,#$FF

Loop3 jnb Enter,Loop3

L4 djnz R1,L4

mov R1,#$FF

Weiter1 jnb Enter,Loop4

jb Taste,Weiter1

L1 djnz R1,L1

mov R1,#$FF

L5 jnb Taste,L5

cpl Aus2

ljmp Weiter1

Loop4 djnz R1,Loop4

mov R1,#$FF

Loop5 jnb Enter,Loop5

ljmp Start

.end

Das Programm funktionierte einwandfrei lt. dem unter Punkt 2 erwähnten Prinzip.

5 Programmierung in C

Als nächstes wurde das gleiche Menüprinzip in C realisiert.

Menu2.c

/*************************************************************************

/* Editor: Florian Rosenauer @ HTBLA Karlstein, Austria-3830 Waidhofen

/* Datum: 13/Mar/1998 Klasse/Gruppe/Kat.Nr : V-EA/-/--

/*************************************************************************

/* Sprache : C51 fuer MC 80C537

/* Programm Nr. : Labor SteG

/* Kurzbeschreibung : Menu2b.asm in C

/*************************************************************************

*/

// const float VERSION = 1.01;

/************************************************************************/

#include <stdio.h>

#include <reg517.h>

/* BEGINN --- putchar von Sampl517 --- */

sbit enter = P5^0;

sbit taste = P5^1;

sbit nb = P4^0;

sbit aus1 = P4^1;

sbit aus2 = P4^2;

#define XON 0x11

#define XOFF 0x13

char putchar (char c) {

if (c == '\n') {

if (S1CON & 0x01) { /* RI*/

if (S1BUF == XOFF) {

do {

S1CON &= 0xFE; /* RI = 0 */

while (!(S1CON & 0x01)); /* RI */

}

while (S1BUF != XON);

S1CON &= 0xFE; /* RI = 0 */

}

}

while (!(S1CON & 0x02)); /* while (!TI); */

S1CON &= 0xFD; /* TI = 0 */

S1BUF = 0x0d; /* output CR */

}

if (S1CON & 0x01) {

if (S1BUF == XOFF) {

do {

S1CON &= 0xFE; /* RI = 0 */

while (!(S1CON & 0x01)); /* while (!RI) */

}

while (S1BUF != XON);

S1CON &= 0xFE; /* RI = 0 */

}

}

while (!(S1CON & 0x02)); /* while (!TI); */

S1CON &= 0xFD; /* TI = 0 */

return (S1BUF = c);

}

/* ENDE --- putchar von Sampl517 --- */

void main (void) {

//bit exit;

unsigned char delay;

/* BEGINN --- Serial 1 Init von Sampl517 --- */

/* initialize serial interface */

//#if 0

S0CON = 0x5A; /* S0CON */

BD = 1; /* internal Baudrate Generator */

PCON |= 0x80; /* 9600 Baud @ 12 MHz */

//#endif

S1REL = 0xD9; /* Reload Value */

S1CON = 0xB2; /* Init Serial Interface */

/* ENDE --- Serial 1 Init von Sampl517 --- */

// '#endif' wofuer ???

putchar('!');

while (1)

{

while (enter == 1)

nb = 0;

nb = 1;

for (delay=0;delay<=250;delay++); // Prellen abwarten

while (enter == 0);

for (delay=0;delay<=250;delay++); // Prellen abwarten

while (enter == 1)

{ if (taste != 1)

{ for (delay=0;delay<=250;delay++); // Prellen abwarten

while (taste == 0);

aus1 = !aus1;

}

}

for (delay=0;delay<=250;delay++); // Prellen abwarten

while (enter == 1)

{ if (taste != 1)

{ for (delay=0;delay<=250;delay++); // Prellen abwarten

while (taste == 0);

aus2 = !aus2;

}

}

for (delay=0;delay<=250;delay++); // Prellen abwarten

} //while (1)

} //main

Das Programm funktionierte jedoch nicht wie erwartet. Ein Wechsel vom Menü 1 mittels Enter in das Menü 2 war nicht möglich, das Toggeln von Zustand 1 jedoch funktionierte.

Vergleicht man das Flussdiagramm mit dem Struktogramm, so kann man erkennen, dass im C-Programm jeweils die Warteschleifen Loop3 und Loop4 vergessen wurden. Drückt man Enter, läuft das Programm zwar zu Menüpunkt 2, geht danach aber sofort zum Normalbetrieb und abermals in den Menüpunkt 1. Somit war ein Wechsel nicht möglich.

Erzeugter Assemblercode aus Menu2.lst

Der eigentlich Teil des Menüs ist fettgedruckt, der Rest ist nur die Initialisierung der Seriellen 1 für printf.

; FUNCTION main (BEGIN)

;---- Variable 'delay' assigned to Register 'R6' ----

; SOURCE LINE # 62

; SOURCE LINE # 69

0000 75985A MOV S0CON,#05AH

; SOURCE LINE # 70

0003 D2DF SETB BD

; SOURCE LINE # 71

0005 438780 ORL PCON,#080H

; SOURCE LINE # 73

0008 759DD9 MOV S1REL,#0D9H

; SOURCE LINE # 74

000B 759BB2 MOV S1CON,#0B2H

; SOURCE LINE # 78

000E 7F21 MOV R7,#021H

0010 120000 R LCALL _putchar

; SOURCE LINE # 80

; SOURCE LINE # 81

0013 ?C0023:

; SOURCE LINE # 82

0013 30F804 JNB enter,?C0024

; SOURCE LINE # 83

0016 C2E8 CLR nb

0018 80F9 SJMP ?C0023

001A ?C0024:

; SOURCE LINE # 84

001A D2E8 SETB nb

; SOURCE LINE # 85

001C E4 CLR A

001D FE MOV R6,A

001E ?C0025:

001E 0E INC R6

001F EE MOV A,R6

0020 D3 SETB C

0021 94FA SUBB A,#0FAH

0023 40F9 JC ?C0025

0025 ?C0028:

; SOURCE LINE # 87

0025 30F8FD JNB enter,?C0028

0028 ?C0029:

; SOURCE LINE # 88

0028 E4 CLR A

0029 FE MOV R6,A

002A ?C0030:

002A 0E INC R6

002B EE MOV A,R6

002C D3 SETB C

002D 94FA SUBB A,#0FAH

002F 40F9 JC ?C0030

0031 ?C0033:

; SOURCE LINE # 90

0031 30F813 JNB enter,?C0034

; SOURCE LINE # 91

0034 20F9FA JB taste,?C0033

; SOURCE LINE # 92

0037 E4 CLR A

0038 FE MOV R6,A

0039 ?C0036:

0039 0E INC R6

003A EE MOV A,R6

003B D3 SETB C

003C 94FA SUBB A,#0FAH

003E 40F9 JC ?C0036

0040 ?C0039:

; SOURCE LINE # 93

0040 30F9FD JNB taste,?C0039

0043 ?C0040:

; SOURCE LINE # 94

0043 B2E9 CPL aus1

; SOURCE LINE # 95

; SOURCE LINE # 96

0045 80EA SJMP ?C0033

0047 ?C0034:

; SOURCE LINE # 98

0047 E4 CLR A

0048 FE MOV R6,A

0049 ?C0041:

0049 0E INC R6

004A EE MOV A,R6

004B D3 SETB C

004C 94FA SUBB A,#0FAH

004E 40F9 JC ?C0041

0050 ?C0044:

; SOURCE LINE # 100

0050 30F813 JNB enter,?C0045

; SOURCE LINE # 101

0053 20F9FA JB taste,?C0044

; SOURCE LINE # 102

0056 E4 CLR A

0057 FE MOV R6,A

0058 ?C0047:

0058 0E INC R6

0059 EE MOV A,R6

005A D3 SETB C

005B 94FA SUBB A,#0FAH

005D 40F9 JC ?C0047

005F ?C0050:

; SOURCE LINE # 103

005F 30F9FD JNB taste,?C0050

0062 ?C0051:

; SOURCE LINE # 104

0062 B2EA CPL aus2

; SOURCE LINE # 105

; SOURCE LINE # 106

0064 80EA SJMP ?C0044

0066 ?C0045:

; SOURCE LINE # 108

0066 E4 CLR A

0067 FE MOV R6,A

0068 ?C0052:

0068 EE MOV A,R6

0069 D3 SETB C

006A 94FA SUBB A,#0FAH

006C 50A5 JNC ?C0023

006E 0E INC R6

006F 80F7 SJMP ?C0052

; SOURCE LINE # 110

; SOURCE LINE # 111

0071 22 RET

; FUNCTION main (END)

C51 COMPILER V5.02, MENU2 15/05/98 00:15:56 PAGE 6

Vergleicht man den nativen Assemblercode mit dem C51-Assemblercode so kann man feststellen, dass der Code an den meisten Stellen relativ ähnlich ist. Dies ist vermutlich darauf zurückzuführen, dass das C-Programm aufgrund des Assemblercodes programmiert wurde.

Der einzige größere Unterschied liegt in der Realisierung der Warteschleifen: Hier hat der Compiler mit INC-, SUBB- und JNC-Befehlen wesentlich komplizierteren Code generiert. Möglicherweise liegt dies daran, dass for-Schleifen verwendet wurden. Wahrscheinlich hätte der Compiler while-Schleifen besser übersetzt!

6 Interpretation der Messergebnisse

Microcontroller stellen eine einfache Möglichkeit dar, mit geringem Hardwareaufwand (Taster etc.) komplexe Funktionen zu realisieren.

Das Programm hätte eventuell noch durch eine Anzeige des aktuellen Menüpunkts verbessert werden können.


Creative Commons Lizenzvertrag
Dieses Werk ist lizenziert unter einer Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen 3.0 Österreich Lizenz.
[http://www.FLR.at/]
Letztes Update vom 25. Jul. 1999 von Florian Rosenauer

Previous PageTop Of Page Next Page

Powered by Transit