Seite 1 von 1

TM1638-LED&KEY-Modul

Verfasst: Mo 9. Mär 2020, 12:47
von Heinrichs
Für dem Attiny2313 habe ich die Funktionsweise dieses Moduls schon ausführlich an dieser Stelle vorgestellt. Nun habe ich das dort angegebene Programm für das Nano-Board angepasst. Wurde bei dem Attiny2313 (mangels eigener SPI-Komponente) noch die USI-Komponente benutzt, so konnte beim Atmega328 jetzt die SPI-Komponente eingesetzt werden.

Da der Atmega32 dieselbe SPI-Komponente wie der Atmega328 besitzt, sollte das folgende Programm auch für den Atmega32 funktionieren; allerdings müssen hier andere Anschlüssen benutzt werden. Beachten Sie dazu die Erläuterungen im Vorspann des Programms.

Code: Alles auswählen

' TM1638 an Nano-Board

' SPI-Funktion für Atmega328 (getestet) und Atmega32
' Der SPI-Takt ist 1/16 der Taktfrequenz des Mikrocontrollers;
' sie darf beim TM1638 laut Datenblatt nicht größer als 1 MHz sein.

' Anschlüsse für Atmega328:
' MOSI an B.3 -> (über 1K-Widerstand) -> DIO  (Data-In-Out)
' MISO an B.4 -> DIO
' SCK an B.5  -> CLK (Clock)
' SS an B.2   -> STB (Chip Select)

' >>>>>>>>>>>>>>> Wichtig für Atmega32 <<<<<<<<<<<<<<<<<<<<<<<<<<<<
' Für das Atmega32-Board muss man die Anschüsse abändern, vgl. Manual Atmega32
' MOSI an B.5 -> (über 1K-Widerstand) -> DIO  (Data-In-Out)
' MISO an B.6 -> DIO
' SCK an B.7  -> CLK (Clock)
' SS an B.4   -> STB (Chip Select)
' Im Programm-Quelltext muss man
' 1. bei der Initialisierung en ddrb-Eintrag anpassen
' 2. im restlichen Quelltext überall portb.2 durch portb.4 ersetzen
' 3. im restlichen Quelltext überall ddrb.3 durch ddrb.5 ersetzen

' Programm zeigt auf der rechten Sieben-Segment-Anzeige die Nummer des zuletzt gedrückten Tasters an.


'----------------------------------------------------------------------------

$regfile = "m328pdef.dat"                                   'Dadurch wird auch das Pin Layout bestimmt, ggf. für Atmega32 abändern
$crystal = 16000000
$framesize = 32
$swstack = 32
$hwstack = 64
$baud = 9600

'**********************************************************
'******************* Deklarationen ************************

Declare Function Spi(s As Byte) As Byte
Declare Sub Loeschen
Declare Sub Display_einschalten
Declare Sub Ziffer_zeigen
Declare Sub Init_muster
Declare Sub Keyscan
Dim Bef1 As Byte
Dim Bef2 As Byte
Dim Bef3 As Byte
Dim Dummy As Byte
Dim Pause As Byte
Dim Wert As Byte
Dim I As Byte
Dim K As Byte
Dim K1 As Byte
Dim S As Byte
Dim Pos As Byte
Dim Scan(4) As Byte
Dim Muster(10) As Byte


'****************** Initialisierung ***********************

' Konfiguration der SPI-Komponente
Spcr = &B01110001                                           'SPI-Takt = Fosc/16 = 1 MHz, SPI enabled, SPI Master, LSB zuerst

' Für Atmega328
Ddrb = &B11101111                                           'Port B als Ausgangsport; B.4 als Input

' Für Atmega32
' Ddrb = &B10111111                                           'Port B als Ausgangsport; B.6 als Input

Portb.2 = 1                                                 'STB auf 1

Waitms 10

'**********************************************************
'******************** Hauptprogramm ***********************

Pause = 2

Call Init_muster
Call Loeschen
Call Display_einschalten
Wert = Muster(1)                                            'Anzeige "0"
Pos = 14
Call Ziffer_zeigen

Do
  Waitms 10
  Call Keyscan
  For I = 1 To 4
    S = Scan(i)
    If S.0 = 1 Then
      K = I + 1
      Wert = Muster(k)
    End If
    If S.4 = 1 Then
      K = I + 5
      Wert = Muster(k)
    End If
    Call Ziffer_zeigen
  Next I
Loop


End

'**********************************************************
'******************* Unterprogramme ***********************

Function Spi(s As Byte) As Byte
  Spdr = S
  Do : Loop Until Spsr.spif = 1
  Spi = Spdr
End Function

Sub Loeschen
  Portb.2 = 0
  Waitus Pause
  Bef1 = $40
  Dummy = Spi(bef1)                                         'Displayreg, Autoinkr.
  Portb.2 = 1
  Waitus Pause
  Portb.2 = 0
  Waitus Pause
  Bef2 = $c0
  Dummy = Spi(bef2)                                         'Startadresse
  Waitus Pause
  Wert = 0
  For I = 0 To 15
    Dummy = Spi(wert)
    Waitus Pause
  Next I
  Portb.2 = 1
  Waitus Pause
End Sub

Sub Display_einschalten
  Portb.2 = 0
  Waitus Pause
  Bef3 = $8f                                                '$8F = 16/16 an; &B10001011 = 10/16 an (PWM)
  Dummy = Spi(bef3)                                         'Display
  Portb.2 = 1
End Sub

Sub Init_muster
  Muster(1) = &B00111111                                    '0
  Muster(2) = &B00000110                                    '1
  Muster(3) = &B01011011                                    '2
  Muster(4) = &B01001111                                    '3
  Muster(5) = &B01100110                                    '4
  Muster(6) = &B01101101                                    '5
  Muster(7) = &B01111101                                    '6
  Muster(8) = &B00000111                                    '7
  Muster(9) = &B01111111                                    '8
  Muster(10) = &B01101111                                   '9
  ' ggf. weiter Muster...
End Sub

Sub Ziffer_zeigen
  Portb.2 = 0
  Waitus Pause
  Bef1 = $44
  Dummy = Spi(bef1)                                         'Displayreg, Autoinkr.
  Portb.2 = 1
  Waitus Pause
  Portb.2 = 0
  Waitus Pause
  Bef2 = $c0 + Pos
  Dummy = Spi(bef2)
  Waitus Pause
  Dummy = Spi(wert)
  Portb.2 = 1
  Waitus Pause
End Sub

Sub Keyscan
  Portb.2 = 0
  Waitus Pause
  Bef1 = $42                                                'read command
  Dummy = Spi(bef1)
  Waitus Pause
  Ddrb.3 = 0                                                'wichtig, weil sonst DI beim Lesen durch DO beeinflusst wird
  Waitus Pause
  For I = 1 To 4
    Scan(i) = Spi(dummy)
    Waitus Pause
  Next I
  Ddrb.3 = 1
  Portb.2 = 1
  Waitus Pause
End Sub