BASCOM-Spielereien für Anfänger

dino03

Aktives Mitglied
27. Okt. 2008
6.760
20
38
Sprachen
  1. BascomAVR
  2. Assembler
Hallo,

ich pack mal etwas kommentierten Quelltext hier rein. Etwas Erklärung ist
auch dabei. Es werden einige Grundprinzipien im Quellcode behandelt ...
Multiplexing, Software-PWM, Ports, Variablen, ...

Die Programme sind für einen ATmega8 mit internem 8MHz-Takt geschrieben.

Es werden weder Interrupts noch irgendwelche anderen Hardwareteile
(Timer, ADC, ...) beim Atmel verwendet. Also pure Software.

Die Überlegung, hier ein paar kleine Hilfen für blutige Anfänger reinzupacken
sind schon etwas älter. Jetzt hab ich einfach mal Quick-n-Dirty ein wenig
getippt. Ich glaube, die Richtung wo es hingehen soll läßt sich erkennen :D

Also spielt mal ein wenig mit den Quelltexten rum und lernt dabei wie die
Sachen funktionieren. Es ist nicht kompliziert. Die Quelltexte bauen aufeinander
auf. Die Variablennamen erklären die Funktion der Variable und es sollten auch
genug Bemerkungen im Quelltext sein.

Also viel Spaß damit ...

Gruß
Dino
 
Basis-Gerippe für Programme

Als erstes einmal ein Basisgerüst von unbedingt notwendigen Teilen eines
Programms.



CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr000 Basis
'
' Basisgeruest fuer ein BASCOM-Programm


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################


' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End

Und hier das ganze als Download (einfacher als Copy-n-Paste) ...
Anhang anzeigen Mega8-HowTo_Nr000_Basis.bas

Die Schaltung habe ich auf einem Steckbrett aufgebaut ...
P1050154.JPG

Für die ISP-Schnittstelle und die Spannungsversorgung hab ich mir schnell
mal nen kleinen Adapter gestrickt (der auf dem Board). Der andere Adapter
ist schon etwas älter und kann 6pin auf 10pin ISP umsetzen und über die
ISP-Leitung eine Schaltung mit Spannung versorgen. Der 10polige Anschluß
auf dem Board wird also im Moment nur für die Spannungsversorgung
benutzt und am 6poligen hängt ein AVRISPmk2 mit USB am PC.
P1050158.JPG

und hier noch der Schaltplan ...
BASCOM-HowTo_Nr001.png
Da im Moment noch der interne 8MHz-Oszillator verwendet wird benötigt man
den Quarz und die beiden 22pF-Keramikkondensatoren noch nicht.
 
Initialisierung der Ports

Jetzt kommt zu dem Basisgerüst die Initialisierung der Port hinzu. Damit der
Atmel weiß was Eingang und was Ausgang ist ...



CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr001 Init
'
' Initialisierung der Hardware und erweitertes Basisgeruest


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- ---- ---- ---- => 00111111 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0000
Portc = &B0011_1111
'
'
'
' PD0 ---->-- LED0 3mm gelb
' PD1 ---->-- LED1 3mm gelb
' PD2 ---->-- LED2 3mm gelb
' PD3 ---->-- LED3 3mm gelb
' PD4 ---->-- LED4 3mm gelb
' PD5 ---->-- LED5 3mm gelb
' PD6 ---->-- LED6 3mm gelb
' PD7 ---->-- LED7 3mm gelb
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' LED7 LED6 LED5 LED4 LED3 LED2 LED1 LED0 => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'






' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do



Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End

und auch wieder als Download ...
Anhang anzeigen Mega8-HowTo_Nr001_Init.bas
jetzt kann es losgehen ;)
 
PortD blinken lassen

Jetzt kommt das erste Lebenszeichen. Wir lassen den gesamten Port blinken.
200ms alles an und 200ms alles aus.


CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr002 Portblink
'
' Alle Bits auf PortD blinken lassen


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- ---- ---- ---- => 00111111 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0000
Portc = &B0011_1111
'
'
'
' PD0 ---->-- LED0 3mm gelb
' PD1 ---->-- LED1 3mm gelb
' PD2 ---->-- LED2 3mm gelb
' PD3 ---->-- LED3 3mm gelb
' PD4 ---->-- LED4 3mm gelb
' PD5 ---->-- LED5 3mm gelb
' PD6 ---->-- LED6 3mm gelb
' PD7 ---->-- LED7 3mm gelb
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' LED7 LED6 LED5 LED4 LED3 LED2 LED1 LED0 => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'






' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Waitms 200 ' 200ms warten

Portd = &B1111_1111 ' Alle Bits am Port auf 1 setzen


Waitms 200 ' 200ms warten

Portd = &B0000_0000 ' Alle Bits am Port auf 0 setzen


Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End

Anhang anzeigen Mega8-HowTo_Nr002_Portblink.bas
 
