PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Keine Anzeige am LCD



sisi
02.09.2015, 15:46
Hallo alle Zusammen,

ich möchte mithilfe ATtiny26 Mikrocontroller eine spannung zwischen 0 und 5 v Messen, Vorerst gabe ich zur Erfassung der Spannung ADC eigenstellt. Darauf hin habe ich LCD intialisiert.. Soweit gut.. und ich habe dann das Programm laufen lassen, jedoch sehe keinen Balken an meinem LCD und es tut sich nichts..

Hier ist mein Quellcode:


;Voreinstellungen

.device ATtiny26
.nolist
.include "tn26def.inc"
.list

;Deklarationen

.def mp=R16 ;allgemeine Register
.def adhigh=R17 ;Ergebnis vom ADC

;Stackpointer initialisiern

ldi mp, RAMEND
out SP, mp

;Definition der Ein und Ausgänge

ldi mp, 0b11111111
out DDRB, mp

ldi mp, 0b11111110
out DDRA,mp

ldi mp,0b00000000
out TCNT0,mp


;Einstellungen des ADC Wandlers
;Die Spannung von 5V (analog) in eine 8 bit (digital) zahl umwandeln
;Initialisierund des ADMUX Registers

ldi mp,0b00100000 ;AVCC Betriebsspannung als Referenzspannung, Datenrichtung linksbündig
out ADMUX,mp ;ADC0 Analoger Eingang

;Initialisierung des ADCSR Registers

ldi mp,0b10000101 ;AD Wandler aktiviert, Einzelwandlung "Single Conversion", Vorteiler 32
out ADCSRA,mp

; ADC für eine Einzelwandlung starten

Main:
sbi ADCsRA, ADSC

LOOP:

sbic ADCSRA, ADSC
rjmp LOOP

;oberste 8 Bit einlesen

in adhigh,ADCH


;LCD

.def mp1=R18
.def mp2=R19
.def mp3=R20

;RS auf PA4
;E auf PA5
;PB4..PB5 auf PA1..PA2
;PB6..PB7 auf PA6..PA7

.equ LCD_PORT=PORTA
.equ LCD_DDR=PORTA
.equ PIN_E=5
.equ PIN_RS=4

LCD_init:

ldi mp1,11111110
out LCD_DDR,mp1

ldi mp3,6

powerupwait:

rcall delay5ms
dec mp3
brne powerupwait ;Wenn 5ms abgelaufen dann Schleife verlassen

ldi mp1, 0b00000011 ;muss dreimal hintereinander gesendet werden
out LCD_PORT, mp1

rcall LCD_enable ;1
rcall delay5ms
rcall LCD_enable ;2
rcall delay5ms
rcall LCD_enable ;3
rcall delay5ms

; 4-Bit-Modus einstellen

ldi mp1, 0b00000010
out LCD_PORT, mp1
rcall LCD_enable
rcall delay5ms


; Funktionen setzen
;DL=0-->4-Bit-Schnittstelle
;N=1--->zwei Zeilen
;F=0--->5x8 Matrix

ldi mp1,0b00101000
rcall LCD_command

;Anzeigenkontrolle ein/aus
;D=1 Anzeige ein
;C=0 Cursor aus
;B=0 Blinken aus

ldi mp1,0b00001100
rcall LCD_command


;fertig initialisiert

ldi mp1,0b00000100
rcall LCD_command

ret

;Löschen Anzeige

LCD_clear:

ldi mp1,0b00000001
rcall LCD_command
rcall delay5ms
ret

;Zurück

LCD_home:

ldi mp1,0b00000010
rcall LCD_command
rcall delay5ms
ret


;Datenbyte an das LCD senden
LCD_data:

mov mp2,mp1
swap mp1
andi mp1,0b00001111
sbr mp1, 1<<PIN_RS
out LCD_PORT,mp1
rcall LCD_enable

andi mp2, 0b00001111
sbr mp2,1<<PIN_RS
out LCD_PORT, mp2
rcall LCD_enable
rcall delay50us
ret


;Befehl an das LCD senden
LCD_command:

mov mp2,mp1
swap mp1
andi mp1,0b00001111
out LCD_PORT,mp1
rcall LCD_enable
andi mp2,0b00001111
out LCD_PORT, mp2
rcall LCD_enable
rcall delay50us
ret


LCD_enable:

sbi LCD_PORT, PIN_E ;Enable High
nop
nop
nop
cbi LCD_PORT, PIN_E ;Enable Low
ret


;Zeitschleife

;50 µs Pause

delay50us:
ldi mp1, $42

delay50us_:
dec mp1
brne delay50us_
ret

;Pause für die Befehle
;5ms Pause bei 1 MHz

delay5ms:

;äußere Schleife

ldi mp1, $21

;innere Schleife

Loop0:

