Forum: Mikrocontroller und Digitale Elektronik Warum läuft BCD Schalter Abfrage nicht ? (Atmega8)


von Robert A. (neostrider)


Lesenswert?

Hallo,

Ich hoffe ihr könnt mir helfen, ich brauche eine möglichkeit über einen 
BCD Schalter 10 verschiedene Programme anzusteuern, bisher hab ich es so 
wie im Anhang gelöst, jedoch funtioniert die lösung nur einmal, dann 
geht nix mehr hilfe !.


$regfile = "m8def.dat"                            'Atmega 8 definieren

$crystal = 8000000                               'Taktfrequenz

Config Pind.2 = Input                            'PIN C 0 EINGANG
Config Pind.3 = Input                             'PIN C 1 EINGANG
Config Pind.4 = Input                             'PIN C 2 EINGANG
Config Pind.5 = Input                               'PIN C 3 EINGANG
Config Pinb.0 = Output                             'PIN B 0 AUSGANG
Config Pinb.1 = Output                              'PIN B 1 AUSGANG
Config Pinb.2 = Output                              'PIN B 2 AUSGANG



Rot Alias Portb.0                                    'ROT PIN B 0 
zuweisen
Gruen Alias Portb.1                                   'GRUEN PIN B 1 
zuweisen
Blau Alias Portb.2                                     'BlAU PIN B 2 
zuweisen


'Config Timer0 = Timer , Prescale = 64
'On Ovf0                                   'Bei Überlauf(Ende) springe 
zu

Config Int0 = Rising                            'Interrupt 0 bei Wechsel
Enable Interrupts
Enable Int0                                           'Int 0 aktivieren
'Enable Timer0                                        'Interrupts 
aktivieren
On Int0 Bcd_auswahl:                'Bei Interrupt 0 springe zu bcd 
auswahl

Bit1 Alias Pind.2
Bit2 Alias Pind.3
Bit4 Alias Pind.4
Bit8 Alias Pind.5

Dim Stellung As Byte
Stellung = 0

Do
Anfang:

If Stellung = 0 Then
Do
Rot = 1                                              'Rote LED Ein
Gruen = 0                                             'Gruene LED Aus
Blau = 1                                              'Blaue LED Ein
Loop
End If                                            'Looping

If Stellung = 1 Then
Do
Rot = 1
Gruen = 0
Blau = 0
Loop
End If

If Stellung = 2 Then
Do
Rot = 0
Gruen = 1
Blau = 0
Loop
End If

If Stellung = 3 Then
Do
Rot = 0
Gruen = 0
Blau = 1
Loop
End If

If Stellung = 4 Then
Do
Rot = 1
Gruen = 1
Blau = 0
Loop
End If

If Stellung = 5 Then
Do
Rot = 0
Gruen = 1
Blau = 1
Loop
End If

If Stellung = 6 Then
Do
Rot = 1
Gruen = 0
Blau = 1
Loop
End If





Loop




Bcd_auswahl:

If Bit1 = 0 And Bit2 = 0 And Bit4 = 0 And Bit8 = 0 Then
   jmp anfang:
End If


If Bit1 = 1 And Bit2 = 0 And Bit4 = 0 And Bit8 = 0 Then
   Stellung = 1
   jmp anfang:
End If


If Bit1 = 0 And Bit2 = 1 And Bit4 = 0 And Bit8 = 0 Then
   Stellung = 2
   jmp anfang:
End If


If Bit1 = 1 And Bit2 = 1 And Bit4 = 0 And Bit8 = 0 Then
   Stellung = 3
   jmp anfang:
End If


If Bit1 = 0 And Bit2 = 0 And Bit4 = 1 And Bit8 = 0 Then
   Stellung = 4
   jmp anfang:
End If


If Bit1 = 1 And Bit2 = 0 And Bit4 = 1 And Bit8 = 0 Then
   Stellung = 5
   jmp anfang:
End If


If Bit1 = 0 And Bit2 = 1 And Bit4 = 1 And Bit8 = 0 Then
   Stellung = 6
   jmp anfang:
End If