Port-Blinker mit einer Byte-Variable

Der selbe "Blinker" wie vorher nur das hier eine Variable in die Ausgabe zum
Port zwischengesschaltet ist.


CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr003 Byte-Variable
'
' Portr-Blink-Routine ueber eine Byte-Variable


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- ---- ---- ---- => 00111111 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0000
Portc = &B0011_1111
'
'
'
' PD0 ---->-- LED0 3mm gelb
' PD1 ---->-- LED1 3mm gelb
' PD2 ---->-- LED2 3mm gelb
' PD3 ---->-- LED3 3mm gelb
' PD4 ---->-- LED4 3mm gelb
' PD5 ---->-- LED5 3mm gelb
' PD6 ---->-- LED6 3mm gelb
' PD7 ---->-- LED7 3mm gelb
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' LED7 LED6 LED5 LED4 LED3 LED2 LED1 LED0 => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'

' ###############################################
' ##### Variablendeklaration ####################
' ###############################################

' Variable A als Byte anlegen
Dim A As Byte
' und initialisieren (Anfangswert setzen)
A = 0


' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Waitms 200 ' 200ms warten

A = 255
Portd = A ' Alle Bits am Port auf 1 setzen


Waitms 200 ' 200ms warten

A = 0
Portd = A ' Alle Bits am Port auf 0 setzen


Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End


Anhang anzeigen Mega8-HowTo_Nr003_Byte-Variable.bas
 
Zählermit Byte-Variable und Ausgabe auf PortD

Die Variable wird jetzt bei jedem Schleifendurchlauf hochgezählt und auf
den LEDs ausgegeben. Man sieht jetzt also die einzelnen Bits der Variable A.


CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr004 Byte-Zaehler
'
' Eine Byte-Variable (8Bit) hochzaehlen lassen und auf LEDs ausgeben


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- ---- ---- ---- => 00111111 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0000
Portc = &B0011_1111
'
'
'
' PD0 ---->-- LED0 3mm gelb
' PD1 ---->-- LED1 3mm gelb
' PD2 ---->-- LED2 3mm gelb
' PD3 ---->-- LED3 3mm gelb
' PD4 ---->-- LED4 3mm gelb
' PD5 ---->-- LED5 3mm gelb
' PD6 ---->-- LED6 3mm gelb
' PD7 ---->-- LED7 3mm gelb
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' LED7 LED6 LED5 LED4 LED3 LED2 LED1 LED0 => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'

' ###############################################
' ##### Variablendeklaration ####################
' ###############################################

' Variable A als Byte anlegen
Dim A As Byte
' und initialisieren (Anfangswert setzen)
A = 1


' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Waitms 200 ' 50ms warten

Portd = A ' Variable auf PortD ausgeben

A = A + 1 ' Variable A um 1 hochzaehlen


Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End


Anhang anzeigen Mega8-HowTo_Nr004_Byte-Zaehler.bas
 
Bit-Rotation durch eine Byte-Variable

Hier wird eine leuchtende LED weitergeschoben (Lauflicht). Da die LEDs gegen
Vcc geschaltet sind muß der Pin auf GND liegen damit die LED leuchtet. Dafür
wird die Variable mit 254 als Startwert gesetzt. 254 dezimal ist 11111110
binär. Also ist Bit 0 der Variable auf 0 und damit der Pin PortD.0 auf GND. Die
erste LED leuchtet. Dieses Muster wird jetzt durch die 8Bit der Variable
geschoben. Was links (bei Bit7) herausfällt kommt bei einer Rotation rechts
(bei Bit0) wieder herein. Die leuchtende LED wandert also immer von rechts
nach links durch die LED-Reihe.


CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr005 Byte-Rotate
'
' Ein Bitmuster in enier Byte-Variable rotieren lassen und anzeigen


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- ---- ---- ---- => 00111111 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0000
Portc = &B0011_1111
'
'
'
' PD0 ---->-- LED0 3mm gelb
' PD1 ---->-- LED1 3mm gelb
' PD2 ---->-- LED2 3mm gelb
' PD3 ---->-- LED3 3mm gelb
' PD4 ---->-- LED4 3mm gelb
' PD5 ---->-- LED5 3mm gelb
' PD6 ---->-- LED6 3mm gelb
' PD7 ---->-- LED7 3mm gelb
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' LED7 LED6 LED5 LED4 LED3 LED2 LED1 LED0 => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'

' ###############################################
' ##### Variablendeklaration ####################
' ###############################################

' Variable A als Byte anlegen
Dim A As Byte
' und initialisieren (Anfangswert setzen)
A = 254


' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Waitms 100 ' 100ms warten

Portd = A ' Variable auf PortD ausgeben