ldi mp2, $C9

Loop1:

dec mp2
brne Loop1
dec mp1
brne Loop0
ret




Kann mir jemand sagen wo der Fehler ist?
Stimmt etwas mit der Initialisierung nícht??


viele Grüße

avr_racer
03.09.2015, 08:20
Hallo,

schonmal am Kontrastpoti gestellt ?? denn müsste die erste Zeile ohne Initialisierung nen dunklen Balken anzeigen, Kontrast leicht runter drehen bis zur Hälfte. Nach der Init sollte der Balken verschwinden.

Mir fällt auf das du zwar das LCD inites aber weder eine Umwandlung der Zahlen vornimmst noch das du die Daten zum LCD schickst?????

1. Grundinitialisierung des Controllers mit Stack/Register/Ram alles zum Anfang machen
2. LCD initialisieren
3. ADC initialisieren

4. Main abarbeiten
4.1 Messung durchführen
4.2 Zahlenwerte wandeln in bevorzugtes Format
4.3 Ausgabe auf LCD
4.4 Sprung zu 4

Schau mal unter

https://www.roboternetz.de/community/forums/70-Bascom-C-ASM-Sketch-Codesammlung-Programmschnipsel

für Atmega16 / 8 oder tiny2313 wie dort die Init gemacht wurde.

sisi
03.09.2015, 12:01
Hallo ,

erstmal vielen Dank für die schnelle Antwort....
Ist es eigentlich nicht egal ob ich zuerst LCD oder ADC initialisiere?

zu Punkt 4.1) Wie führe ich Messungen durch? Ich dachte diese geschieht indem ich ADC initialisiere?
zu Punkt 4.2) Ist dies mit zahlenwerte wandeln gemeint?

lcd_number:
push temp1 ; die Funktion verändert temp1 und temp2,
push temp2 ; also sichern wir den Inhalt, um ihn am Ende
; wieder herstellen zu können

mov temp2, temp1 ; das Register temp1 frei machen
; abzählen wieviele Hunderter
; in der Zahl enthalten sind
;** Hunderter **
ldi temp1, '0'-1 ; temp1 mit ASCII '0'-1 vorladen
lcd_number_1:
inc temp1 ; ASCII erhöhen (somit ist nach dem ersten
; Durchlauf eine '0' in temp1)
subi temp2, 100 ; 100 abziehen
brcc lcd_number_1 ; ist dadurch kein Unterlauf entstanden?
; nein, dann zurück zu lcd_number_1
subi temp2, -100 ; 100 wieder dazuzählen, da die
; vorherhgehende Schleife 100 zuviel
; abgezogen hat
rcall lcd_data ; die Hunderterstelle ausgeben

;** Zehner **
ldi temp1, '0'-1 ; temp1 mit ASCII '0'-1 vorladen
lcd_number_2:
inc temp1 ; ASCII erhöhen (somit ist nach dem ersten
; Durchlauf eine '0' in temp1)
subi temp2, 10 ; 10 abziehen
brcc lcd_number_2 ; ist dadurch kein Unterlauf enstanden?
; nein, dann zurück zu lcd_number_2
subi temp2, -10 ; 10 wieder dazuzählen, da die
; vorherhgehende Schleife 10 zuviel
; abgezogen hat
rcall lcd_data ; die Zehnerstelle ausgeben

;** Einer **
ldi temp1, '0' ; die Zahl in temp2 ist jetzt im Bereich
add temp1, temp2 ; 0 bis 9. Einfach nur den ASCII Code für
rcall lcd_data ; '0' dazu addieren und wir erhalten dierekt
; den ASCII Code für die Ziffer


pop temp2 ; den gesicherten Inhalt von temp2 und temp1
pop temp1 ; wieder herstellen
ret ; und zurück

viele Grüße

- - - Aktualisiert - - -

also ich sehe gar keine verändung am LC Display

avr_racer
03.09.2015, 14:33
Ja ist es aber selber legt man sich ja seinen Ablauf fest und wenn die Sachen schon mal funktioniert haben kann man sie auch als erstes hinschreiben bzw aktivieren...

> zu Punkt 4.1) Wie führe ich Messungen durch? Ich dachte diese geschieht indem ich ADC initialisiere?

das ist nur die Vorbereitung das der ADC eingestellt/aktiviert ist. Außer ich habe nur einen Messkanal dann kann man den Free Running Mode nutzen...

> ; ADC für eine Einzelwandlung starten
> Main:
> sbi ADCsRA, ADSC

da steht Einzelwandlung starten d.h. ADSC (StartConversion) aber nur bis die Wandlung fertig ist und wenn sie beendet ist bleib sie das auch.