If Bit1 = 1 And Bit2 = 1 And Bit4 = 1 And Bit8 = 0 Then
   Stellung = 7
   jmp anfang:
End If


If Bit1 = 0 And Bit2 = 0 And Bit4 = 0 And Bit8 = 1 Then
   Stellung = 8
   jmp anfang:
End If


If Bit1 = 1 And Bit2 = 0 And Bit4 = 0 And Bit8 = 1 Then
   Stellung = 9
   jmp anfang:
End If

Return

von Otto (Gast)


Lesenswert?

Hallo Robert,

die Auswahl im Interrupt auszuführen ist m.E.
vollkommen unnötig - lass es weg.

Lass das "do loop" innerhalb "if Stellung ="
weg und die Auswahl geht immer.

Gruss Otto

von Otto (Gast)


Lesenswert?

und ruf "BCD_Auswahl" immer nach dem 1. "do" auf

Otto

von Matthias (Gast)


Lesenswert?

Hilfe...
geht das auch in C ?

**duck und weg**

von Michael U. (Gast)


Lesenswert?

Hallo,

@Matthias: warum? Auch BasCom kann SELECT CASE...

Naja, Assembler wäre mir trotzdem lieber. ;-)

Gruß aus Berlin
Michael

von A.K. (Gast)


Lesenswert?

> Config Pind.2 = Input            'PIN C 0 EINGANG

Interessante Kombination aus Code und Kommentar.

von Robert A. (neostrider)


Lesenswert?

A.K. wrote:
>> Config Pind.2 = Input            'PIN C 0 EINGANG
>
> Interessante Kombination aus Code und Kommentar.

SORRY

von Robert A. (neostrider)


Lesenswert?

Unten stehend ist der aktuelle stand, hätte jedoch gerne eine andere 
lösung als alle 20 Durchläufe wieder komplett zu laufen.

Und wie bekomm ich das hin das der Taster nur "On demand" abgefragt 
wird, also am besten halt über einen interrupt und dann wieder an den 
Anfang des Hauptprogrammes springen.

Und als Sahnestück halt noch das Dimmen? Wie bekomm ich das lauffähig in 
ein Unterprogramm.

Wegen Select Case habe ich schon probiert, jedoch fehlt mir 
warscheinlich ein Parameter um alle 4 Bits gleichzeitig abzufragen.




$regfile = "m8def.dat"

$crystal = 8000000

Config Pind.2 = Input
Config Pind.3 = Input
Config Pind.4 = Input
Config Pind.5 = Input
Config Pinc.0 = Output
Config Pinc.1 = Output
Config Pinc.2 = Output
Config Pinc.3 = Output
Config Pinc.4 = Output
Config Pinc.5 = Output


Rr Alias Portc.2
Gr Alias Portc.0
Br Alias Portc.1
Rl Alias Portc.5
Gl Alias Portc.3
Bl Alias Portc.4



Bit1 Alias Pind.2
Bit2 Alias Pind.3
Bit4 Alias Pind.4
Bit8 Alias Pind.5



Declare Sub Bcd_auswahl
Dim Stellung As Byte
Dim Pwm As Byte
Dim Warte As Byte
Warte = 1

Stellung = 0

Do
Anfang:

   Call Bcd_auswahl



   If Stellung = 0 Then

      Rl = 0
      Rr = 0
      Gl = 0
      Gr = 0
      Bl = 0
      Br = 0

   End If



   If Stellung = 1 Then

      Rr = 1
      Rl = 1
      Gr = 0
      Gl = 0
      Br = 0
      Bl = 0

   End If



   If Stellung = 2 Then

      Rr = 0
      Rl = 0
      Gl = 1
      Gr = 1
      Bl = 0
      Br= 0

   End If



   If Stellung = 3 Then

      Rr = 0
      Rl = 0
      Gl = 0
      Gr = 0
      Bl = 1
      Br = 1

   End If



   If Stellung = 4 Then

      Rl = 1
      Rr = 1
      Waitms 4
      Gl = 1
      Gr = 1
      Waitms 2
      Gl = 0
      Gr = 0
      Bl = 0
      Br= 0

   End If



   If Stellung = 5 Then

     Rl = 0
     Rr = 0
     Gl = 1
     Gr = 1
     Bl = 1
     Br = 1

   End If



   If Stellung = 6 Then

      Rr = 1
      Rl = 1
      Gr = 0
      Gl = 0
      Br= 1
      Bl = 1

   End If