Rotate A , Left , 1 ' Variableninhalt um ein Bit nach links verschieben
' Bit 7 6 5 4 3 2 1 0 =<= um ein Bit nach links schieben
' 1 1 1 1 1 1 1 0 vorher
' 1 1 1 1 1 1 0 1 nachher

' 7 <- 6 <- 5 <- 4 <- 3 <- 2 <- 1 <- 0 Rotation der Bits durch die Positionen im Byte
' | |
' ----->--------->-------->------->-
'


Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End


Anhang anzeigen Mega8-HowTo_Nr005_Byte-Rotate.bas
 
Ansteuerung einer 7Segment-Anzeige mit gemeinsamer Anode

Jetzt wurden die LEDs durch eine 7Segment-Anzeige ersetzt. Die Beschaltung
ist im Quelltext angegeben. Alle 500ms ändert sich das Muster. Die Anzeige
ist wie die LEDs gegen Vcc (gemeinsame Anode). Die Muster sind so gesetzt
das die Ziffern 0 bis 9 nacheinander angezeigt werden.


CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr006 7Segm-Start
'
' Erste Anfaenge mit einer 7Segment-Anzeige


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- ---- ---- ---- => 00111111 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0000
Portc = &B0011_1111
'
'
'
' PD0 ---->-- Segm a a 7Segment-Display gemeinsame Anode
' PD1 ---->-- Segm b ----
' PD2 ---->-- Segm c f| |b
' PD3 ---->-- Segm d | g |
' PD4 ---->-- Segm e ----
' PD5 ---->-- Segm f e| |c
' PD6 ---->-- Segm g | d | dp
' PD7 ---->-- Segm dp ---- O
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' dp SEGg SEGf SEGe SEGd SEGc SEGb SEGa => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'

' ###############################################
' ##### Variablendeklaration ####################
' ###############################################

' Variable A als Byte anlegen
Dim A As Byte
' und initialisieren (Anfangswert setzen)
A = 254


' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Waitms 500 ' 100ms warten
A = &B1100_0000 ' 0 => Segmente abcdef
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B1111_1001 ' 1 => Segmente bc
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B1010_0100 ' 2 => Segmente abdeg
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B1011_0000 ' 3 => Segmente abcdg
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B1001_1001 ' 4 => Segmente bcfg
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B1001_0010 ' 5 => Segmente acdfg
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B1000_0010 ' 6 => Segmente acdefg
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B1111_1000 ' 7 => Segmente abc
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B1000_0000 ' 8 => Segmente abcdefg
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B1001_0000 ' 9 => Segmente abcdfg
Portd = A ' Variable auf PortD ausgeben

Waitms 500 ' 100ms warten
A = &B0000_0000 ' Alle Segmente und Dezimalpunkt an
Portd = A ' Variable auf PortD ausgeben



Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End

wieder als Download ...
Anhang anzeigen Mega8-HowTo_Nr006_7Segm-Start.bas

und hier der Aufbau der Hardware.
P1050156.JPG
 
verbesserte Version mit Mustertabelle

Da man ja nicht jedes mal das Muster in den Fingern haben will habe ich
hier als Zwischenstück eine Tabelle eingefügt die über einen Indexwert
ein entsprechendes Muster der Ziffer ausgibt. Das wird dann an den Port
weitergereicht und leuchtet auf der Anzeige.

Tabellen fangen bei BASCOM leider mit 1 an. Da man aber auch eine Null
anzeigen will muß man immer 1 zu der Ziffer addieren die man sehen möchte.
Also das Muster für die 7 ist zB über den Index 8 in der Tabelle zu finden.


CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr007 7Segm-Besser
'
' Die Muster der 7Segment-Anzeige werden ueber eine Tabelle erzeugt


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- ---- ---- ---- => 00111111 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0000
Portc = &B0011_1111
'
'
'
' PD0 ---->-- Segm a a 7Segment-Display gemeinsame Anode
' PD1 ---->-- Segm b ----
' PD2 ---->-- Segm c f| |b
' PD3 ---->-- Segm d | g |
' PD4 ---->-- Segm e ----
' PD5 ---->-- Segm f e| |c
' PD6 ---->-- Segm g | d | dp
' PD7 ---->-- Segm dp ---- O
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' dp SEGg SEGf SEGe SEGd SEGc SEGb SEGa => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'

' ###############################################
' ##### Variablendeklaration ####################
' ###############################################

' Variable A als Byte anlegen
Dim A As Byte
' und initialisieren (Anfangswert setzen)
A = 0