Um immer wieder eine neue Messung zu starten, für nur EINEN Messkanal, wäre es Sinnvoll den FREE RUNNING MODE zu nutzen, wenn EINE Messung aber über die SingleConversion gemacht werden soll, dann muss das ADSC-Bit immer wieder neu gesetzt werden um die Wandlung anzustoßen.

Warum gibs das ?? Ganz einfach, es gibt nur ein ADC aber mehrere Messkanäle, die man nutzen möchte/könnte/will und die Umschaltung kann nur gemacht werden wenn kein Wandlung gestartet wurde/ist.

Hoffe das es soweit verständlich ist. Ab und an das Datenblatt nutzen, denn dort steht ne janze Menge drin....


> zu Punkt 4.2) Ist dies mit zahlenwerte wandeln gemeint?

mmhh überleg mal kannst du sofort auf dem LCD den Hex oder Bin oder Octawert richtig interpretieren???? Die meisten eher weniger, also nimmt man eine Zahlsystemwandlung, von xxSystem zum dezimalen System vor.


Hinweis um Quellcode zum posten, rechts unten mal auf erweitert klicken, dann kann auch Quellcode lesbarer eingestellt werden... UND GANZ WICHTIG immer den kompletten Code einstellen weil sonst keiner die Zusammenhänge erkennt, es ist ziemlich umständlich sonst zu lesen.... is ja keine Klatschpresse hier :DD....

Kurze Init als Hilfe... auf das Zeichen # klicken und dann den Text einfügen



;.device ATtiny26
;.nolist <<<<kann man weg lassen
.include "tn26def.inc"
;.list <<<<<kann man weg lassen

;Deklarationen

.def mp =R16 ;allgemeine Register
.def adhigh =R17 ;Ergebnis vom ADC Achtung der ADC HAT ADCH:ADCL-Register
.def mp1 =R18
.def mp2 =R19
.def mp3 =R20

;RS auf PA4
;E auf PA5
;PB4..PB5 auf PA1..PA2
;PB6..PB7 auf PA6..PA7

.equ LCD_PORT=PORTA
.equ LCD_DDR=PORTA
.equ PIN_E=5
.equ PIN_RS=4

;Stackpointer initialisiern

ldi mp, RAMEND
out SP, mp

racll lcd_init ;init
rcall clear_lcd

rcall adc_init

Loop:
;und hier steht dein Hauptprogramm
rjmp loop


Frage: Wann hast du angefangen zu programmiern mit Assembler??

sisi
05.09.2015, 20:48
Hallo, also nicht lang.. so richtig seit einem Monat befasse ich mich mit assembler...

- - - Aktualisiert - - -