If Stellung = 7 Then
Pwm = 0
Do
      Gr = 0
      Gl = 0
      Br = 1
      Bl = 1


      Rr = 1
      Rl = 1
      Waitms Pwm

     Rr = 0
     Rl = 0
      Waitms 10

      Pwm = Pwm + 1



Loop Until Pwm = 20
End If




Sub Bcd_auswahl



   If Bit1 = 0 And Bit2 = 0 And Bit4 = 0 And Bit8 = 0 Then  'BCD 
Schalter auf 0

      Stellung = 0

   End If



   If Bit1 = 1 And Bit2 = 0 And Bit4 = 0 And Bit8 = 0 Then  'BCD 
Schalter auf 1

      Stellung = 1

   End If



   If Bit1 = 0 And Bit2 = 1 And Bit4 = 0 And Bit8 = 0 Then  'BCD 
Schalter auf 2

      Stellung = 2

   End If



   If Bit1 = 1 And Bit2 = 1 And Bit4 = 0 And Bit8 = 0 Then  'BCD 
Schalter auf 3

      Stellung = 3

   End If



   If Bit1 = 0 And Bit2 = 0 And Bit4 = 1 And Bit8 = 0 Then  'BCD 
Schalter auf 4

      Stellung = 4

   End If



   If Bit1 = 1 And Bit2 = 0 And Bit4 = 1 And Bit8 = 0 Then  'BCD 
Schalter auf 5

      Stellung = 5

   End If



   If Bit1 = 0 And Bit2 = 1 And Bit4 = 1 And Bit8 = 0 Then  'BCD 
Schalter auf 6

      Stellung = 6

   End If



   If Bit1 = 1 And Bit2 = 1 And Bit4 = 1 And Bit8 = 0 Then  'BCD 
Schalter auf 7

      Stellung = 7

   End If



   If Bit1 = 0 And Bit2 = 0 And Bit4 = 0 And Bit8 = 1 Then  'BCD 
Schalter auf 8

      Stellung = 8

   End If


   If Bit1 = 1 And Bit2 = 0 And Bit4 = 0 And Bit8 = 1 Then  'BCD 
Schalter auf 9

      Stellung = 9

   End If


End Sub



Loop


von Michael U. (Gast)


Lesenswert?

Hallo,

naja, man kann es natürlich chaotisch genug machen... ;)

Die 4 Bit eines BCD-Schalters stellen ja direkt die Werte 0000 - 1001 
dar, sonst wäre er ja keiner.
Man sollte die natürlich nicht erst auseinanderreißen, um sie dann 
mühsam wieder zusammenzubasteln.

Den Kram vom Port als komplettes Byte eingelesen, bei Deiner Beschaltung 
um 2 Bit nach rechts verschoben und die oberen 4 Bit ausmaskieren.
Schon steht in der Variablen die Nummer der Schalterstellung.

Benutze kein BasCom, in Assembler würde es so aussehen:

.def drehschalter = r16
in drehschalter,PIND    ; jetzt haben wir den ganzen Port
lsr drehschalter                    ; 2x rechts schieben, um von 
Bit5..Bit2 zu Bit3...Bit0 zu kommen
lsr drehschalter

andi drehschalter,0x0F  ; obere 4 Bit auf 0 setzen

nun steht in Drehschalter der Wert 0...9 für die Schalterstellung...

Gruß aus Berlin
Michael

von Robert A. (neostrider)


Lesenswert?

Ok vielen dank leider kann ich überhaupt kein Assembler !

Htte in Bascom ja auch schon den Gedanken den ganzen Schalter einzulesen 
als String.. doch wie man das umsetzt hab ich keine Ahnung.

von Michael U. (Gast)


Lesenswert?

Hallo,