' Byte-Feld (Byte-Array oder Byte-Liste) anlegen
Dim Seg(16) As Byte ' Byte-Tabelle fuer Segment-Muster
' Die Tabelle faengt beim Index 1 an (leider)
Seg(1) = &B1100_0000 ' 0 => Segmente abcdef
Seg(2) = &B1111_1001 ' 1 => Segmente bc
Seg(3) = &B1010_0100 ' 2 => Segmente abdeg
Seg(4) = &B1011_0000 ' 3 => Segmente abcdg
Seg(5) = &B1001_1001 ' 4 => Segmente bcfg
Seg(6) = &B1001_0010 ' 5 => Segmente acdfg
Seg(7) = &B1000_0010 ' 6 => Segmente acdefg
Seg(8) = &B1111_1000 ' 7 => Segmente abc
Seg(9) = &B1000_0000 ' 8 => Segmente abcdefg
Seg(10) = &B1001_0000 ' 9 => Segmente abcdfg


' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Waitms 500 ' 500ms warten
A = Seg(3) ' Muster fuer Ziffer 2 laden
Portd = A ' Muster auf PortD ausgeben


Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End

Der Quellcode als Download ...
Anhang anzeigen Mega8-HowTo_Nr007_7Segm-Besser.bas
 
einstelliger 7Segment-Zähler

Nun bauen wir uns einen Zähler der immer von 0 bis 9 zählt. Mit diesem Zähler
holen wir uns das entsprechende Muster für die Ziffer aus der Tabelle und
zeigen sie dann auf der 7Segm-Anzeige an. Wenn der Zähler also auf 5 steht
wird über eine Hilfsvariable eins dazugezählt (wir erinnern uns, die Tabelle
fängt nicht bei 0 sondern bei 1 an) und diese Hilfsvariable wird dann als Index
für die Mustertabelle verwendet. Wir sehen also den Stand des Zählers auf
der 7Segment-Anzeige.


CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr008 7Segm-Zaehler
'
' Es wird ein Zaehler von 0-9 auf einer 7Segment-Anzeige ausgegeben.


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- ---- ---- ---- => 00111111 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0000
Portc = &B0011_1111
'
'
'
' PD0 ---->-- Segm a a 7Segment-Display gemeinsame Anode
' PD1 ---->-- Segm b ----
' PD2 ---->-- Segm c f| |b
' PD3 ---->-- Segm d | g |
' PD4 ---->-- Segm e ----
' PD5 ---->-- Segm f e| |c
' PD6 ---->-- Segm g | d | dp
' PD7 ---->-- Segm dp ---- O
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' dp SEGg SEGf SEGe SEGd SEGc SEGb SEGa => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'

' ###############################################
' ##### Variablendeklaration ####################
' ###############################################

' Variable A als Byte anlegen
Dim A As Byte
' und initialisieren (Anfangswert setzen)
A = 0

Dim Zaehler As Byte
Zaehler = 0
Dim Index As Byte
Index = 0

Dim Seg(16) As Byte ' Byte-Tabelle fuer Segment-Muster
' Die Tabelle faengt beim Index 1 an (leider)
Seg(1) = &B1100_0000 ' 0 => Segmente abcdef
Seg(2) = &B1111_1001 ' 1 => Segmente bc
Seg(3) = &B1010_0100 ' 2 => Segmente abdeg
Seg(4) = &B1011_0000 ' 3 => Segmente abcdg
Seg(5) = &B1001_1001 ' 4 => Segmente bcfg
Seg(6) = &B1001_0010 ' 5 => Segmente acdfg
Seg(7) = &B1000_0010 ' 6 => Segmente acdefg
Seg(8) = &B1111_1000 ' 7 => Segmente abc
Seg(9) = &B1000_0000 ' 8 => Segmente abcdefg
Seg(10) = &B1001_0000 ' 9 => Segmente abcdfg


' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Waitms 500 ' 500ms warten
Index = Zaehler + 1 ' Index entsprechend anpassen
A = Seg(index) ' Muster fuer Ziffer laden
Portd = A ' Muster auf PortD ausgeben

Incr Zaehler ' Zaehler um 1 erhoehen (incrementieren)

If Zaehler > 9 Then ' testen ob der Zaehler ueber 9 ist
Zaehler = 0 ' wenn ja, dann Zaehler wieder auf 0 setzen
End If


Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End

der Quellcode ...
Anhang anzeigen Mega8-HowTo_Nr008_7Segm-Zaehler.bas

Und der Zähler auf der Anzeige. Der Zähler steht grade auf 4, die Hilfsvariable
"Index" steht dadurch auf 5 (wegen dem +1) und holt aus der fünften
Tabellenzeile das Muster für die Ziffer 4. Und das wird dann ausgegeben.
P1050157.JPG
Ist doch garnicht so kompliziert :D
 
Hi Dino,

mit einer DO...LOOP UNTIL x>9 innerhalb der Mainloop geht's schneller und eleganter.:)

Wenn Ihr so weiter macht, gibt's bald kaum noch Fragesteller und das Forum schläft ein...:confused::eek:
Auf der anderen Seite sind Eure "Lehrgänge" natürlich gute Starthilfen.:cool:


Grüsse,

Michael
 
Hi Michael,