Mein Quellcode ist falsch ..Im AVR Tutorial wurde Atmega8 benutzt und ich verwende ein Attiny26 und somit sind die Pins anders belegt.
Ich musste mein Code verändern um überhaupt noch eine Verbindung mit dem LCD herzustellen :(((

avr_racer
06.09.2015, 12:54
1 Monat und dann gleich LCD 0.o das vllt doch bisschen viel aufeinmal...

Das heißt du musst die Pins nur im Quellcode anpassen. Sind deine Datenpins nicht alle am selben Port, wirds richtig schwierig da du die Bits umherspringen lassen musst, also eher auf einen halben Port die 4 DataPins anschließen und die anderen beiden können beliebig irgendwo angeschlossen werden.

Wie ist der bisherige Sachstand also Stand Verkabelung Software usw???

AtTiny26_origin.asm


;# Projekt: #
;# #
;# #
;# Taktfrequenz des AVR: 4 MHz #
;# #
;# CS-SOFT #
;###########################################

.include "tn26def.inc" ;Tiny 26

;hier Rregisterdeklarationen
.def math1h = r8
.def math1l = r9
.def math2h = R10
.def math2l = r11
.def matherghh = r12
.def mathergh = r13
.def mathergl = r14
.def mathergll = r15

.def temp0 = r16 ;
.def temp1 = r17 ;
.def temp2 = r18
.def temp3 = r19 ;
.def temp4 = r20
.def cnt = r21

;Konstanten
;für UART KOM
.equ cpu = 4000000
.equ Baud = 9600
.equ UBRRx = cpu/(16*Baud)-1

;Definitionen für den RAM
;**********SRAM
.equ erg_k = $0060 ;erg_k wird bis zu 5 weiteren bytes genutzt sprich erg_k+5
.equ ocra0 = $0065 ;für T0
.equ ocrb0 = $0066 ;für T0
.equ ocra1h = $0067 ;;;;;
.equ ocra1l = $0068 ;;;;;;;; für T1 A channel
.equ ocrb1h = $0069 ;;;;;
.equ ocrb1l = $006a ;;;;;;;; für T1 B channel
.equ icr1xh = $006b ;;;;;
.equ icr1xl = $006c ;;;;;;;; für T1 ICR
.equ eep_adr = $006d ;eeprom
.equ hadc = $006e ;High ADC
.equ ladc = $006f ;Low ADC

;ADC Deklaerationen
.equ ADC_ddr_a = ddrA
.equ ADC_Port_a = PortA
.equ ADC_Pin_a = PinA
.equ Chan0 = 0
.equ Chan1 = 1
.equ Chan2 = 2
.equ Chan3 = 3
.equ Chan4 = 4
.equ Chan5 = 5
.equ Chan6 = 6
.equ ADC_ddr_b = ddrB
.equ ADC_Port_b = PortB
.equ ADC_Pin_b = PinB
.equ Chan7 = 4
.equ Chan8 = 5
.equ Chan9 = 6
;.equ Chan10 = 7;=RESET FINGER WEG SONST AUSGESPERRT

;***************************Einsprungadressen***** ******************
.cseg
.org $0000
rjmp stack
.org $0001 ;1
reti;rjmp INT_0
.org $0002 ;2
reti;rjmp I/O_pins chnage maks Interrupt
.org $0003 ;3
reti;rjmp INT_T1_COMPa
.org $0004 ;4
reti;rjmp INT_T1_COMPb
.org $0005 ;5
reti;rjmp INT_T1_OVF
.org $0006 ;6
reti;rjmp INT_T0_OVF0
.org $0007 ;7
reti;rjmp INT_USI_Strt
.org $0008 ;8
reti;rjmp INT_USI_OVF
.org $0009 ;9
reti;rjmp INT_EE_rdy
.org $000a ;a
reti;rjmp ANA_COMP
.org $000b ;b
reti;rjmp ADC

;***************************Init mit allem drumdran*****************
stack: ldi temp0,low(ramend) ;Stackpointer festlegen
out sp, temp0

; rcall lcd_init
; rcall lcd_clear
rcall adc_init

Hauptprogramm:
rcall adc_chan_0
rcall start_convers

rcall adc_chan_1
rcall start_convers

rcall adc_chan_2
rcall start_convers

rcall adc_chan_3
rcall start_convers

rcall adc_chan_4
rcall start_convers

rcall adc_chan_5
rcall start_convers

rcall adc_chan_6
rcall start_convers

rcall adc_chan_7
rcall start_convers

rcall adc_chan_8
rcall start_convers

rcall adc_chan_9
rcall start_convers

rjmp Hauptprogramm

.include "adc_tiny26.asm"
;************************************************* ******************


adc_tiny26.asm

/*
.equ ADC_ddr = ddr?
.equ ADC_Port = Port?
.equ ADC_Pin = Pin?
.equ Chan0 = 0
.equ Chan1 = 1
.equ Chan2 = 2
.equ Chan3 = 3
.equ Chan4 = 4
.equ Chan5 = 5
.equ ref5 = $1312
.equ ref256 = $09d0
*/

;mit Interrupt
start_convers_int:
in temp0,adcsra ;wenn ADFR aktiv dann nur adc_read nötig für jeweiligen kanal
ori temp0,(0<<ADEN|1<<ADSC|0<<ADFR|1<<ADIE|1<<ADPS2|0<<ADPS1|0<<ADPS0) ;freigabe ADC Abtastrate zwischen 50Khz-200Khz Teiler=32 single mode
out adcsra,temp0 ;
sei
ret

;ohne Interrupt dann abfrage auf des bits ADSC=1?????
start_convers:
in temp0,adcsra
ori temp0,(0<<ADEN|1<<ADSC|0<<ADFR|0<<ADIE|1<<ADPS2|0<<ADPS1|1<<ADPS0);freigabe der Messung
out adcsra,temp0
start_convers2: ;;;
sbic ADCSR,ADSC ;;;;;; diese kleine routine braucht man nicht wenn man mit ints arbeitet
rjmp start_convers2 ;;;
in temp0,adcl ;wichtig erst low
in temp1,adch ;dann high lesen sonst erg müll
sts ladc,temp0
sts hadc,temp1
ret

;******************************adc_interrupt****** ****************
adc_rdy:
in temp0,adcl ;wichtig erst low
sts ladc,temp0
in temp1,adch ;dann high lesen sonst erg müll
sts hadc,temp1
reti


;***********************adc_init****************** ***********
adc_init:
ldi temp0,(0<<Chan6|0<<Chan5|0<<Chan4|0<<Chan3|0<<Chan2|0<<Chan1|0<<Chan0)
out ADC_ddr_a,temp0
ldi temp0,(0<<Chan6|0<<Chan5|0<<Chan4|0<<Chan3|0<<Chan2|0<<Chan1|0<<Chan0)
out ADC_Pin_a,temp0

ldi temp0,(0<<Chan9|0<<Chan8|0<<Chan7)
out ADC_ddr_b,temp0
ldi temp0,(0<<Chan9|0<<Chan8|0<<Chan7)
out ADC_ddr_b,temp0

in temp0,adcsra
ori temp0,(1<<ADEN|0<<ADSC|0<<ADFR|0<<ADIE|1<<ADPS2|0<<ADPS1|1<<ADPS0) ;
out adcsra,temp0

rcall adc_ref_5V

ret

;*********************AREF
adc_ref_5V: ;AVCC on
in temp0,admux
andi temp0,(0<<REFS1|0<<REFS0|1<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0) ;AVCC with external capacitor at AREF pin
out admux,temp0
ret

adc_ref_extern: ;AREexternF
in temp0,admux
andi temp0,(0<<REFS1|0<<REFS0|1<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0)
ori temp0,(0<<REFS1|1<<REFS0|0<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0) ;AVCC with external capacitor at AREF pin
out admux,temp0
ret

adc_ref_256V1: ;2,56V on
in temp0,admux
andi temp0,(0<<REFS1|0<<REFS0|1<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0)
ori temp0,(1<<REFS1|0<<REFS0|0<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0) ;AVCC with external capacitor at AREF pin
out admux,temp0
ret

adc_ref_256V2: ;extern on
in temp0,admux
andi temp0,(0<<REFS1|0<<REFS0|1<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0)
ori temp0,(1<<REFS1|1<<REFS0|0<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0) ;AVCC with external capacitor at AREF pin
out admux,temp0
ret

;*******************Channels********************** ************************************************** **************
adc_chan_0:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
out admux,temp0
ret

adc_chan_1:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|1<<MUX0)
out admux,temp0
ret

adc_chan_2:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|1<<MUX1|0<<MUX0)
out admux,temp0
ret

adc_chan_3:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|1<<MUX1|1<<MUX0)
out admux,temp0
ret