ich habe mal spaßeshalber Deine eine Subroutine aufgeräumt.
Allerdings nur mal schnell aus der BasCom-Doku die Befehle rausgesucht, 
falls da was am Format nicht stimmt, muß Du selber schauen.
Ich benutze kein BasCom, will es auch nur zum Test für solche Sachen 
nicht unbedingt installieren.

Ist nur als Denkansatz gedacht...

Gruß aus Berlin
Michael

von Michael U. (Gast)


Lesenswert?

Hallo,

kommt davon, wenn man es so eilig hat... :-(

$regfile = "m8def.dat"

$crystal = 8000000

Config Pind.2 = Input
Config Pind.3 = Input
Config Pind.4 = Input
Config Pind.5 = Input
Config Pinc.0 = Output
Config Pinc.1 = Output
Config Pinc.2 = Output
Config Pinc.3 = Output
Config Pinc.4 = Output
Config Pinc.5 = Output


Rr Alias Portc.2
Gr Alias Portc.0
Br Alias Portc.1
Rl Alias Portc.5
Gl Alias Portc.3
Bl Alias Portc.4


Schalter Alias Pind


Declare Sub Bcd_auswahl
Dim Stellung As Byte
Dim Pwm As Byte
Dim Warte As Byte
Warte = 1

Stellung = 0

Do
Anfang:

   Call Bcd_auswahl

   If Stellung = 0 Then

      Rl = 0
      Rr = 0
      Gl = 0
      Gr = 0
      Bl = 0
      Br = 0

   End If

   If Stellung = 1 Then

      Rr = 1
      Rl = 1
      Gr = 0
      Gl = 0
      Br = 0
      Bl = 0

   End If

   If Stellung = 2 Then

      Rr = 0
      Rl = 0
      Gl = 1
      Gr = 1
      Bl = 0
      Br= 0

   End If

   If Stellung = 3 Then

      Rr = 0
      Rl = 0
      Gl = 0
      Gr = 0
      Bl = 1
      Br = 1

   End If

   If Stellung = 4 Then

      Rl = 1
      Rr = 1
      Waitms 4
      Gl = 1
      Gr = 1
      Waitms 2
      Gl = 0
      Gr = 0
      Bl = 0
      Br= 0

   End If

   If Stellung = 5 Then

     Rl = 0
     Rr = 0
     Gl = 1
     Gr = 1
     Bl = 1
     Br = 1

   End If

   If Stellung = 6 Then

      Rr = 1
      Rl = 1
      Gr = 0
      Gl = 0
      Br= 1
      Bl = 1

   End If

If Stellung = 7 Then
Pwm = 0
Do
      Gr = 0
      Gl = 0
      Br = 1
      Bl = 1

      Rr = 1
      Rl = 1
      Waitms Pwm

     Rr = 0
     Rl = 0
      Waitms 10

      Pwm = Pwm + 1

Loop Until Pwm = 20
End If

Sub Bcd_auswahl
  Stellung = Schalter
  SHIFT Stellung,RIGHT,2
  Stellung = Stellung AND &H0F
End Sub

Loop

Gruß aus Berlin
Michael

von Karl H. (kbuchegg)


Lesenswert?

Zur Not kann man das ja immer noch so machen

  Stellung = 8 * Bit3 + 4 * Bit2 + 2 * Bit1 + Bit0

Da aber BASCOM derart komplexe Berechnungen nicht erlaubt,
musst du halt die ganzen Berechnungen einzeln aufdröseln.

Aber das einfachste ist es sicherlich, wie Michael schon
sagte: Vergiss das ganze Einzelbitabfragen. Braucht kein
Mensch. Lies den Port als ganzes ein und danach setzt du
gezielt alle Bits die du nicht brauchst mit einem AND
auf 0. Danach noch um 2 Bits nach rechts schieben (das
ist eine Division durch 4) und fertig.

von Robert A. (neostrider)


Lesenswert?

Danke für die Antworten.

Wo steht jetzt in dem neuen Sub mein Portname ?

Wie bekomme ich jetzt noch zeitkritische Abläufe hin (PWM) also in den 
Unterprogrammen

MfG,

Neostrider

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.