mit einer DO...LOOP UNTIL x>9 innerhalb der Mainloop geht's schneller und eleganter.:)
ich wollte Schritt-für-Schritt eins auf das andere aufbauen. Es gibt sicherlich
wesentlich elegantere Läösungen. Allerdings sind diese für Anfänger am
einfachsten zu durchschauen (hoffe ich ;) )

Wenn Ihr so weiter macht, gibt's bald kaum noch Fragesteller und das Forum schläft ein...:confused::eek:
Auf der anderen Seite sind Eure "Lehrgänge" natürlich gute Starthilfen.:cool:
Es gibt so viele Spezialfälle und Timing-Dinge die man beachten muß ...
meiner Meinung nach wird es immer noch genug Probleme geben. Allerdings
retten uns die Schulungen/Tutorials/HowTos davor, immer wieder im
"Urschleim" der Programmierung rumzurühren :D :eek: :rolleyes:

Gruß
Dino
 
Hi Dino,

ich wollte Schritt-für-Schritt eins auf das andere aufbauen. Es gibt sicherlich
wesentlich elegantere Läösungen. Allerdings sind diese für Anfänger am
einfachsten zu durchschauen

hast natürlich recht. - - -

Bist ja selbst noch Basic- Anfänger....:p:p


Grüsse,

Michael
 
Bist ja selbst noch Basic- Anfänger....:p:p
Basic-Anfänger bin ich nicht sondern Bascom-Anfänger :D

Basic auf ZX81
Basic auf ZXSpectrum
Basic auf PC (GWBasic)
Basic auf PC (Quickbasic)
Basic auf Amiga (GFABasic)
evtl hab ich noch was vergessen ... waren auf jeden Fall einige

:eek: :p :p :p :p :p

Gruß
Dino
 
ok, 1.0 ür Dich....;)

das mit dem Forum und "müde werden" habe ich ernst gemeint. Knapp 4000 User - und wieviele unterhalten sich hier? Anmelden - Abgreifen Eurer/ unserer Mühe - Adios.

Gut, Thema hatte wir schon. Wenn ich da aber an Deine, Cassios, oldmax, etc Arbeit denke...Jaja - geb ja schon wieder Ruh'.


Hmm, GFfA- Basic. Ich hätte richtig Lust, die Oberfläche der Rennbahn- Steuerung unter DOS zuprogrammieren. Die Interpr./Compiler- Lizenzen hab ich noch.
Mit Grafik und Maus...:cool::D


Grüsse,

Michel
 
Hi,

Ich hätte richtig Lust, die Oberfläche der Rennbahn- Steuerung unter DOS zuprogrammieren.:cool::D

Oder in Python. Das ist noch :cool:er. Reingelesen hab ich mich schon... :D Aber das ist ein anderes Thema.

Ende :offtopic:


Grüsse,

Michel
 
sehr einfache Binär-Uhr mit Multiplexing

Der Einfachheit halber bin ich erst einmal wieder auf einzelne LEDs
zurückgegangen. Nun kommt das Multiplexing von einer LED-Matrix.
Eins vorweg ... die Binär-Uhr geht nicht genau ! Die ist nur um das Prinzip
zu erklären. Man kann sie aber als Grundlage für eine richtige Binär-Uhr
benutzen (Timer-Interrupt, Tasten zu stellen, ...) Und noch etwas
wichtiges. Die Stellen sind hier nicht mit Transistoren sondern direkt
mit dem Port geschaltet. Das geht nur weil die Vorwiderstände der LEDs
entsprechend wenig Strom durch die LEDs fließen lassen.
Die Treiber vom
PortC sind hierbei mit 20mA ausgelastet. Mehr geht nicht!




CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr009 Multiplexing
'
' Wir bauen uns eine kleine sehr einfache Binaer-Uhr


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= O=2= O=1= O=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- Row3 Row2 Row1 => 00000000 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0111
Portc = &B0000_0100
'
'
'
' PD0 ---->-- LED0 3mm gelb
' PD1 ---->-- LED1 3mm gelb
' PD2 ---->-- LED2 3mm gelb
' PD3 ---->-- LED3 3mm gelb
' PD4 ---->-- LED4 3mm gelb
' PD5 ---->-- LED5 3mm gelb
' PD6 ---->-- LED6 3mm gelb
' PD7 ---->-- LED7 3mm gelb
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' LED7 LED6 LED5 LED4 LED3 LED2 LED1 LED0 => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'
' ======= Aufbau der LED-Matrix ================
'
' PC0 (Sekunden)
' |
' | PC1 (Minuten)
' | |
' | | PC2 (Stunden)
' | | | 1k
' o------------->|--o--###---PD0 Bit0
' | | | |
' | o---------->|--o
' | | | |
' | | o------->|--o
' | | | 1k
' o------------->|--o--###---PD1 Bit1
' | | | |
' | o---------->|--o
' | | | |
' | | o------->|--o
' | | | LEDs
' : : :
' Die Stelle wird durch eine 1 (Vcc) am entsprechenden Bit von PortC eingeschaltet
' Die Bits der Stelle werden durch eine 0 (GND) beim PortD eingeschaltet. Da die Bits
' in einem Byte des Sekunden/inuten/Stundenzaehlers genau anders herum arbeiten
' also 1= Eingeschaltet muß zur Ausgabe am Port invertiert werden.