adc_chan_4:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|0<<MUX3|1<<MUX2|0<<MUX1|0<<MUX0)
out admux,temp0
ret

adc_chan_5:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|0<<MUX3|1<<MUX2|0<<MUX1|1<<MUX0)
out admux,temp0
ret

adc_chan_6:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|0<<MUX3|1<<MUX2|1<<MUX1|0<<MUX0)
out admux,temp0
ret

adc_chan_7:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|0<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0)
out admux,temp0
ret

adc_chan_8:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|1<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
out admux,temp0
ret

adc_chan_9:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX4|1<<MUX3|0<<MUX2|0<<MUX1|1<<MUX0)
out admux,temp0
ret

adc_chan_BG:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|0<<MUX0)
out admux,temp0
ret

adc_chan_GND:
in temp0,admux
andi temp0,(1<<REFS1|1<<REFS0|1<<ADLAR|0<<MUX4|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0)
ori temp0,(0<<REFS1|0<<REFS0|0<<ADLAR|1<<MUX4|1<<MUX3|1<<MUX2|1<<MUX1|1<<MUX0)
out admux,temp0
ret

sisi
06.09.2015, 15:26
Hallo,

danke für die Antwort... Mein Problem liegt erstmal in der Steuerung des LCDs.. Hierbei ist ist mein Ziel erstmal den Mikrocontroller so zu programmieren, das am LCD etwas zusehen ist. Im tutorial als auch in den Foren ist der Mikrocontroller und der LCD immer gleich angeschlossen, wie:


[C 4bit-Interface ;;
;; DB4-DB7: PD0-PD3 ;;
;; RS: PD4 ;;
;; E: PD5 ]

Und bei mir sind die Datenleitungen aufgeteilt:

[;RS auf PA4
;E auf PA5
;PB4..PB5 auf PA1..PA2
;PB6..PB7 auf PA6..PA7
]

PB4 mit PA1
PB5 mit PA2
PB6 mit PA6
PB7 mit PA7

Daher kann ich nicht einfach den Quellcode aus dem Tutorial nehmen bzw ich weiss nicht was ich da alles verändern soll, damit dieser meiner Schaltung anpasst..

avr_racer
06.09.2015, 23:05
Ah jetzt kommen wir der Sache schon näher... ok

1. Warum hast du das so gemacht?

2. Der Quellcode kann definitiv genutzt werden, dein Problem ist nur das du die Deklarationen im Moment noch fehlinterpretierst, da dir einfach die Routine/Erfahrung fehlt aber wenn es denn unbedingt mit dieser Verdrahtung sein soll, müssen die Pins per Software umgeroutet werden...

du schriebst "ich weiss nicht was ich da alles verändern soll, damit dieser meiner Schaltung anpasst.. "

Es sind die Deklarationen zu ändern und zwar so, das die Hw mit der SW past, soll heißen...


.equ port_lcd_x = porta ;auch für parallel notwendig
.equ ddrx_lcd_x = ddra ;auch für parallel notwendig
; Pinbelegungen
; STD ;STD= 1te Testplatine noch kein Endstadium

