Ein Hilfesuchender Neuling stellt sich vor

Ernst

Mitglied
04. Okt. 2009
61
9
8
nähe Regensburg
Sprachen
Einen netten Gruß an alle hier.
Zu meiner Person ich bin männlich und 52 Jahre alt. Seit meinen 10 Lebensjahr
ist Elektrotechnik und speziell Elektronik mein Hobby. Ich habe auch schon eine
Unmenge an Schaltungen aus ELV, Elo, Elektor usw. erfolgreich nachgebaut.
An eines habe ich mich nie herangetraut die Pic` IC´s. Nun habe ich mir seit etwa
einen halben Jahr das myAVR Bord MK1 LPT Version 1,5 gekauft und aufgebaut.
Es funktionierte auch sofort und ich habe nach dem Lehrbuch so ziemlich alle
vorgegebenen Programme ausprobiert und zu Lehrzwecke für mich passend
umgeändert. Mir ist es auch gelungen einfache Programme selbst zu schreiben
die auch mit etwas Mühe funktionierten. Nun bin ich aber an einen Punkt angelangt
wo mir das Handbuch nicht weiter hilft. Folgendes, Ich habe mir eine Vierstellige
7 Segment Anzeige aufgebaut und an das Bord gehängt das ich mit Multiplex
ansteuere. Mein Programm ist soweit das ich die Zahlen 0- 9 in 10 Unterprogramme
geschrieben habe und diese auch je nach dem wie ich die Zahlen im Hauptprogramm
eingebe sauber als 4 Stellige Anzeige angezeigt werden. Nun aber bin ich an einen
Punkt angelangt wo ich nicht mehr weiter weis. Ich habe versucht mit den „loop´s“
als Zeitverzögerung einen Zähler zu bauen der von 0- zum Überlauf der Anzeige
hinauf zählt. Leider klappt es dann mit den Multiplexen nicht mehr weil eben der
Prozessor durch die „loop´s“ auch das Multiplexen unmöglich macht. Ich komme
einfach nicht drauf wie ich das umgehen kann. ich habe zwar gelesen das es da Timer
gibt weis aber nicht wie ich die passend programmieren soll. In den Handbuch da
steht es leider nicht so ausführlich beschrieben damit ich das Gewünschte anfangen
kann. Nun die Frage an euch, gibt es da Bücher dazu wo dies ausführlicher beschrieben
ist? Am liebsten wäre es mir wenn darin viele Programmbeispiele sind aus denen man
lernen kann. Ich bin für jede Antwort und Hilfe von euch dankbar.
Mit netten Gruß Ernst
 
Herzlich willkommen

Ich möchte Dich bei uns im Forum begrüßen :hello:

So so, nun hat Dich auch das AVR-Fieber gepackt. Sie diese Welt mal am Beispiel von myAVR-Boards und den Heften anzusehen ist sicher nicht die schlechteste Lösung.

Mir hat sich jetzt noch nicht erschlossen, welche Programmiersprache Du ausprobieren möchtest. Hast Du Dich mit Assembler versucht oder mit C, wie es die myAVR-Beschreibungen hergeben. Oder möchtest Du in BASCOm Basci einsteigen? Ein bissle was erzählen die Broschüren von Laser Solution darüber auch aber die streifen das Thema eher.

Ich würde Dir so oder so noch zusätzliche Literatur zur Programmierung der AVR's empfehlen. Es gibt gute Bücher zum Einstieg der Programmierung in C, Assembler oder BASCOM. Dort wird anhand von Beispielen auch der Umgang z.B. mit Timern erläutert.

Du solltest auch nicht davor zurück schrecken Dir das Datenblatt zum AVR als Pflichtlecktüre vorzunehmen. Es hilft wirklich, selbst wenn man am Anfang noch nicht alles versteht.

Grüße,
Markus
 
Hallo,

hab ich doch glatt übersehen ... :eek:
auch von mir ein herzliches Wilkommen :D

Ich hab mir mal kurz die Anleitung von dem Board runtergeladen (wegen Schaltplan)
Kannst Du mal erzählen die du die Anzeigen angeschlossen hast ? (Schaltplan
kritzeln). Dann hat man mal ne Übersicht was schon an welchem Port hängt.

So wie ich das aus deinem Beitrag herausgelesen hab, hast du das mit dem
Multipplex viel zu kompliziert gemacht :eek: Man benötigt nicht für jede
Zahl von 0..9 ein Unterprogramm. So etwas macht man über Tabellen viel
einfacher und eleganter :cool:

Setll einfach mal deinen Programmcode mit hier rein das man mal drüberschauen
kann.

Gruß
Dino
 
Grüßt Euch

Grüßt Euch
Zuerst einen Dank für eueren netten Empfang und das ihr mir helfen wollt.
Ich verwende zum Programmieren das Programm my AVR Workpad Plus.
Zur Lektüre, ich habe mir das Buch von Florian Schäffer AVR Hardware und
C-Programierung in der Praxis gekauft aber es hat mich auch nicht so wie
gewünscht weiter gebracht. Hier habe ich mal ein Bild von meinen „Machwerk“
geschossen, aber bitte nicht auslachen. Es ist nur ein Provisorium. Wenn die
Anzeige wie gewünscht klappt dann stelle ich eine komplette Platine dafür her
wo ich dann nur noch den fertig programmierten Prozessor einstecke.
http://img96.imageshack.us/img96/2464/p1060519.jpg
Hier ist das Programm dazu. Weiter bin ich auch aus Zeitgründen noch nicht
gekommen.
Gruß Ernst


CodeBox asm

;----------------------------------------------------------------------
; Title : myAVR Beispiel "Multiplex" für den ATmega8
;----------------------------------------------------------------------
; Funktion : 4 Stellige Anzeige
; Schaltung
;----------------------------------------------------------------------
; Prozessor : ATmega8
; Takt : 3,6864 MHz
; Sprache : Assembler
; Datum : 12.09.09
; Version : 1.0
; Autor : Ernst
; Programmer :
; Port :
;----------------------------------------------------------------------
.equ F_CPU, 3686400
.include "avr.h"
;-----------------------------------------------------------------------
;Reset and Interruptvectoren ;VNr. Beschreibung
begin:
rjmp main ; 1 POWER ON RESET
reti ; 2 Int0-Interrupt
reti ; 3 Int1-Interrupt
reti ; 4 TC2 Compare Match
reti ; 5 TC2 Overflow
reti ; 6 TC1 Capture
reti ; 7 TC1 Compare Match A
reti ; 8 TC1 Compare Match B
reti ; 9 TC1 Overflow
reti ;11 SPI, STC Serial Transfer Complete
reti ;12 UART Rx Complete
reti ;13 UART Data Register Empty
reti ;14 UART Tx Complete
reti ;15 ADC Conversion Complete
reti ;16 EEPROM Ready
reti ;17 Analog Comperator
reti ;18 TWI (IC) Serial Interface
reti ;19 Strore Program Memory Ready
;------------------------------------------------------------------------
;Start, Power ON, Reset
main:
ldi r16,lo8(RAMEND)
out SPL,r16 ;Init Stackpointer LO
ldi r16,hi8(RAMEND)
out SPH,r16 ;Init Stackpointer HI


rcall Stelle4
rcall Z1 ;Ziffer 1
rcall waitMs
rcall Stelle3
rcall Z2 ;Ziffer 2
rcall waitMs
rcall Stelle2
rcall Z3 ;Ziffer 3
rcall waitMs
rcall Stelle1
rcall Z4 ;Ziffer 4
rcall waitMs
rjmp main
;------------------------------------------------------------------------
mainloop: wdr
;------------------------------------------------------------------------
rjmp mainloop
;------------------------------------------------------------------------
Z0: ;Ziffer 0
ldi r17,0b11111100
out DDRD,17
ret
;------------------------------------------------------------------------
Z1: ;Ziffer 1
ldi r17,0b01100000
out DDRD,17
ret
;------------------------------------------------------------------------
Z2: ;Ziffer 2
ldi r17,0b11011010
out DDRD,17
ret
;------------------------------------------------------------------------
Z3: ;Ziffer 3
ldi r17,0b11110010
out DDRD,17
ret
;------------------------------------------------------------------------

Z4: ;Ziffer 4
ldi r17,0b01100110
out DDRD,17
ret
;------------------------------------------------------------------------
Z5: ;Ziffer 5
ldi r17,0b10110110
out DDRD,17
ret

;------------------------------------------------------------------------
Z6: ;Ziffer 6
ldi r17,0b10111110
out DDRD,17
ret
;------------------------------------------------------------------------
Z7: ;Ziffer 7
ldi r17,0b11100000
out DDRD,17
ret
;------------------------------------------------------------------------
Z8: ;Ziffer 8
ldi r17,0b11111110
out DDRD,17
ret
;------------------------------------------------------------------------
Z9: ;Ziffer 9
ldi r17,0b11110110
out DDRD,17
ret
;-----------------------------------------------------------------------
Stelle4:
ldi r20,0b00001000
out DDRC,20
ret
;------------------------------------------------------------------------
Stelle3:
ldi r20,0b00000100
out DDRC,20
ret
;------------------------------------------------------------------------
Stelle2:
ldi r20,0b00000010
out DDRC,20
ret
;------------------------------------------------------------------------
Stelle1:
ldi r20,0b00000001
out DDRC,20
ret
;------------------------------------------------------------------------
; UP WaitMs, Warteroutine im Millisekundenbereich
waitMs: push r16 ;r16 retten
push r17 ;r17 retten
push r18 ;r18 retten
ldi r16,10
loop1: ldi r17,10 ;Laufvariable loop1 0xFF
loop2: ldi r18,10 ;Laufvariable loop3 13 255
loop3: dec r18 ;Zähler 3 -1, hier Kalibrierung auf MCU Takt
brne loop3 ;Solange nicht NULL
dec r17 ;Zähler 2 -1
brne loop2 ;Solange nicht NULL
dec r16 ;Zähler1 -1
brne loop1 ;Solange nicht NULL
pop r18 ;r18 wiederherstellen
pop r17 ;r17 wiederherstellen
pop r16 ;r16 wiederherstellen
ret ;Rücksprung
;------------------------------------------------------------
 
Hi Ernst,

dann will ich mal ein wenig was tippen ... ;)

Hier habe ich mal ein Bild von meinen „Machwerk“
geschossen, aber bitte nicht auslachen. Es ist nur ein Provisorium. Wenn die
Anzeige wie gewünscht klappt dann stelle ich eine komplette Platine dafür her
wo ich dann nur noch den fertig programmierten Prozessor einstecke.
http://img96.imageshack.us/img96/2464/p1060519.jpg
Das würde ich nicht unbedingt als Provisorium ansehen, sieht doch gut aus :)
Bei mir ist das immer Lochrastergebastel weil ich keine Lust mehr zum panschen
mit Ätzlösung habe und auch keine Lust mir ein Einzelexemplar von ner Platine
zu bestellen.

Hier ist das Programm dazu. Weiter bin ich auch aus Zeitgründen noch nicht
gekommen.

Dann wolln wir doch mal sehen ...
ich zerleg es mal in Abschnitte ...


CodeBox asm

;----------------------------------------------------------------------
; Title : myAVR Beispiel "Multiplex" für den ATmega8
;----------------------------------------------------------------------
; Funktion : 4 Stellige Anzeige
; Schaltung
;----------------------------------------------------------------------
; Prozessor : ATmega8
; Takt : 3,6864 MHz
; Sprache : Assembler
; Datum : 12.09.09
; Version : 1.0
; Autor : Ernst
; Programmer :
; Port :
;----------------------------------------------------------------------
.equ F_CPU, 3686400
.include "avr.h"
;-----------------------------------------------------------------------
;Reset and Interruptvectoren ;VNr. Beschreibung
begin:
rjmp main ; 1 POWER ON RESET
reti ; 2 Int0-Interrupt
reti ; 3 Int1-Interrupt
reti ; 4 TC2 Compare Match
reti ; 5 TC2 Overflow
reti ; 6 TC1 Capture
reti ; 7 TC1 Compare Match A
reti ; 8 TC1 Compare Match B
reti ; 9 TC1 Overflow
reti ;11 SPI, STC Serial Transfer Complete
reti ;12 UART Rx Complete
reti ;13 UART Data Register Empty
reti ;14 UART Tx Complete
reti ;15 ADC Conversion Complete
reti ;16 EEPROM Ready
reti ;17 Analog Comperator
reti ;18 TWI (IC) Serial Interface
reti ;19 Strore Program Memory Ready
;------------------------------------------------------------------------

Schön mit Kopf und Version(Datum) und Bemerkungen ;)
Sieht recht nett aus ... Den Programmierstil kanst du beibehalten :)
Als Tip ... Schreib bei den Interrupt-Vektoren vor jedes reti ein .org
ungefähr so ...


CodeBox asm

;########## BEISPIEL VON MIR ############
; ----- INTERRUPT-VECTOREN -----
;
.cseg ; Beginn eines Code-Segmentes
.org 0x000 rjmp RESET ; Reset Handler
;.org 0x002 rjmp EXT_INT0 ; IRQ0 Handler
;.org 0x004 rjmp EXT_INT1 ; IRQ1 Handler
.org 0x006 rjmp PC_INT0 ; PCINT0 Handler (PCINT7..0)
.org 0x008 rjmp PC_INT1 ; PCINT1 Handler (PCINT14..8)
.org 0x00A rjmp PC_INT2 ; PCINT2 Handler (PCINT23..16)
;.org 0x00C rjmp WDT ; Watchdog Timer Handler
;.org 0x00E rjmp TIM2_COMPA ; Timer2 Compare A Handler
;.org 0x010 rjmp TIM2_COMPB ; Timer2 Compare B Handler
;.org 0x012 rjmp TIM2_OVF ; Timer2 Overflow Handler
.org 0x014 rjmp TIM1_CAPT ; Timer1 Capture Handler
;.org 0x016 rjmp TIM1_COMPA ; Timer1 Compare A Handler
;.org 0x018 rjmp TIM1_COMPB ; Timer1 Compare B Handler
.org 0x01A rjmp TIM1_OVF ; Timer1 Overflow Handler
;.org 0x01C rjmp TIM0_COMPA ; Timer0 Compare A Handler
;.org 0x01E rjmp TIM0_COMPB ; Timer0 Compare B Handler
;.org 0x020 rjmp TIM0_OVF ; Timer0 Overflow Handler
;.org 0x022 rjmp SPI_STC ; SPI Transfer Complete Handler
;.org 0x024 rjmp USART_RXC ; USART, RX Complete Handler
;.org 0x026 rjmp USART_UDRE ; USART, UDR Empty Handler
;.org 0x028 rjmp USART_TXC ; USART, TX Complete Handler
;.org 0x02A rjmp ADC ; ADC Conversion Complete Handler
;.org 0x02C rjmp EE_RDY ; EEPROM Ready Handler
;.org 0x02E rjmp ANEOMP ; Analog Comparator Handler
;.org 0x030 rjmp TWI ; 2-wire Serial Interface Handler
;.org 0x032 rjmp SPM_RDY ; Store Program Memory Ready Handler
.org 0x034 ; Start Hauptprogramm (erste brauchbare Adresse)
;
; ----- MAIN-PROGRAM -----
;
RESET:
ldi r16,low(ramend)
ldi r17,high(ramend)
out spl,r16 ; Stackpointer auf
out sph,r17 ; RAM-Ende setzen
;########## BEISPIEL VON MIR ############

Das hat einen wichtigen Grund ... manche AVRs haben bei den Vektoren
Platz für einen Befehl und manche für 2 Befehle. Wenn du also nur die
reti-Befehle hintereinanderschreibst, dann hast du zB bei AVRs mit mehr
Platz bei den Vektoren 2x reti bei einem Vektor drin aber nur die hälfte der
Vektoren definiert. Das könnte später mal Probleme geben.
Aber sonst ist das so ok.





CodeBox asm

;Start, Power ON, Reset
main:
ldi r16,lo8(RAMEND)
out SPL,r16 ;Init Stackpointer LO
ldi r16,hi8(RAMEND)
out SPH,r16 ;Init Stackpointer HI


rcall Stelle4
rcall Z1 ;Ziffer 1
rcall waitMs
rcall Stelle3
rcall Z2 ;Ziffer 2
rcall waitMs
rcall Stelle2
rcall Z3 ;Ziffer 3
rcall waitMs
rcall Stelle1
rcall Z4 ;Ziffer 4
rcall waitMs
rjmp main
;------------------------------------------------------------------------
mainloop: wdr
;------------------------------------------------------------------------
rjmp mainloop
;------------------------------------------------------------------------
Z0: ;Ziffer 0
ldi r17,0b11111100
out DDRD,17 ; << muß das nicht r17 heißen ?
ret
;------------------------------------------------------------------------
Z1: ;Ziffer 1
ldi r17,0b01100000
out DDRD,17 ; << muß das nicht r17 heißen ?
ret
;------------------------------------------------------------------------
Z2: ;Ziffer 2
ldi r17,0b11011010
out DDRD,17 ; << muß das nicht r17 heißen ?
ret
;------------------------------------------------------------------------
Z3: ;Ziffer 3
ldi r17,0b11110010
out DDRD,17 ; << muß das nicht r17 heißen ?
ret
;------------------------------------------------------------------------

Z4: ;Ziffer 4
ldi r17,0b01100110
out DDRD,17 ; << muß das nicht r17 heißen ?
ret
;------------------------------------------------------------------------
Z5: ;Ziffer 5
ldi r17,0b10110110
out DDRD,17 ; << muß das nicht r17 heißen ?
ret

;------------------------------------------------------------------------
Z6: ;Ziffer 6
ldi r17,0b10111110
out DDRD,17 ; << muß das nicht r17 heißen ?
ret
;------------------------------------------------------------------------
Z7: ;Ziffer 7
ldi r17,0b11100000
out DDRD,17 ; << muß das nicht r17 heißen ?
ret
;------------------------------------------------------------------------
Z8: ;Ziffer 8
ldi r17,0b11111110
out DDRD,17 ; << muß das nicht r17 heißen ?
ret
;------------------------------------------------------------------------
Z9: ;Ziffer 9
ldi r17,0b11110110
out DDRD,17 ; << muß das nicht r17 heißen ?
ret
;-----------------------------------------------------------------------
Stelle4:
ldi r20,0b00001000
out DDRC,20 ; << muß das nicht r20 heißen ?
ret
;------------------------------------------------------------------------
Stelle3:
ldi r20,0b00000100
out DDRC,20 ; << muß das nicht r20 heißen ?
ret
;------------------------------------------------------------------------
Stelle2:
ldi r20,0b00000010
out DDRC,20 ; << muß das nicht r20 heißen ?
ret
;------------------------------------------------------------------------
Stelle1:
ldi r20,0b00000001
out DDRC,20 ; << muß das nicht r20 heißen ?
ret
;------------------------------------------------------------------------

Irgendwie stellst du da ne Menge an den Dadenrichtungs-Registern für
die Ports C und D dran rum. Warum so kompliziert ? Man stellt normalerweise
alle 8 Bits eines Ports auf einmal ein. Außerdem gibt es nach meiner Meinung
keinen Befehl, mit dem man einen Wert direkt in ein Ausgangsregister schreiben
kann. Darum geht das auch immer indirekt über ein weiteres Register als
Zwischenspeicher. es müßte also zum Beispiel so heißen ...


CodeBox asm

;########## BEISPIEL VON MIR ############
ldi r18,0b00110000 ; PortB: PB4 und PB5 auf Ausgang
out ddrb,r18 ; setzen
ldi r18,0b00001001 ; PullUps bei PB0 und PB3 einschalten
out portb,r18 ; setzen


und weiter im Text ...



CodeBox asm

; UP WaitMs, Warteroutine im Millisekundenbereich
waitMs: push r16 ;r16 retten
push r17 ;r17 retten
push r18 ;r18 retten
ldi r16,10
loop1: ldi r17,10 ;Laufvariable loop1 0xFF
loop2: ldi r18,10 ;Laufvariable loop3 13 255
loop3: dec r18 ;Zähler 3 -1, hier Kalibrierung auf MCU Takt
brne loop3 ;Solange nicht NULL
dec r17 ;Zähler 2 -1
brne loop2 ;Solange nicht NULL
dec r16 ;Zähler1 -1
brne loop1 ;Solange nicht NULL
pop r18 ;r18 wiederherstellen
pop r17 ;r17 wiederherstellen
pop r16 ;r16 wiederherstellen
ret ;Rücksprung
;------------------------------------------------------------

Die Warteschleife sieht soweit gut aus ...

Aber das mit deiner Ziffernanzeige wird mit den Befehlen nix. Da ist nach
meiner Meinung noch ein kleines Verständnisproblem ;) Ich glaube, du
versuchst die Segmente und Stellen mit den DDR-Registern an- und
abzuschalten. Das geht leider so nicht. Lies dir mal folgendes durch ...

Mini-FAQ : Die Port-Register DDRx, PORTx, PINx
Das erklärt dir einige Sachen mit den Ports ...

Wie ziehe ich ein Projekt durch ... (7-Segment-Multiplexanzeige)
Das sollte dir eine andere einfachere Lösungsmöglichkeit zeigen. So bei
Beitrag #19 (Seite 2) wirds Programmtechnisch interessant. Ich mache das
über Daten-Tabellen. Auf die Art arbeiten auch Character-LCDs in ihrem
Inneren ;) Das ist sehr flexibel und einfach zu programmieren.
Ich hab die Quellcodes aber nie selber getestet. Alles im Kopf zusammengebaut
und hoffentlich fehlerfrei :rolleyes:

Gruß
Dino
 
Hallo Dino

Grüß dich Dino
Zuerst einen herzlichen Dank für deine Mühe und das du mir das so ausführlich erklärt
hast. Zu deiner Frage ob das nicht „r17 oder r20“ heißen muss. Es stimmt es muss
r17 bzw. r20 heißen warum es trotzdem funktioniert hat weiß ich selbst nicht. Inzwischen habe ich es auf r17 bzw. r20 umgeändert. Ich habe schon gemerkt das ich mit dem Programm
zwar Zahlen anzeigen kann aber dann nicht mehr weiter komme.
Das mit den „org“ wusste ich auch nicht, ich habe halt von den Begleitprogrammen das
Grundgerüst für die Programmierung verwendet. Auch für diesen Tipp noch einen Dank.
Ich finde den ersten Link von dir einfach spitze wie du das erklärt hast. So verstehe ich es sogar. Zu deinen Zweiten Link den habe ich bei weiten noch nicht ganz durch studiert Aber ich weiß jetzt zumindest wie man das anpacken muss und wie so ein Programm überhaupt
ausschaut. Ein Stoppuhrprogramm habe ich mir aus dem Internet herunter geladen es funktioniert auch auf meinen Bord und meiner Anzeige wenn man davon absieht das die Anzeige nicht im Sekundentakt hoch zählt weil die dort einen Quarz von 16 MHz verwenden und ich am Board ja nur einen mit 3,6864 MHz am Board habe. Das Problem dabei ist
das ich nur den Hex- Code von dem Programm habe und ich das Programm nicht anschauen bzw. daraus lernen kann. Meine Frage gibt es eigentlich ein Computerprogramm das den
Hex-Code wieder in Assembler zurückverwandeln kann?
Gruß Ernst
 
Hi Ernst,

Das mit den „org“ wusste ich auch nicht, ich habe halt von den Begleitprogrammen das
Grundgerüst für die Programmierung verwendet. Auch für diesen Tipp noch einen Dank.
nennt sich "Assembler-Direktiven" ...
Ich hab da was für dich ...
AVR_assembler_tutorial_beginner_de.pdf
hab ich mal irgendwo im Internet gefunden
AVR_Assembler_User_Guide_DOC1022.PDF
und das hab ich irgendwo mal bei Atmel gefunden (glaube ich). Ist aber wohl
auch in der Help zum AVR-Studio mit drin.
Kapitel 4.5 => Assembler-Directives

Zu deinen Zweiten Link den habe ich bei weiten noch nicht ganz durch studiert Aber ich weiß jetzt zumindest wie man das anpacken muss und wie so ein Programm überhaupt ausschaut.
Eigentlich recht einfach. Über den Characterwert wird ein Tabelleneintrag
indiziert, der dann das Segment-Muster enthält. Das ist bei DotMatrix
genauso nur das man da etwas mehr Bytes pro Eintrag benötigt.

Ein Stoppuhrprogramm habe ich mir aus dem Internet herunter geladen es funktioniert auch auf meinen Bord und meiner Anzeige wenn man davon absieht das die Anzeige nicht im Sekundentakt hoch zählt weil die dort einen Quarz von 16 MHz verwenden und ich am Board ja nur einen mit 3,6864 MHz am Board habe. Das Problem dabei ist
das ich nur den Hex- Code von dem Programm habe und ich das Programm nicht anschauen bzw. daraus lernen kann. Meine Frage gibt es eigentlich ein Computerprogramm das den
Hex-Code wieder in Assembler zurückverwandeln kann?
Wie bei Radio Eriwan : Im Prinzip ja ... :rolleyes:
Das Problem ... wenn irgendwo im Hexcode mittendrin Daten liegen werden
die vom Disassembler auch als Maschinencode interpretiert. Dadurch kann
der Rest dahinter voll durcheinander kommen. Wenn man also ein Programm
als Hex-Code (bereits übersetzt) für andere zum proggen ins Internet stellt
und nicht möchte das es jemand erfolgreich disassembled, dann muß man
nur ab und zu mal Daten einstreuen :cool:

Noch ein kleiner Ausschnitt mit einer Tabelle in Assembler ...


CodeBox asm

; ###########################################################
; ##### LCD-Zeilentabelle ###################################
; ###########################################################
;
; High r31 Low r30
; -------- --------
; |76543210| |76543210| Z-Register (r31,r30)
; -------- --------
; 0x10 00000zzz
; |||
; Zeilen-Nummer ==> addr(zzz)=Startadresse im CHR-RAM des LCD

.cseg ;===== Sitronix ST7066U-0A in Powertip PC1602-E (Pollin) =====
.org 0x1D00 ;Startadresse der Cursor-Tabelle ( H=0x3A , L=0x00 )
; => im Speicher liegt der Start wegen 16Bit dann bei 0x3A00
; PC 0x1D00 => Speicherstelle 0x3A00 (wegen 16Bit-Zellen)
; Speicherzugriff mit ZH/ZL dann aber auf die Speicherstelle
; # ACHTUNG!! Es koennen nur gerade Anzahlen an Bytes geschrieben werden
cursorcalc: .db 0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40 ; 3A00-1A07 - Cursor-Startwerte
; fuer Reihen
; * Zeile 1 - 0 ... 39 (0x00...0x27) 16 Zeichen sichtbar
; * Zeile 2 - 64 ... 103 (0x40...0x67) 16 Zeichen sichtbar

Das wichtigste dabei ... Die Daten und Adressen im Flash sind 16Bit breit
und die Adressierung mit dem LPM-Befehl ist 8Bit-breit. Also verdoppelt sich
die Adresse aus dem Flash beim LPM-Befehl.

Gruß
Dino
 
Grüß dich Dino

Grüß dich Dino
Das mit den DDR- Registern habe ich jetzt verstanden. Ich habe damit praktisch zwischen
Ein- und Ausgang hin und her geschaltet und so die Anzeige bekommen. Künftig werde ich es nach deiner Methode machen und die benötigten Ports damit auf Ausgang schalten und mit
den PORT- Befehl die gewünschten Ausgänge an- und ausschalten. Mir ist jetzt auch klar geworden wie das geht die einzelnen Zahlen meiner Anzeige in ein Register ablegen und nicht wie ich es gemacht habe in ein Unterprogramm. Mit dem „.cseg und .org „ klappt es bei meinen Assemblerprogramm nicht, da kommt dann sofort die Fehlermeldung „ Unbekannter Ausdruck“. Ich bin ja so dankbar daß ich hier jemanden fragen kann wie man es macht. Als ich mich mit etwa 10 Jahren mit Elektronik befasst habe da gab es keine Hilfe für mich. Ein Buch wo einfache Transistorschaltungen gezeichnet gewesen sind ist alles gewesen was mir zur Verfügung stand. Als ich dann in eine Radio-, Fernsehreparaturwerkstatt gegangen bin um mir die Bauteile zu kaufen (so Elektronikläden wie Conrad oder so kannte ich ja damals nicht) dann hieß es die Transistoren gibt es ja schon lange nicht mehr. Ich weis noch wie mir der dann einen Fotowiderstand besorgt hatte und ich damit eine funktionierende Lichtschranke aufgebaut habe. Ich bin so glücklich gewesen. Meine erste Platine bestand aus einer Pertinaxplatte in die ich Löcher gebohrt habe und so meine Leiterbahnen gezogen habe, an diese lötete ich dann meine Bauteile an. Später dann fing ich an Platinen selbst zu ätzen. Bei den ersten Platinen sahen die Leiterbahnen dann aus als seien die Motten drüber gewesen. Auch wenn es hier nicht zum Thema passt, ich wollte einfach einmal schildern wie meine Anfänge gewesen sind.
Gruß Ernst
 
Grüßt euch

Zuerst ein Danke an das AVR Team für den Geburtstagsgruß.
Die letzten Monate kam ich aus Zeitgründen einfach nicht dazu
an meinen AVR etwas zu machen. Ich muß mich inzwischen mit der
Pogramierung erst wieder richtig hereinarbeiten. Ein Problem aber konnte
ich einfach nicht lösen. Ich habe Daten ins Programm geschrieben
aber bringe meinen AVR einfach nicht dazu das er die liest.
Gruß Ernst
 
Hi Ernst,

Ich habe Daten ins Programm geschrieben
aber bringe meinen AVR einfach nicht dazu das er die liest.
also die Daten mit .cseg im Assemblercode ins Flash gepackt.
Denk dran das mit .org immer 16Bit-Adressen gemeint sind wegen den
16Bit breiten Befehlen und im Pointerregister die 8Bit breite Adresse beim
lesen der Daten stehen muß.

Also bei ...

.org 0x0100

für die Datenadresse im Flash muß zB im Z-Registerpaar (ZH undd ZL oder
auch r30/r31) die Byte-Adresse angegeben werden. Also ...

Z=0x0200 oder ZH=0x02 / ZL=0x00

Mit .org wird in Wortbreite adressiert und mit dem Z-Registerpaar in
Bytebreite. Also immer der doppelte Wert.

Grruß
Dino
 
Grüßt euch alle.
Ich möchte euch hiermit schöne Osterfeiertage wünschen.
Über die Feiertage habe ich entlich wieder etwas Zeit für
mein AVR- Board. Nun noch einen Dank für euere Hilfe für
mich.
Gruß Ernst
 
Grüßt euch
Die letzten Monate kam ich einfach aus Beruflichen Gründen nicht dazu an meiner Bastelei mit meinem AVR-Bord weiter programieren. Wenn man als Elektriker ständig Überstunden schieben darf dann kann man Zuhause einfach
nichts Elektrisches mehr sehen. Mit meiner Vierstelligen Digitalanzeige bin ich inzwischen soweit das ich beliebige Zahlen von 0 - 9999 Anzeigen kann wenn ich an einer Stelle des Programmes die Zahl von 0 - 255 bzw. 256 aufwärts
als zweite Zahl eingebe. Ich habe ein Programm das eigendlich für etwas anderes gedacht gewesen ist umgeschrieben. Beim Versuch das er die Zahlen von selbst hoch zählt bin ich soweit gekommen das er das auch soweit macht allerdings mit der Prozessorgeschwindigkeit. Beim Versuch das Zählen zu verlangsamen mittels Zeitschleife klappte dann das Multipexen nicht mehr. Das Hauptproblem ist bei mir das ich mit meinen Board blos in Assembler programieren kann. Die vielen anderen Programme wie Win-AVR oder AVR-Studio kann ich nicht anwenden
da die dann beim Programmüberspielen auf das Board das Board nicht erkennen. In der Auswahlliste von den Programierboards ist das meinige natürlich nicht dabei. Manchmal bin ich am verzweifeln gewesen.
Gruß Ernst
 
Einen netten Gruß von mir Prix und vor allen Dingen einen Dank für den Tipp und das Programm. Mir gefällt an dem Programm das es in Deutsch ist da meine Englischkenntnisse beschränkt sind.
Gruß Ernst
 
Hallo,

da ich sowas mal im Rahmen eines Hobbyprojektes gemacht habe, poste ich einfach mal den Code für ein funktionierendes Display.
Das Display unterstützt 3-6 7-Segment Displays mit common anode(CA) oder common cathode(CC), ist durch PWM Helligkeitsregulierbr, wird über RS232 mit Daten versorgt und ist dank Timer Interrupt flackerfrei.

Es wurde etliche hundertmal nachgebaut und wird in Homecockpit Flugsimulatoren angewendet.

Es ist zwar für den Anfang bestimmt schwer zu verstehen, ich glaube aber das dein Problem mit dem gestörten Multiplexer durch Verwenden des Timer Interrupts verschwindet.

Tipp: verwende AVR Studio mit dem AVR gcc Compiler. Damit es flashed, könnte derAVRispII für ~40EUR eine gute Investition sein.


/********************************************************************
FSBUS Display

Dirk Anderseck July 2004

ATTINY2313, 4MHz

17.4.05 R-Command 133 stores a local brightness base level on each display board
25.4.05 ATTINY version
*********************************************************************/
#include <avr/interrupt.h>
#include <avr/eeprom.h>

#include <stdio.h>
#include <string.h>

#define BV(x) (1<<x)

#define u08 unsigned char
#define u16 unsigned short

#define PORT_SEG PORTB

#define PORT_DSP PORTD
#define D1 6
#define D10 5
#define D100 4
#define D1000 3
#define D10000 2
#define D100000 1

#define CMD_RESET 128
#define CMD_SETCID 129
#define CMD_BRIGHTNESS 130
#define CMD_POWER 131
#define CMD_DECIMALPOINT 132
#define CMD_BASEBRIGHT 133

volatile u08 rbuf[4]; // Code (0-15) einer Stelle rbuf[0] = rechtes Display
volatile u08 dbuf[6];
volatile u08 rxidx;
volatile u08 cid; // CID dieses Bausteins
volatile u08 cmd;
volatile u08 val;
volatile u08 dp; // position of dp (0 = off; 1 = rechtes Display)
volatile u08 dispix; // Index der multiplexed displays
volatile u08 flags;
#define F_CC 0x01 // common anode
#define F_NEEDSAVE 0x02
#define F_SHOWCID 0x04
volatile u08 bright;
volatile u08 battery;
volatile u08 cidcnt;
volatile u08 rqcid;

u16 tickcount;
u08 dummy;
u08 ircv;
u08 basebright;

void Reset(void);
int Delay (int ms);

//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
int main( void )
{
int x;

/*
* ATTINY2313 das FUSE Bit CKDIV8 bestimmt den initialen Clock Scale
* hier wird der Teilfaktor auf 0 gesetzt
*/
CLKPR = BV(CLKPCE);
CLKPR = 0;

cid = eeprom_read_byte((uint8_t *)0);

bright = 128;
basebright = eeprom_read_byte((uint8_t *)2);
battery = 100;
rxidx = 99;

if (eeprom_read_byte((uint8_t *)1) != (cid | 0x80))
{
cid = 31;
basebright = 0;
}

tickcount = 0;
// Timer 0 Prescaler
// 0: timer stop 1: cpu clock 2: clk*8 3: clk*64 4: clk*256 5: clk*1024
// Interrupt erfolgt nach Überlauf von TCNT0(8bit)
TCCR0A = 0;
TCCR0B = 2; // 4ms
TCNT0 = 0; // Timer0 Counter
TIMSK = BV(TOIE0); // Enable Interrupt
//timer_enable_int(_BV(TOIE0));

// UART
UBRRH = 0; // bps MSB
UBRRL = 12; // bps LSB
UCSRA = 0;
UCSRB = ( BV(RXCIE) | BV(RXEN) ); // enable receiver
UCSRC = (BV(USBS) | BV(UCSZ1) | BV(UCSZ0)); // 8bit no parity, 2 Stopbit


Reset();
sei();
flags = F_SHOWCID;

while (1)
{
if (flags & F_SHOWCID)
{
flags &= ~F_SHOWCID;
for (x=0; x<sizeof(dbuf); x++)
dbuf[x] = 0x0f;
dp = 0;
dbuf[1] = cid>=10 ? (cid / 10) : 15;
dbuf[0] = cid % 10;
Delay (1000);
for (x=0; x<sizeof(dbuf); x++)
dbuf[x] = 0x0f;
}
if (flags & F_NEEDSAVE)
{
flags &= ~F_NEEDSAVE;
eeprom_write_byte ((uint8_t *)0, cid);
eeprom_write_byte ((uint8_t *)1, 0x80 | cid);
eeprom_write_byte ((uint8_t *)2, basebright);
Delay (1000);
//flags = F_SHOWCID;
Reset();
}
}
}

//---------------------------------------------------------------------
void Reset()
{
dp = 0;
dispix = 0;
ircv = 7;
rxidx = 255;

DDRB = 0xff;
DDRD = 0xff;
}

//---------------------------------------------------------------------
int Delay (int ms)
{
int cnt = 0;
for (; ms; ms--)
for (cnt = 0; cnt<10000;cnt++);
return cnt;
}

//---------------------------------------------------------------------
SIGNAL (SIG_TIMER0_OVF)
{
u08 x=0;
u08 i=0;
int ib;

#ifdef DSP_CA
PORTB = 0xff;
#else
PORTB = 0x00;
#endif

ib = bright + 128 - basebright;
if (ib < 0)
ib = 0;
if (ib > 255)
ib = 255;

tickcount++;
if (tickcount & 1) {
TCNT0 = ib;
return;
}

// Display 5 4 3 2 1 0
// Index rbuf 5 4 3 2 1 0
// PORTD 6 5 4 3 2 1
if (++dispix > 5)
dispix = 0;

#define SA 0x02
#define SB 0x08
#define SC 0x40
#define SD 0x20
#define SE 0x80
#define SF 0x01
#define SG 0x04
#define Sdp 0x10
#define S0 0x02
#define S1 0x04
#define S2 0x08
#define S3 0x10
#define S4 0x20
#define S5 0x40

switch (dbuf[dispix])
{
case 0: x = SA|SB|SC|SD|SE|SF; break;
case 1: x = SB|SC; break;
case 2: x = SA|SB|SD|SE|SG; break;
case 3: x = SA|SB|SC|SD|SG; break;
case 4: x = SB|SC|SG|SF; break;
case 5: x = SA|SC|SD|SG|SF; break;
case 6: x = SF|SE|SG|SC|SD; break;
case 7: x = SA|SB|SC; break;
case 8: x = SA|SB|SC|SD|SE|SF|SG; break;
case 9: x = SA|SB|SC|SG|SF; break;
case 10: x = SG; break; // -
case 11: x = SA|SC|SD|SG|SF; break; // S
case 12: x = SD|SE|SF|SG; break; // t
case 13: x = SB|SC|SD|SE|SG; break; // d
case 14: x = SA|SD|SE|SF|SG; break; // E
case 15: x = 0; break;
}
if (dispix == (dp-1))
x |= Sdp;
switch (dispix) {
case 0: i = S0; break; // least significant position
case 1: i = S1; break;
case 2: i = S2; break;
case 3: i = S3; break;
case 4: i = S4; break;
case 5: i = S5; break;
}

if (battery > 80)
{
#ifdef DSP_CA
PORTB = ~x;
PORTD = i;
#else
PORTB = x;
PORTD = ~i;
#endif
}
TCNT0 = 255 - ib;
}

//---------------------------------------------------------------------
SIGNAL (SIG_USART0_RX)
{
u08 i;
u08 x;
u08 adr;

i = UCSRA;
x = UDR;
if ((i & BV(FE)) || (i & BV(DOR))) // Framing error or data overrun
return;

if (x & 0x80)
{
// new block
adr = (x & 0x7c) >> 2;
cmd = (x & 0x02) ? 0x80 : 0;
val = x & 0x01;

if (adr && (adr != cid)) {
rxidx = 255;
return;
}

rxidx = 0;
for (i=0; i<4; i++)
rbuf = 0xff;
return;
}

if (rxidx >= 4)
return;

if (cmd & 0x80)
{
// ordinary command
if (++rxidx == 1)
{
cmd |= x;
return;
}

// 3. und letztes Byte
val |= (x<<1);

switch (cmd)
{

case CMD_BASEBRIGHT:
basebright = 255 - val;
flags = F_NEEDSAVE;
for (x=0; x<6; x++)
{
dbuf[x] = val % 10;
val /= 10;
}
break;

case CMD_RESET:
cli();
if (val)
flags |= F_SHOWCID;
Reset();
sei();
break;

case CMD_SETCID:
val &= 0x1f;
if (cidcnt && (rqcid != val))
cidcnt = 0;

dbuf[0] = 3 - cidcnt;
dbuf[1] = 0x1f;
dbuf[2] = val % 10;
dbuf[3] = val / 10;
dbuf[4] = 0x1f;
dbuf[5] = 0x1f;

rqcid = val;
if (++cidcnt >= 3)
{
// SET NEW CID
cid = rqcid;
flags = F_NEEDSAVE;
}
return;

case CMD_BRIGHTNESS:
bright = val;
break;

case CMD_POWER:
battery = val;
break;

case CMD_DECIMALPOINT:
dp = val & 0x07;
break;
}
cidcnt = 0;
rxidx = 255;

} else {
// display
rbuf[rxidx++] = x;
if (x & 0x40)
{
// Display, copy to display buf
dbuf[0] = ((rbuf[0] & 0x30) >> 2) | ((rbuf[1] & 0x30) >> 4);
dbuf[1] = rbuf[0] & 0x0f;
dbuf[2] = rbuf[1] & 0x0f;
dbuf[3] = ((rbuf[2] & 0x30) >> 2) | ((rbuf[3] & 0x30) >> 4);
dbuf[4] = rbuf[2] & 0x0f;
dbuf[5] = rbuf[3] & 0x0f;
return;
}
if (rxidx >= 4)
rxidx = 255;
}
 
Hi zusammen
Nun möchte ich auch mal etwas dazugeben, zumal endlich wieder Assembler gesprochen wird:)
Ich arbeite mit dem Board von Pollin und bin ebenfalls in der (Misslichen) Lage, war mit AVR Studio entwickeln zu können und dann mit PonyProg die Hex Files zu flashen. Hab mich aber dran gewöhnt und nun zu´m eigentlichen Grund:
Vielleichtschaust du mal bei der "Konkurenz" bei Mikrocontroller.net in die Tutorials. Ein Link ist ja glaub ich schon dabei gewesen. Die sind ganz gut und haben mir bei meinen Problemen viel geholfen. Nun weiß ich auch aus Erfahrung, das eine Arbeit mit einem µC nervig ist, wenn man nicht sieht, was er grad treibt und ob die vorgesehenen Routinen so abgearbeitet werden , wie erwartet. Deshalb hab ich ein Programm geschrieben, OpenEye, um in den Controller zu schauen und die Wariablenwerte auszulesen. Dieses Programm kann hier runtergeladen werden. Du mußt nur in deinen Controller eine RS 232 programmieren und die Registerwerte über Variablen führen. Falls es dich interessiert, es ist auch eine Doku dabei und zur Not kannst du auch nachfragen.
Gruß oldmax
 
Grüßt Euch
Ich wollte mich wieder einmal bei euch melden. Vor ein paar Monaten
da habe ich mir von AVR die sechsstellige Digitalanzeige geleistet.
In dem Begleitheft sind interessante Programme wie Stoppuhr,
Echtzeituhr und Voltmeter drinnen gewesen. Ich habe aus dem
Programmbeispielen viel gelernt. Zuvor hatte ich ja immer mit dem
Multiplexen von so Anzeigen Probleme. Wenn ich Beispielsweise einen
Zähler in dem Programm integrierte dann klappte es mit dem Multiplexen
der Anzeige nicht mehr und so weiter. Jetzt bin ich so glücklich denn
meine Programme klappen einfach wunderbar. Ich habe von dem
Originalprogramm den Teil der für das Multiplexen zuständig ist als
Grundgerüst gelassen und dann meine eigenen Programme dazu geschrieben.

Aus den Voltmeter-Programm da habe ich ein 6 Fach Voltmeter gemacht
das an den 6 Eingängen an Port C die Spannungen abfragt und am Display
der Reihe nach anzeigt.

Aus dem Stoppuhr- Programm das im Original nur die Sekunden bis 999999
hoch zählte habe ich so umgestaltet das es Zehntel-, Sekunden, Minuten und
Stunden zählt. Mit den Tasten kann ich die Stoppuhr anhalten, weiterlaufen
lassen oder auf 0 zurücksetzen.

Zur Programmierübung habe ich noch ein Programm geschrieben das am
Display Impulse die ich per Taster erzeuge hoch zählt und ein Programm das
von einer Einprogrammierten Zeit (Stunden, Minuten Sekunden) bis 0 herunter
zählt. Beim Zählerstand 0 habe ich noch einen Schaltausgang (LED) dazu
programmiert.

Die letzten zwei Wochen habe ich mir schon wieder was Neues angetan.
In meiner Bastelkiste fand sich noch eine 5 mal 7 Ledmatrixanzeige mit der ich
damals nicht das gewünschte anfangen konnte. Ich habe sie an mein AVR-Board
angeschlossen und auch schon die ersten Erfolge erzielt. Wenn ihr möchtet könnt
ihr hier anschauen wie mein Board jetzt ausschaut. Mit den Drahtbrücken schaut
es aber etwas wirr aus.
Gruß Ernst
http://imageshack.us/f/809/p1110539v.jpg/
 
Hi Ernst,

Ich habe aus dem
Programmbeispielen viel gelernt. Zuvor hatte ich ja immer mit dem
Multiplexen von so Anzeigen Probleme. Wenn ich Beispielsweise einen
Zähler in dem Programm integrierte dann klappte es mit dem Multiplexen
der Anzeige nicht mehr und so weiter. Jetzt bin ich so glücklich denn
meine Programme klappen einfach wunderbar.
...
Wenn ihr möchtet könnt
ihr hier anschauen wie mein Board jetzt ausschaut. Mit den Drahtbrücken schaut
es aber etwas wirr aus.http://imageshack.us/f/809/p1110539v.jpg/
sehr schön ;)
Wenn man das Multiplexing verstanden hat dann ist imKopf schon ein großer Knoten geplatzt ;)

Ich hoffe, es ist dir recht wenn ich das Bild deiner Erfolge direkt ins Forum packe ...
p1110539v_.jpg
Ich hab dein JPG-Bild auf 73% Qualität runtergerechnet damit es hochzuladen geht.
Es ist immer schade wenn die Bilder aus den Internetdiensten mit der Zeit verschwinden und der Thread dadurch einen großen Teil seines Sinns verliert.

Denn mal weiter so und noch viel Erfolg. Wenn es mal Probleme gibt weißt du ja wo du Hilfe bekommst ;)

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)