' ###############################################
' ##### Variablendeklaration ####################
' ###############################################

' Variable Stelle als Byte anlegen - fuer die Umschaltung beim Multiplexing
Dim Stelle As Byte
' und initialisieren (Anfangswert setzen)
Stelle = 1

' Variable fuer Sekunden (0..59)
Dim Sekunden As Byte
Sekunden = 0

' Variable fuer Minuten (0..59)
Dim Minuten As Byte
Minuten = 0

' Variable fuer Stunden (0..23)
Dim Stunden As Byte
Stunden = 0

' Verzoegerungszaehler - Nach x Schleifendurchlaeufen soll Sekunde +1
' Mit Hilfe dieses Zaehler kann man die "Uhr" vom Multiplexing entkoppeln
Dim Verzoegerung As Byte
Verzoegerung = 0

' Variable zum Zwischenspeichern von allem moeglichen
Dim Temp As Byte
Temp = 0


' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Waitms 10 ' 10ms warten


' ======== Zeitverarbeitung ===========
' Der Verzoegerungszaehler
' Nach 20 Durchlaeufen der Hauptschleife soll die Sekunde eins hochgezaehlt werden
' Wer wirkliche Sekunden haben moechte ...
' Bei "Waitms 10" muessten 100 Durchlaeufe in etwa eine Sekunde ergeben. Also >99
' Damit man aber auf eine Aenderung der Stunden nicht ewig warten muß hab ich es
' ein wenig beschleunigt (5 fach)
Verzoegerung = Verzoegerung + 1
If Verzoegerung > 19 Then
Verzoegerung = 0
Sekunden = Sekunden + 1
End If

' Wenn der Sekundenzaehler ueber 59 geht sollen Minuten +1 und die Sekunden wieder auf 0
If Sekunden > 59 Then
Sekunden = 0
Minuten = Minuten + 1
End If

' Wenn der Minutenzaehler ueber 59 geht sollen Stunden +1 und die Minuten wieder auf 0
If Minuten > 59 Then
Minuten = 0
Stunden = Stunden + 1
End If

' Wenn der Stundenzaehler ueber 23 geht soll er wieder auf 0
If Stunden > 23 Then
Stunden = 0
End If


' ======== Das Multiplexing =================
' Bei jedem Hauptschleifendurchlauf wird eine Stelle angezeigt.
' Nach 3 Schleifendurchlaeufen wurden alle drei Stellen einmal angezeigt
Stelle = Stelle + 1 ' Eine Stelle weitergehen (+1)
If Stelle > 3 Then ' Wir haben nur 3 Stellen (Stunden, Minuten, Sekunden)
Stelle = 1 ' also zurueck auf die erste Stelle
End If

' Die erste Stelle ausgeben (Sekunden)
If Stelle = 1 Then
Temp = Not Sekunden ' Die Bits fuer die Sekunden invertieren damit die richtigen LEDs an sind
Portd = Temp ' und ausgeben
Portc = &B0000_0001 ' und natuerlich die Stelle fuer die Sekunden anschalten
End If
' Das selbe fuer die Minuten
If Stelle = 2 Then
Temp = Not Minuten
Portd = Temp
Portc = &B0000_0010
End If
' und nochmal fuer die Stunden
If Stelle = 3 Then
Temp = Not Stunden
Portd = Temp
Portc = &B0000_0100
End If


Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End

hier der Quellcode
Anhang anzeigen Mega8-HowTo_Nr009_LED-Multiplex.bas

und noch zwei Bildchen vom Testaufbau ...
P1050159.JPG P1050161.JPG

Denn mal viel Spaß bei der Kombination mit 7Segment-Anzeigen. Das Prinzip
ist erklärt und mit ein wenig Übung sollte man aus zwei Teilen eins machen
können.

Gruß
Dino
 
Binär-Uhr mit Multiplexing und Dimmung

Hier hab ich mal ein wenig mit Multiplexing und Dimmung gleichzeitig
gespielt. Es ist zum Zeigen des Prinzips gedacht.

Damit alles etwas flüssiger aussieht habe ich den Wait auf 100µs gesetzt.
Das ganze sieht also Zählermäßig folgendermaßen aus ...

Schleifendurchlauf --> /16 (PWM-Rampe) --> /3 (Multiplexing)

Schleifendurchlauf --> /1500 (Verzögerung) --> Sekunden --> /16 (Dimmschritte) --> /2 (Hoch/Runter) --> Dimm-Durchlauf