.equ LCD_P1 = 1
.equ LCD_P2 = 2
.equ LCD_P3 = 6
.equ LCD_P4 = 7

.equ PRS = 4 ;= PIN4 nur für alte routine parallel im 4bit modus
.equ PEnable = 5 ;= PIN5 nur für alte routine parallel im 4bit modus

code ist nur ein Beispiel, aber das Hinzubekommen ist für jemanden der 1 Monat ASM macht deutlich zu hoch.
Lasse die Finger davon also von der komischen Verdrahtung Daten am besten soweit es geht parallel führen....

3. Wenn es änderbar ist, dann tausche PA2 <-> PA5, PA1 <-> PA4 in der Hardware und du kannst dann die Routine
1:1 nutzen da der Aufwand deutlich geringer ist.

sisi
08.09.2015, 14:46
So jetzt habe ich die Datenleitungen verändert und versucht den Code anzupassen.
PB7 - PA7
PB6 - PA6
PB5 - PA5
PB4 - PA4

RS - PA1
E - PA2

es tut sich was undzwar ich sehe am LCD schwarze Balken, schon mal ein Fortschritt.. Ich versuche ein A auszugeben : ldi mp1, 'A' , jedoch erschein kein A am LCD Bildschirm.. Muss noch weitere Fehler im Code finden, falls jemanden einen Fehler findet ...




[; Voreinstellungen
.device Attiny26
.nolist
.include "tn26def.inc"
.list

;Deklarationen

;Voreinstellungen

.device ATtiny26
.nolist
.include "tn26def.inc"
.list

;Deklarationen

.def mp=R16
.def mp1=R17
.def mp2=R18
.def mp3=R19

;Stackpointer initialisieren

ldi mp, RAMEND
out SP, mp

;Ein- und Ausgänge definieren

ldi mp, 0b11111111
out DDRB, mp

ldi mp, 0b11111110
out DDRA, mp

ldi mp, 0b00000000
out TCNT0, mp

; Initialisierung des LCD
;Datenleitungen

.equ lcd_A7_ddr=DDRA
.equ lcd_A7_port=PORTA
.equ lcd_A7=7

.equ lcd_A6_ddr=DDRA
.equ lcd_A6_port=PORTA
.equ lcd_A6=6

.equ lcd_A5_ddr=DDRA
.equ lcd_A5_port=PORTA
.equ lcd_A5=5

.equ lcd_A4_ddr=DDRA
.equ lcd_A4_port=PORTA
.equ lcd_A4=4

;LCD Enable

.equ lcd_e_ddr= DDRA
.equ lcd_e_port=PORTA
.equ lcd_e=2

;LCD Selektionsleitung 1=Dateneingang 0=Befehlseingang

.equ lcd_rs_ddr= DDRA
.equ lcd_rs_port=PORTA
.equ lcd_rs=1


LCD_Init:

sbi lcd_A7_ddr, lcd_A7
sbi lcd_A6_ddr, lcd_A6
sbi lcd_A5_ddr, lcd_A5
sbi lcd_A4_ddr, lcd_A4

sbi lcd_e_ddr,lcd_e
sbi lcd_rs_ddr,lcd_rs

ldi mp3,6

powerupwait:

rcall delay5ms
dec mp3
brne powerupwait ;nach Ablauf von 5ms Schleife verlassen

; dreimal hintereinander senden

ldi mp1, 0b00000011 ;1
rcall lcd_enable
rcall delay5ms

ldi mp1, 0b00000011 ;2
rcall lcd_enable
rcall delay5ms

ldi mp1, 0b00000011 ;3
rcall lcd_enable
rcall delay5ms

;4-Bit-Modus einstellen

ldi mp1, 0b00000010
rcall lcd_enable
rcall delay5ms

; Funktionen setzen
;DL=0-->4-Bit-Schnittstelle
;N=1--->zwei Zeilen
;F=0--->5x8 Matrix

ldi mp1,0b00101000
rcall LCD_command

;Anzeigenkontrolle ein/aus
;D=1 Anzeige ein
;C=0 Cursor aus
;B=0 Blinken aus

ldi mp1,0b00001100
rcall LCD_command


;fertig initialisiert

ldi mp1,0b00000100
rcall LCD_command

;Anzeige löschen

LCD_clr:

ldi mp1, 0b00000001
rcall LCD_command
rcall delay5ms

LCD_home:

ldi mp1, 0b00000010
rcall LCD_command
rcall delay5ms

;Datenbyte an das LCD senden

LCD_Data:

mov mp2, mp1
swap mp1
andi mp1, 0b11110000
sbr mp1, 1<<lcd_rs
rcall lcd_enable

andi mp2, 0b11110000
sbr mp2, 1<<lcd_rs
rcall lcd_enable
rcall delay50us

;Einen Befehl an das LCD

LCD_command:
mov mp2,mp1
swap mp1
andi mp1,0b11110000
rcall lcd_enable
andi mp2,0b11110000
rcall lcd_enable
rcall delay50us

;Enable Puls

lcd_enable:

sbi lcd_e_ddr,lcd_e ;enable gesetzt
nop
nop
nop
cbi lcd_e_ddr,lcd_e ;enable gelöscht
ret

;Pause nach jeder Übertragung

delay50us:

push mp1
ldi mp1,$10
Loop0: dec mp1
brne Loop0
pop mp1
ret


;Längere Pause für manche Befehle

delay5ms:

push mp1
push mp2
ldi mp1,$07
Loop1: ldi mp2,$ED
Loop2: dec mp2
brne loop2
dec mp1
brne loop1
pop mp1
pop mp2
ret

ldi mp1, 'A'
rcall lcd_data]