Wobei die Uhr immer noch absolut zu schnell geht damit man nicht ewig auf
die Stunden warten muß.



CodeBox BASCOM

' #################################################
' ##### Programmentwicklung auf einem ATmega8 #####
' #################################################
' (c) 20.08.2010 by Dino
'
' Mega8-HowTo Nr010 Multiplexing und Dimmung
'
' Wir bauen uns eine kleine sehr einfache Binaer-Uhr


' Prozessor ATmega8 - Definitionsdatei fuer internen uC-Aufbau
$regfile = "m8def.dat"
' 8,000MHz interner Takt
$crystal = 8000000
' 16,000MHz Quarztakt
'$crystal = 16000000

' Groesse des Hardwarestacks fuer Ruecksprungadressen (SUBs/ISRs/...)
$hwstack = 40
' Groesse des Softwarestacks fuer Adressen von Uebergabeparameter an SUBs
$swstack = 32
' Speichergroesse fuer Uebergabeparameter an Unterprogramme, lokale Variablen
' und temporaere Werte
$framesize = 60
' Wenn man die Variablen selber sauber setzt kann man sich den Code von
' BASCOM fuer eine Speicherreinigung sparen.
$noramclear


' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PB0 ---->-- Test-LED 5mm rot
' PB1 ------- nix
' PB2 ------- nix
'
' PB3 -- MOSI |
' PB4 -- MISO | ISP-Port
' PB5 -- SCK |
'
' PB6 -- XTAL1 | Systemquarz
' PB7 -- XTAL2 | 16,000MHz
'
' ===== PortB =================================================================
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= O=0= => 00000001 => DDRB (In/Out)
' XTAL2 XTAL1 ---- ---- ---- ---- ---- LED => 00000000 => PORTB (PullUp/init)
' x x | | | | | |
'
Ddrb = &B0000_0001
Portb = &B0000_0000
'
'
'
' PC0 ------- nix
' PC1 ------- nix
' PC2 ------- nix
' PC3 ------- nix
' PC4 ------- nix
' PC5 ------- nix
' PC6 -- RESET | ISP-Port
'
' ===== PortC =================================================================
' I=7= I=6= I=5= I=4= I=3= O=2= O=1= O=0= => 00000000 => DDRC (In/Out)
' ---- Reset ---- ---- ---- Row3 Row2 Row1 => 00000000 => PORTC (PullUp/init)
' x x | | | | | |
'
Ddrc = &B0000_0111
Portc = &B0000_0100
'
'
'
' PD0 ---->-- LED0 3mm gelb
' PD1 ---->-- LED1 3mm gelb
' PD2 ---->-- LED2 3mm gelb
' PD3 ---->-- LED3 3mm gelb
' PD4 ---->-- LED4 3mm gelb
' PD5 ---->-- LED5 3mm gelb
' PD6 ---->-- LED6 3mm gelb
' PD7 ---->-- LED7 3mm gelb
'
' ===== PortD =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRD (In/Out)
' LED7 LED6 LED5 LED4 LED3 LED2 LED1 LED0 => 00000000 => PORTD (PullUp/init)
' | | | | | | | |
'
Ddrd = &B1111_1111
Portd = &B0000_0000
'
'
' ======= Aufbau der LED-Matrix ================
'
' PC0 (Sekunden)
' |
' | PC1 (Minuten)
' | |
' | | PC2 (Stunden)
' | | | 1k
' o------------->|--o--###---PD0 Bit0
' | | | |
' | o---------->|--o
' | | | |
' | | o------->|--o
' | | | 1k
' o------------->|--o--###---PD1 Bit1
' | | | |
' | o---------->|--o
' | | | |
' | | o------->|--o
' | | | LEDs
' : : :
' Die Stelle wird durch eine 1 (Vcc) am entsprechenden Bit von PortC eingeschaltet
' Die Bits der Stelle werden durch eine 0 (GND) beim PortD eingeschaltet. Da die Bits
' in einem Byte des Sekunden/inuten/Stundenzaehlers genau anders herum arbeiten
' also 1= Eingeschaltet muß zur Ausgabe am Port invertiert werden.


' ###############################################
' ##### Variablendeklaration ####################
' ###############################################

' Variable Stelle als Byte anlegen - fuer die Umschaltung beim Multiplexing
Dim Stelle As Byte
' und initialisieren (Anfangswert setzen)
Stelle = 1

' Variable fuer Sekunden (0..59)
Dim Sekunden As Byte
Sekunden = 0

' Variable fuer Minuten (0..59)
Dim Minuten As Byte
Minuten = 0

' Variable fuer Stunden (0..23)
Dim Stunden As Byte
Stunden = 0

' Verzoegerungszaehler - Nach x Schleifendurchlaeufen soll Sekunde +1
' Mit Hilfe dieses Zaehler kann man die "Uhr" vom Multiplexing entkoppeln
Dim Verzoegerung As Word
Verzoegerung = 0