- - - Aktualisiert - - -

Tut mir leid, ich schaffe es immer noch net einen code richtig einzufügen..Also # und dann kommt [code] , in welchem Feld füge ich nun den Code?

avr_racer
09.09.2015, 14:08
Hallo,

Anpassung Datenleitung check

Der Kontrast ist zu stark und deshalb könntest du evtl nix sehen, also am Kontrastpoti drehen so das die Balken heller werden. Sollte nun Buchstaben zu sehen sein funktioniert schonmal die Init und ein Teil der Ausgabe aber die einzelnen Programmteile für sich selbst durchtesten ob diese so arbeiten wie sie sollen. Ist das einmal gemacht müsstest du rein theoretisch die Unterprogramme nicht mehr ändern.

Fürs Forum um den Code einzustellen fehlt dir am Ende nur folgendes >>>> [/Code] <<<<

Deine Init für die Daten ist noch bisschen heftig du brauchst es nur wie folgt zu ändern sie Code


.
.
.
.
; Initialisierung des LCD
;Datenleitungen
;Warum SO?? ganz einfach der Port wird umbenannt damit brauch man jetzt nicht
.equ lcd_ddr = DDRA ;alle Unterprogramme absuchen und es ändern sondern nur hier und man brauch den Port nur einmal umbenennen ;)
.equ lcd_port = PORTA
; hier kriegen die PinNummern nur Namen, ähnlich wie ne IP-Adresse, denn kein Mensch merkt sich die IP sondern man merkt sich nur www.google.de
.equ lcd_A7 = 7 ; Die PinNummern können auch auf andere Ports angewendet werden da diese ja nicht nur an PortA vorkommen ;)
.equ lcd_A6 = 6
.equ lcd_A5 = 5
.equ lcd_A4 = 4
.equ lcd_e = 2
.equ lcd_rs = 1
.
.
.
.
LCD_Init:

ldi mp, ( 1<<lcd_A7 | 1<<lcd_A6 | 1<<lcd_A5 | 1<<lcd_A4 | 1<<lcd_e | 1<<lcd_rs ) ; ist übersichtlicher und ist das selbe wie 0b011110110
out lcd_ddr,mp ;Datenrichtung als Output konfigurieren



Packe deine .equ-Deklarationen direkt unter die RegisterDefinitionen, damit behältst du Übersicht und musst nicht in weiteren Dateien umherkramen um was zu ändern sondern nur in der Hauptdatei. Man kann auch Deklarationen vor Unterprogramme ändern aber das ist noch ne Nummer zu hoch für dich.

Nachtrag: Berücksichtige den Ablauf deines Hauptprogrammes welches im vorpost nicht zu erkennen ist. Worauf will ich hinaus? Auf das, das du ohne die call-Funktion zu nutzen einfach in die Init-Routine springts aber ganz unten deine Ausgabe mit dem 'A' steht, da wird dein µC aber nie hinkommen folgender Ablauf zur Initalisierung MUSS dringends eingehalten werden



.
.
.
.
stack: ldi temp0,low(ramend) ;Stackpointer festlegen
out sp, temp0
rcall lcd_init
rcall lcd_clear
ldi mp1, 'A'
rcall lcd_data

Hauptprogramm:
;Warum steht hier nix ??
;ganz einfach du gibts das A direkt nach der Init aus, da der Cursor auf adresse 0 geinit
;wird, steht das A an Position 0, was das erste Zeichen im LCD wäre.
;Das schöne ist, das der Text nicht ständig gesendet werden muss weil du nur
;sagst welcher Buchstabe an welcher Position steht und das auch nur wenn du
;Text/Zahlen ausgeben möchtest/musst
rjmp Hauptprogramm
.
.
.
.



Hinweis: Im Leben kann man nicht alles wissen deshalb muss man auch ab und an was kopieren, um es zu verstehen. Überleg mal wie du das Schreiben gelernt hast... Buchstaben solange schriftlich wiederholt bis der Ablauf von Anfang bis Ende quasi im Hirn eingebrannt war und das ist kopieren in total einfachster Form... Also lieber gut kopiert als schlecht selbst geschrieben !!!!! Zumindest um einen Anfang zu haben und um zu begreifen!!!!!!!!

sisi
10.09.2015, 12:31
Hi,

danke ich werde mal deine Rat befolgen....

avr_racer
11.09.2015, 05:33
Moin ok

geb mal nen bisherigen Sachstand bitte denn laufen so richtig tuts ja noch nicht oder???

sisi
11.09.2015, 13:19
Hallo,

also immer noch hats sich nichts getan.. Ich habe einiges an meinem Code verändert und trotzdem sehe ich nichts...
Ich gucke mall weiter und probiere bis etwas am LCD ausgegeben wird..

avr_racer
12.09.2015, 10:49
OK Poste mal bitte als Zip Datei den kompletten Quellcode denn schau ich mal drüber. Dann umgehen wir auch gleich das Problem mit der CodeFormatierung hier im Forum... erstmal... ;)

sisi
13.09.2015, 16:30
Hi,

der veränderte Code ist im Anhang als Zip-Datei beigefügt...Ich gehe davon aus, dass dieses Mal der Code keine Fehler enthält...

avr_racer
13.09.2015, 22:11
Hey ho,

AAAALLLSSSOOOO du weißt gar nicht wie knapp du vor dem Ziel bist!!!!!!!!!!!!!!!!!!!!!!!!

Dein Problem ist das Verständniss wie man die 8Bit-Ansteuerung in eine 4bit-Ansteurung umwandelt und welche Daten als erstes übermittelt werden müssen,
damit sich das 2x4Bit-Word zu 1x8BitWord zusammensetzt.


Problem ist in den Unterroutinen des

LCD-Command
LCD-Data

zu suchen.

In der ZIP findest du die modifizierte Variante, beide mal mit einander vergleichen und durchsimulieren was da passiert und wo genau der Unterschied liegt.

Dein zusätzliches Problem ist das Grundverständiss vom Aufbau eines Programmes in ASM und wann man wie welche CALL'S oder xJUMPS man nutzt.

Am besten hier mal nachlesen und verstehen
http://www.avr-asm-tutorial.net/avr_de/index.html

Probiers mal aus und bei Problemen einfach durchschreiben.... ;)

sisi
15.09.2015, 07:33
Hallo,

ich hätte gerade noch eine Verständnisfrage zur LCD_Data ( LCD_Command).. Ich habe Kommentare eingefügt und würde gerne wissen ob diese richtig sind.

LCD_DATA
mov mp2, mp1
andi mp1, 0b11110000 ; untere Nibble auf Null gesetzt
sbr mp1, 1<<lcd_rs ;RS auf H setzen
out lcd_port, mp1 ;Ausgabe obere Nibble (1111)
rcall lcd_enable

swap mp2 ;vertauschen der 4 höherwertigen Bits mit den 4 niederwertigen bits (entspricht 00001111)
andi mp2, 0b11110000 ;obere Nibble auf Null setzen
sbr mp2, 1<<lcd_rs ;RS auf L setzen
out lcd_port, mp2 ; Ausgabe der unteren Nibble ( entspricht 1111)

rcall lcd_enable
rcall delay50us
ret

avr_racer
15.09.2015, 07:52
Kommt noch die Frage zu LCD DATA/COMMAND oder bezieht sich das auf die Kommentare??? 0.o

Kommentare sind soweit in Ordnung


LCD_DATA:
mov mp2, mp1
andi mp1, 0b11110000 ; untere Nibble auf Null gesetzt << ok
sbr mp1, 1<<lcd_rs ;RS auf H setzen << ok
out lcd_port, mp1 ;Ausgabe obere Nibble (1111) << ok
rcall lcd_enable

swap mp2 ;vertauschen der 4 höherwertigen Bits mit den 4 niederwertigen bits (entspricht 00001111) <<joar optimaler: vertauschen der des High und Low-Nibble
andi mp2, 0b11110000 ;obere Nibble auf Null setzen << ok
sbr mp2, 1<<lcd_rs ;RS auf L setzen << falsch auch hier RS wird zu 1
out lcd_port, mp2 ; Ausgabe der unteren Nibble ( entspricht 1111) << ok

rcall lcd_enable
rcall delay50us
ret


geb mal Sachstand wie weit du bist!

RoboHolIC
17.09.2015, 15:11
Enthält lcd_enable eine kurze Wartezeit zwischen setzen und löschen der enable-Leitung?
Der enable-Puls darf nicht beliebig kurz sein.