' Variable zum Zwischenspeichern von allem moeglichen
Dim Temp As Byte
Temp = 0

Dim Hell As Byte
Hell = 15

Dim Rampe As Byte
Rampe = 0

Dim Updn As Bit
Updn = 0

' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Do


Waitus 100 ' 0,1ms warten


' ======== Zeitverarbeitung ===========
' Der Verzoegerungszaehler
' Nach 20 Durchlaeufen der Hauptschleife soll die Sekunde eins hochgezaehlt werden
' Wer wirkliche Sekunden haben moechte ...
' Bei "Waitms 10" muessten 100 Durchlaeufe in etwa eine Sekunde ergeben. Also >99
' Damit man aber auf eine Aenderung der Stunden nicht ewig warten muß hab ich es
' ein wenig beschleunigt (5 fach)
Verzoegerung = Verzoegerung + 1
If Verzoegerung > 1500 Then
Verzoegerung = 0
Sekunden = Sekunden + 1
' Hier wird ein wenig mit der Helligkeit gespielt
' Jeder "Sekundentakt" wird ein Schritt herauf oder herabgedimmt.
' Die Anzeige pulst also mit einem Rhytmus von 32 Sekundentakten
If Updn = 1 Then ' 1 = Hochdimmen
Incr Hell ' Helligkeit um 1/16 heller
If Hell >= 15 Then ' Volle Helligkeit erreicht
Hell = 15 ' Sicherheitshalber Maximalwert setzen (für Fehlerfall)
Updn = Not Updn ' Umschalten von Hoch- auf Runterdimmen
End If
Else ' 0 = Runterdimmen
Decr Hell ' Helligkeit um 1/16 dunkler
If Hell < 1 Then
Hell = 0 ' Sicherheitshalber Minimalwert setzen (für Fehlerfall)
Updn = Not Updn ' Umschalten von Runter- auf Hochdimmen
End If
End If
End If

' Wenn der Sekundenzaehler ueber 59 geht sollen Minuten +1 und die Sekunden wieder auf 0
If Sekunden > 59 Then
Sekunden = 0
Minuten = Minuten + 1
End If

' Wenn der Minutenzaehler ueber 59 geht sollen Stunden +1 und die Minuten wieder auf 0
If Minuten > 59 Then
Minuten = 0
Stunden = Stunden + 1
End If

' Wenn der Stundenzaehler ueber 23 geht soll er wieder auf 0
If Stunden > 23 Then
Stunden = 0
End If




' ======== Das Dimming ======================
' der Rampenzaehler fuer das Soft-PWM
' er geht von 0..15 . Also 0,1,2,..,14,15,0,1,...
' Damit eine Stelle richtig gedimmt werden kann muss sie
' natuerlich synchron zur Dimm-Rampe umgeschaltet werden.
' Darum wird erst nach beendeter Rampe die naechste Stelle eingeschaltet.
Rampe = Rampe + 1
If Rampe > 15 Then
Rampe = 0
Stelle = Stelle + 1 ' Eine Stelle weitergehen (+1)
End If



' ======== Das Multiplexing =================
' Nach Vollendung einer PWM-Rampe kommt die naechste Stelle dran
If Stelle > 3 Then ' Wir haben nur 3 Stellen (Stunden, Minuten, Sekunden)
Stelle = 1 ' also zurueck auf die erste Stelle
End If

' Die erste Stelle ausgeben (Sekunden)
If Stelle = 1 Then
Temp = Not Sekunden ' Die Bits fuer die Sekunden invertieren damit die richtigen LEDs an sind
Portd = Temp ' und ausgeben
If Hell > Rampe Then
Portc = &B0000_0001 ' und natuerlich die Stelle fuer die Sekunden anschalten
Else
Portc = &B0000_0000 ' oder wegen dimmung abschalten
End If
End If

' Das selbe fuer die Minuten
If Stelle = 2 Then
Temp = Not Minuten
Portd = Temp
If Hell > Rampe Then
Portc = &B0000_0010
Else
Portc = &B0000_0000
End If
End If

' und nochmal fuer die Stunden
If Stelle = 3 Then
Temp = Not Stunden
Portd = Temp
If Hell > Rampe Then
Portc = &B0000_0100
Else
Portc = &B0000_0000
End If
End If


Loop
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################



' ###############################################
' ##### Programm Ende ###########################
' ###############################################
End

und zum Abschluß noch einmal der Quellcode.
Anhang anzeigen Mega8-HowTo_Nr010_LED-MuxDim.bas

Was zu beweisen war ... man kann auch ohne Interrupts und Timer schon
ne Menge machen wenn man es geschickt anstellt. Genaue Zeiten für ne
Uhr wird man zwar nicht hinbekommen aber für einige Spielereien reicht es
aus.

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)