Hallo miteinander!
Ich habe gerade einen ADC mit dem Programm MPLAB programmert (Code ist
im Anhang) und wollte das Programm so gestalten, dass sich die 8 LED's
am Microcontroller von Links nach rechts je nach Spannunsgbeaufschlagung
einschalten d.h.; bei 0 VOlt soll keine LED leuchten und bei 5 Volt
sollen alle LED's leuchten.
Mein Problem ist jedoch, dass die LED's willkürlich zu leuchten
beginnen.
Der Programmiercode ist als PDF- Documetn angehängt.
Der Microcontroller ist ebenfalls als PDf angehängt.
Ich bitte euch darum vielleicht einen kurzen Blick darüber zu werfen und
mir eventuell den/ die Fehler zu nennen.
Ich bedanke mich schonmal im Vorraus!
MFG Tonei!
Du hast den fremden ASM-Code nicht wirklich verstanden, gell? Sonst
wüsstest du, dass dir die LEDs die oberen 8bit des A/D-Wandlers im
Binärformat anzeigen. Also, Code umschreiben, so dass jede LED ab einem
gewissen Wert leuchtet und fertig ist deine Aussteuerungsanzeige.
Wobei DIE Schaltung in der Praxis ohnehin nicht laufen würde - der
16F877 hat keinen Internen Oszillator und ich sehe dort nirgends eine
Taktquelle ;-)
Hallo,
ich habe Dir ein paar Beispiele beiglegt. Ich vermute das die
Ausrichtung im ADRESH nicht korrekt ist oder in der Config etwas nicht
stimmt.
Viele Grüße
Ingo
sagt er ja, dass es läuft.
Aber es löst nicht seine Aufgabe.
Anton. überleg mal.
Vom ADC kriegst du 256 verschiedene Zahlen. Je nach Spannung. Du hast
aber nur 8 LED. Es ist daher völlig unlogisch das ADC Ergebnis einfach
so auf die LED zu legen. Das kann nicht das realisieren, was du dir
vorstellst.
Michi schrieb:> Chris B. schrieb:>> und ich sehe dort nirgends eine>> Taktquelle ;-)>> OSI, Pin 16
Der Pin heisst T1OSI und ist der Eingang für den TIMER1-Oszillator.
Und vor allem sollte mal PORTA auch als ANALOGEINGANG definiert
werden..a la Datenblatt:
BCF STATUS, RP0 ;
BCF STATUS, RP1 ; Bank0
CLRF PORTA ; Initialize PORTA by clearing output data latches
BSF STATUS, RP0 ; Select Bank 1
MOVLW 0x06 ; Configure all pins
MOVWF ADCON1 ; as digital inputs
MOVLW 0x.. ; (1)
MOVWF TRISA ;
(1)Hier setzt du deinen Wert entsprechend der Funktionen der einzeln
Pins ein.
Hallo Leute
Vielen Dank für die tatkräftige Unterstützung jedoch habe ich es immer
noch nicht geschafft mein Programm zum Laufen zu bringen.
Habe jetzt noch sowas ähnliches im Internet gefunden und mit dem
vorherigen Programmen etwas vermischt. Jedoch zeigt es mir immer noch
Errors an und es funktioniert nicht.
Vielleicht könnt ihr nochmals einen Blick drüber werfen.
Würde mich sehr freuen!
MFG ANTON
Anton P. schrieb:> Habe jetzt noch sowas ähnliches im Internet gefunden und mit dem> vorherigen Programmen etwas vermischt. Jedoch zeigt es mir immer noch> Errors an und es funktioniert nicht.
Ja in der Tat und es ist auch kaum Verwunderlich.
Wenn der Zielcontroller ein PIC16F877 sein soll, dann hat der eben kein
VRCON Register wie auch kein CMCON Register.
Dieses "Zusammenkopierte" aus diversen Quellen (eigene Initialisierung,
ein Fragment aus der AN700 von MICROCHIP und die "AD-Wandlung" mit nicht
vorhandenem Comperator) durchblicke ich (ohne maximalen Zeitaufwand)
ehrlich gesagt nicht.
Vielleicht solltest du beim ursprünglichen Programm mit dem AD-Wandler
weitermachen, wenn du dort die Ports (besonders PORTA) richtig
konfigurierst bist du dem Ziel wesentlich näher als mit dieser
"Variante".
Oder einfach mit einer blinkenden LED beginnen.....
Hallo Anton,
wenn Du anstatt des PDF-Files Deinen Code als ASM-File anghängt hättest,
dann könnte man den Code
1. besser lesen
2. MPLAB mal drüber laufen lassen und die Fehler korrigieren...
mfG Ottmar
Ottmar K. schrieb:> Hallo Anton,> wenn Du anstatt des PDF-Files Deinen Code als ASM-File anghängt hättest,> dann könnte man den Code> 1. besser lesen> 2. MPLAB mal drüber laufen lassen und die Fehler korrigieren...>> mfG Ottmar
Hallo Ottmar!
Danke für deinen Hinweis habe jetzt im Anhang das ASM- File angehängt
und bitte darum dieses mal anzusehen und eventuell die Fehler
auszubessern.
Nochmal zur gewollten Funktion:
Je nach Spannungswert an der Spannungsquelle sollen die 8 LED's
leuchten.
D.h.: Bei 0V keine LED und bei 5V alle LDS.
Microcontroller PIC 16F877
DANKE
MFG ANTON
Hi
>Nochmal zur gewollten Funktion:>Je nach Spannungswert an der Spannungsquelle sollen die 8 LED's>leuchten.>D.h.: Bei 0V keine LED und bei 5V alle LDS.
Dann reduziere den ADC-Wert auf die obersten 3 Bit und schiebe Einsen
entsprechen dieses Werte von rechts in ein mit Null initialisiertes
Register.
Wie das in PIC-Assembler aussieht weiß ich nicht.
MfG Spess
Hallo Anton,
anbei ist nochmals ein Beispiel von mir. Ich denke das ist ganz genau
das was Du benötigst.
Bei A/D-Wert 0 leuchtet keine LED - bei A/D-Wert 255 leuchten alle. Die
Taktfrequenz beträgt 20 Mhz. Bei andere Frequent solltest du dies im
Quelltext und in der Erholungspause des AD-Wandlers beachten.
Solltest Du die oberen drei Bits noch benötigen, solltest du das
Programm anpassen in dem Du mit ADRESL und ADRESH arbeitest.
LG
Ingo
Hallo Ingo!!
Vielen vielen Dank für deine Unterstützung. Mein Programm funktioniert
jetzt wie gewollt und ohne Fehler. Bin sehr dankbar für dieses Forum und
hoffe, dass auch ich einmal helfen kann.
Nochmals vielen Dank!
MFG ANTON
Hallo Anton,
sehr gerne. nur ganz kurz eine Frage. Warum programmierst Du in
Assembler? Für den PIC16F877 gibt es doch auch ganz gute C-Compiler. Ich
verwende den CC5X. Für diese Anwendung würde auch die kostenlose Version
ausreichen. Der CCS oder der HITEC ist auch net schlecht.
Viele Grüße
Ingo
Hallo Ingo
Ich habe zwar schon einiges an Erfahrung mit C jedoch wollte ich
verstehen was mit den einzelnen Bits so passiert und auch mal in
Assembler hineinschnuppern. ;)
ok, das macht Sinn.
Der Umstieg von Assembler in C ist einfach. Aber von C zum Assembler ist
es ein wenig komplexer. Ist hal ein schmaller Assembler Syntax gegenüber
dem 8051.
Ja der Umstieg von C zu Assembler ist in der Tat schwirig bin fast
verzweifelt. Werde aber jetzt aus Neugier mal den C- Compiler testen um
zu sehen wie das so funktioniert.
Kann man da so programmieren wie in C++ nur das die Variablen Eingänge
bzw. Ausgänge sind?
Hier wäre ein Beispiel für den CC5X. Da gab es mal eine suer seite zu.
Gibts leider nicht mehr.
Ich kenn mich bei c++ nicht so gut aus. Es ist kein Full ANSI C aber der
taugt was.
Ich habe sehr viele Beispiele zu:
PIC16F877 in C (CC5X) und Assembler
PIC18F452 für den C18 von Microchip
PIC18F97J60 für den C18 von Microchip
Hallo Anton,
ja die benörigts Du. Du kannst die genau benötigte Zeit im Datenbalatt
berechnen. Bei 20 MHz verwende ich in der Regel 20 - 25 ms.
Im Prozzesor ist ein Multiplexer verbaut. den kannst Du ja über die
Config-Register steuern. Damit unter anderem ein prellen nicht vorkommt
wird wird dies zwingend benötigt.
LG
Ingo
Hallo Ingo
Kann ich die LED's auch ohne eines vorher definierten Wertes (z.B.:
MOVLW D'96') zum leuchten bringen? D.h.: Nur mit dem Signal das ich aus
dem ADC bekomme??
MFG ANTON
Hallo Anton,
vom Prinzip her schon. Die Pins müssen als Ausgang definiert sein.
Du musst dann nur folgendes tun...
MOVLW D'96' // Hier ladest Du den Dezimalwert 96 in den Akku
MOVWF PORTB // Nun musst du diesen Wert vom Akku an z.B. wie hier an
PORTB schrieben...
Grüße
Ingo
Anton P. schrieb:> Hallo Ingo>> Kann ich die LED's auch ohne eines vorher definierten Wertes (z.B.:> MOVLW D'96') zum leuchten bringen? D.h.: Nur mit dem Signal das ich aus> dem ADC bekomme??>> MFG ANTON
Dafür am besten den AD-Wandler so konfigurieren das das Ergebniss "Left
justified" ist (ADCON1.ADFM = 0).
Wenn dann der AD-Wandler fertig ist (ADCON0.GDO_DONE = 0) hast die die
höherwertigsten Bits vom 10-Bit-Ergebniss in ADRESH (damit bekommst du
auch den vollen ADC-Wertebereich angezeigt, nur eben mit 8 Bit
Auflösung). Ausgabe dann mit:
BANKSEL ADRESH
MOVF ADRESH,W
BANKSEL PORTB
MOVWF PORTB
Anton P. schrieb:> Wie wende ich das bei meinem Programm an da ich nirgends die Befehle> BANKSEL und dergleichen habe??
BANKSEL ist kein Controllerbefehl sondern eine Assembleranweisung
genaugenommen ein MACRO.
BANKSEL erstzt dir z.B. "bsf STATUS,RP0" etc.
Du brauchst nicht mehr im Datenblatt nachsehen in welcher Bank sich das
Register befindet.
Und es gibt PIC die haben mehr als 2 BÄNKE, also gibt es da auch ein RP0
u. RP1 und damit eine neue Fehlerquelle welche man mit BANKSEL vermeiden
kann.
Hallo Leute!!
Habe noch eine Frage:
Möchte noch auf eine andere Art den ADC programmieren.
Möchte je nach Spannungswert an der Spannungsquelle de LED's nach
einander leuchten lassen.
Nur habe ich das Problem: das mit meinem Programm(im Anhang) die LED's
willkürlich zu leuchten beginnen.
Hoffe ihr könnt mir noch einmal helfen!
MFG ANTON
Hallo Anton
Ich hoffe Dir ist klar wie das ADC-Ergebnis ausgegeben wird und wie
grunsätzliche vorzugehen ist.
Egal welche Vref Du im CVRCON CONTROL REGISTER ausgewählt hast, der ADC
gibt bei Uinput ADC = Vref, stets dieses Ergebnis aus.
ADRESH = b'00000011', ADRESL = b'11111111' = 1023 oder 0x 03FF
bei geringerer Spannung eben einen niedrigeren Wert als 1023. Das
Ergebnis ist binär, besteht also aus einer Folge von Einsern und Nullen.
Es ist dann Sache des Anwenders durch geeignete Umrechnung von
ADRESH,ADRESL den wirklichen Spannungswert zu berechnen.
Solange Du versuchst ADRESH oder ADRESL direkt, also bit für bit in den
PORTB zu kopieren:
; Wert nach PortB schreiben
movfw ADRESH ; obere 8 Bit auslesen
movwf PORTB ; obere 8-Bit nach PortB
erhältst Du stets die Binärzahl des ADC-Ergebnisses. Das kann durchaus
z.B. in ADRESH b'00000000' oder in ADRESL b'10101001' sein. In ADRESH
werden maximal nur die Bits 0 und 1 gesetzt!! Bit 2-7 bleiben
ungenutzt!!
Eine Balkenanzeige ist nur dann sinnvoll zu realisieren, wenn das
maximale Ergebnis des ADC = Maximal 1024 (0 - 1023) - eben wegen der 8
bits von PORTB - durch 8 geteilt wird und in 128er-Stufen (1024/8=128)
eine LED zu- bzw. eingeschaltet wird.
Im Prinzip brauchst Du nur ADRESH,ADRESL durch 127 (0-127) zu teilen.
Das kann z.B. durch einfache Subtraktion geschehen, wobei die Anzahl der
Subtraktionen ohne negatives Ergebnis letztlich die Anzahl der zu
schaltenden Bits ergibt (5 Subtraktionen - Balkenanzeige PORTB,Bit 0-4
EIN, Einzelanzeige nur PORTB,4 EIN).
Tip:
Schau Dir mal bei
[http://www.sprut.de/electronic/pic/programm/adclcd/adclcd.html] das
Programmbeispiel zur 16-Bit-Subtraktion an.
mfG Ottmar
Hallo!
Das Problem ist, dass ich es so nicht machen darf.
Mir wurde gesagt das ich am Ausgang das minderwertigste Bit definieren
muss und dann aufsteigend nur wie soll das gehen ohne den LEDs
Dezimalzahlen zuzuordnen??
BITTE um Hilfe
MFG ANTON
Hallo Anton,
habe ich Dich jetzt richtig verstanden?
Du willst nur das Low-Byte des ADC-Ergebnisses "ADRESL" für die Balken-
bzw. Einzelanzeige verwenden? Ja nun, das ist aber recht simpel zu
lösen!
Hier ein Beispiel zur Balkenanzeige, die Verwirklichung einer
Einzelanzeige wird Dir da bestimmt leicht fallen.
Prinzip:
Du frägst einfach beginnend mit dem MSB die Bits 7 - 0 von ADRESL ab und
setzt dann entsprechend am LED-PORT die Bits absteigend vom höchsten
gesetzten Bit.
Vergiss nicht ein genügend langes Delay zu verwenden um den Balken nicht
zu sehr zappeln zu lassen. Es ist klar, dass die Anzeige nicht dem real
gemessenen Spannungswert folgt sondern in Sprüngen von 2^0 - 2^7.
Soll es ein Einzelanzeige sein - die Lösung fällt Dir bestimmt rasch
ein.
Schau Dir mal dazu beiliegenden Codeschnipsel an. Das geht bestimmt noch
eleganter, aber so ist es wohl am verständlichsten.
mfG Ottmar
Wenn tatsächlich eine Dekadische Anzeige verlangt ist und die
Balkenlänge ein binäres Vielfaches ist (also 2,4,8,16... Segmente), dann
ist das auch keine Hexerei.
In "var_adc" steht der Wert aus der ADC-Wandlung, in "var_balken" wird
die Anzeige gebastelt.
Anzeigeintervalle gehen von 0...31,32....64 usw., also zuerst den
ADC-Wert durch 32 dividieren:
1
rrf var_adc,F
2
rrf var_adc,F
3
rrf var_adc,F
4
rrf var_adc,F
5
rrf var_adc,F
dann die 3 uns interessierenden Bit isolieren
1
movlw b'00000111'
2
andwf var_adc,W
3
movwf counter
ergibt eine Wert von 0...7, wir haben aber 8 Segmente also:
1
incf counter,F
und alle Segmente löschen
1
clrf var_balken
jetzt von RECHTS solange "1" reinschieben bis Zähler auf 0
1
loop
2
rlf var_balken,F ;bereits gesetze Segmente
3
bsf var_balken,0 ;PLUS das äusserts RECHTE
4
decfsz counter,F
5
goto loop
fertig und anzeigen
1
movf var_balken,W
2
movwf PORTB
3
......
Zumindest am Simulator läuft es wie es soll....;-)
Wenn man natürlich eine Anzeige mit z.B. 17 Segementen möchte, dann wird
das etwas aufwändiger.....
Hallo Leute
Vielen Dank für eure Unterstützung!
Habe jetzt noch eine letze Frage:
Möchte bei der SChaltung (im Anhang) bei den rechten 8 LEDS die
niederwertigste (untersten) Bits ausgeben ausgeben und bei den rechten
8 LEDs die höherwertigen Bits(obersten) ausgeben.
Das Board ist als Word- Dokument angehängt,da mein pdf creator leider
nicht mehr funktioniert.
Das Problem ist jetzt, das er links und rechts das gleiche ausgibt.
Hoffe ihr könnt mir helfen!
MFG ANTON
Dann solltest du das machen was dir hier schon geraten wurde: konsequent
BANKSEL verwenden - denn ADRESH und ADRESL liegen in unterschiedlichen
Speicherbänken!!!
Zuerst Zugriff auf ADCON0, dann liest du ADRESL. Dummerweise liegt in
der Bank von ADCON0 auf der Adresse ADRESH - also gibts du ADRESH auf
PortB aus. Und dann - diesmal korrekterweise - ADRESH nochmals, aber auf
PortD!
Hallo!
Ich bin schon fast am verzweifeln und bekomme mein Programm nicht zum
laufen! :(
Ich weis, dass dies keine Webside ist um Aufgaben erfüllen zu lassen,
doch ich bitte darum das mir vielleicht jemand dieses Programm etwas
überarbeitet. BITTE
MFG ANTON
Hallo Anton,
Du weißt dass die Register beim PIC auf verschiedene Speicherbänke
verteilt sind. Nur wenn Du dem Assembler mitteilst wo diese Register zu
finden sind, können die entsprechenden Codebefehle ausgeführt werden.
Wird z.B. TRISA "beschrieben" ohne dass zur Bank 1 umgeschaltet wird,
geht dieser Befehl ins Leere. Dies gilt auch für ADRESH bzw. ADRESL,
jedes dieser beiden Register befindet sich in einer anderen Bank.
Z.B. befindet sich beim PIC16F877 PORTA in Bank 0. TRISA in Bank 1.
Diese erreichst Du so:
bcf STATUS, RP0 ;umschalten auf Speicherbank 0
bsf STATUS, RP1 ; "
clrf PORTA ;Wert um RA7:0 auf logisch 0 zu setzen
jetzt zum Datenrichtungsregister TRISA, welches sich in Bank 1 befindet
BSF STATUS, RP0 ;umschalten zu Bank (Bit RP1 bleibt unverändert)
movlw 0xFF ;Wert um RA7:0 als Eingänge zu schalten
movwf TRISA ;Wert in Datenrichtungsregister kopieren
bcf STATUS, RP0 ; und nun wieder zurück zu Bank0
BANKSEL
Der Assembler kennt sogenannte "Preprozessorbefehle" wie z.B. "banksel".
Schau dazu mal hier nach:
[http://www.sprut.de/electronic/pic/assemble/pseudo.html] sobald ein
solcher "Pseudo-Befehl" im Assemblercode auftaucht, wird der
entsprechende Assemblercode zum Bankwechsel ohne Dein Zutun iin das
Programm (nicht in das ASM-File!) eingefügt:
"banksel PORTA"
Nach "RUN" in MPLAB-Sim, bzw. "MAKE" oder "Build all" im Menü "Projekt"
kannst Du im Menü "View - Programm-Memory" aber sehen, dass MPLAB
selbstständig diesen Code anstelle von "banksel PORTA" eingetragen hat:
BCF 0x3, 0x5 ;=BCF Registeradresse, Bitnummer -> bcf STATUS, RP0
BCF 0x3, 0x6 ;= " " " -> bcf STATUS, RP1
CLRF 0x5 ;=CLRF Registeradresse -> CLRF PORTA
Wie Du siehst ist es viel einfach einfach "banksel <Registerlabel>" zu
schreiben, als zwei Codezeilen zu schreiben. Im letzteren Fall musst Du
genau wissen in welcher Bank sich das Register befindet, mit "banksel"
aber nicht, weil das ja Dein Assemblerprogramm für Dich weiß.
Natürlich ist es Blödsinn einfach vor jedes Register "banksel" zu
verwenden. Dazu schaut man immer wieder im Datenblatt im Abschnitt
"Memory Organization", Tabelle "PIC16F876A/877A REGISTER FILE MAP" nach.
Dort sind die einzelnen Bänke mit den darin enthaltenen Register
übersichtlich aufgeführt.
So lernt man die Hardware des PIC kennen und das Programmieren wird
zusehends leichter und auf jeden Fall machst Du mit "banksel" keinen
Fehler bei der Auswahl der Bank für das/die nachfolgend verwendeten
Register.
Ich habe mal Dein Balkenprogramm kurz überdacht und dazu meine Version
geschrieben und nur "banksel" zum Bankwechsel vewendet. Du musst aber
daran denken, dass mit den unteren 8 Bit ADRESL lediglich der Bereich 0
- ca. 1,246Volt dargestellt werden kann. Darüber kommen Bit 0 und 1 von
ADRESH ins Spiel.
Schau es Dir mal an, vielleicht hilft Dir das weiter.
Noch ein Tip: Wenn Du ein Programm schreibst, nimm das Datenblatt und
gehe dort Schritt für Schritt durch die Beschreibung der Register. Spare
NIEMALS mit Kommentaren zu JEDER Codezeile. Es ist nicht sinnvoll so zu
kommentieren:
bsf PORTB,RB1 ;bit 1 Setze RB1 = 1
besser:
;bit1=1 LED an RB1 einschalten
also keinen Befehlscode erläutern, sonder das was der Befehlscode
bewirkt!
Na ja, kommt Zeit kommt Rat!
noch viel Spass mit den PICs!
mfG Ottmar
Hallo Ottmar!
Vielen Dank für dein Programm und die ausfühliche Beschreibung!
Kann ich das bei deinem Programm so verstehen, das wenn man auf 5 Volt
ist alle LEDs leuchtn und wenn man die Spannung auf 4,35Volt veringert
die niederwertigsten Bits (LEDS) aufhören zu leuchten?? Und warum
leuchten bei einem Wert von 3.75Volt und 0 Volt wieder alle LEDS???
Kann ich mir das jetzt so vorstellen, dass einfach der Wert vom ADC
ausgegeben wird ohne jede Ordnung und die LEDs die als erstes nicht
leuchten die niederwertigsten Bits(LEDS) sind??
MFG ANTON
So wie ich das sehe ist da ein kleiner Bug in dem Programm:
Definiert wird mit ADCON0.ADFM = 1 eine Rechtsbündige Ausgabe, also
ADRESH:ADRESL = xxxxxx11 11111111 (Maximalwert).
Bei der ADC-Wandlung wird ADRESH in tempADC1 und ADRESL in TempADC0
gespeichert.
Der Erzeugung des BALKEN wird aber tempADC0 verwendet! also wiederholt
sich der Wertbereich von 00000000....11111111 insgesamt 4x.
Richtig wäre:
ADCON0.ADFM = 0 -> Linksbündige Ausgabe, also
ADRESH:ADRESL = 11111111 11xxxxxx (Maximalwert).
Und die in der Routine "LED_Bargraph" wird tempADC1 zur Erzeugung des
Balken verwendet.
Natürlich sind bei 3,75V alle LED wieder aus: 5V /4 = 1,25V (5V - 1,25V
= 3,75V) und das ist genau der Wert der mit Rechtsbündiger Ausgabe mit 8
Bit in ADRESL darstellbar ist....
Hallo Anton,
Chris B. hat natürlich recht. Bei der linksbündigen Ausgabe werden die
höherwertigen Bits berücksichtigt und die letzten Bits (0 und 1) fallen
unter den Tisch.
Ich habe das übersehen (könnte ja auch sagen: wollte wissen ob Du es
bemerkst :-). In meinem Programm wird tatsächlich über 1,246V nur noch
Unsinn im Balken angezeigt, während bei der linksbündigen Ausgabe ab 5V
abwärts bis auf 1,251 als letzter Balken angezeigt wird. Ein kleiner
Unterschied aber mit spürbarer Wirkung!
Zum ADC: Der ADC kann die Vref, in diesem Fall die Betriebsspannung des
PIC in 1023 einzelne Stufen auflösen. Im Abschnitt "Init" wurde Vdd
(+5V) als +Referenzspannung und Vdd (GND, Masse, OV) als Vss- gewählt.
Dies Werte stehen durch die Konfiguration von ADCON0/ADCON1 intern zur
Verfügung.
Die Auflösung des ADC beträgt 10bit, also dezimal 1023. Somit ist die
geringste messbare Spannung am ADCD 5000mV/1023 = 4,8875.... mV.
ADRESL hat 8 Bit, kann also von den 1023 Steps lediglich 256 (0 - 255)
darstellen. ADRESH verfügt über lediglich 2 Bits, aber diese sind
höherwertig als die Bits in ADRESL.
Hier die RECHTSbündige Ausgabe:
ADC-Wert
255 ADRESH b'00000000', ADRESL = b'11111111'
+ 1
256 ADRESH b'00000001', ADRESL = b'00000000'
+255
511 ADRESH b'00000001', ADRESL = b'11111111'
+1
512 ADRESH b'00000010', ADRESL = b'00000000'
+255
767 ADRESH b'00000010', ADRESL = b'11111111'
+ 1
768 ADRESH b'00000011', ADRESL = b'00000000'
+255
1023 ADRESH b'00000011', ADRESL = b'11111111'
LINKSbündig formatiert sieht das Ergebnis aber so aus:
1023 ADRESH b'11111111', ADRESL = b'11000000'
Im diesem Fall orientiert sich die Balkenanzeige voll und ganz an ADRESH
und zeigt lediglich die letzten Bits 0 und 1 von ADRESL (rechtsbündig)
nicht an. Somit umfasst Deine Balkenanzeige in diesem Fall
ADRESH b'10000000' = 256 * 4.8875mV = 1251mv
bis
ADRESH b'11111111' = 1023 * 4.8875mV = 5000mV
Also ist es günstiger die Variable tmpADC1 (Kopie von ADRESH) zur
Erzeugung Deiner Balkenanzeige zu verwenden.
Wenn Du die Balkenanzeige drauf hast, wird es -so meine ich- Zeit, dass
Du dran gehst die Spannung als Volt oder mV im LCD auszugeben!
mfG Ottmar
Ottmar K. schrieb:> Somit umfasst Deine Balkenanzeige in diesem Fall>> ADRESH b'10000000' = 256 * 4.8875mV = 1251mv> bis> ADRESH b'11111111' = 1023 * 4.8875mV = 5000mV
Da habe ich einen Krampf dargestellt (typischer Schnellschuss)! Am
Ergebnis des ADC hat sich natürlich trotz der linksbündigen Ausgabe
nichts geändert! Die Balkenanzeige zeigt daher nur im Bereich ab ca.
19,5mV - 2502mV eine Veränderung der ADC-Spannung an.
Für die hier besprochene Balkenanzeige ist ja nur maßgeblich, dass das
höchste Bit gesetzt ist, die niedrigeren Bits fallen bei dieser
Auswertung unter den Tisch.
Die niedrigste angezeigte Spannung ist (Segment wechselt von Aus<->Ein):
ADRESH = 00000000,ADRESL = 00000100 = dez. 4, 4x(5V/1023)=0,0195V
linksbündig:
ADRESH = 00000100,ADRESL = 00000000
Spannungsänderungen unter diesem Wert werden nicht angezeigt (Balken
vollständig aus).
Die höchste angezeigte Spannung ist:
ADRESH = 00000010,ADRESL = 00000000 = dez. 512, 512x(5V/1023)=2,502V.
linksbündig:
ADRESH = 10000000,ADRESL = 00000000
Spannungsänderungen über diesem Wert werden nicht angezeigt (Balken
vollständig ein)
mfG Ottmar
Hallo Leute!
Es tut mir leid aber ich verstehe den Fehler leider nicht was ihr da
meint mit der linksbündigen und rechtsbündigen Ausgabe.
Gibt es nicht eine einfacher Variante des ADC die Leds zum leuchten zu
bringen ohne Balkenanzeige oder der gleichen nur die Ausgabe des ADC mit
Beachtung der niederwertigsten Bits--> bei 5 Volt leuchten alle LEDs und
ab 4,5V oder so hören die niederwertigsten /höchstwertigsten Bits (LEDs)
auf zum leuchten??
Ich bitte ein letztes Mal um Hilfe und entschuldige mich das ich solche
Fragen stelle, die für euch wahrscheinlich als "dumm" gelten.
MFG ANTON
Wurde eigentlich genau erklärt was man rechtsbündig / linksbündig
versteht, aber ganz einfach:
1.Ersetze im Programm von Ottmar K. die Zeile
...bsf ADCON1,ADFM ;b7=1 A/D-Ergebnis rechts ausgerichtet...
durch
...bcf ADCON1,ADFM ;b7=0 A/D-Ergebnis links ausgerichtet...
2. Ersetze nach dem label LED_loop die zeile mit
....rlf tmpADC0,f ;ADC-Wert linksschieben...
durch
....rlf tmpADC1,f ;ADC-Wert linksschieben
Dann sollte das Program genau das tun was es soll!
(einige Kommentare bei der ADC-Wandlung selbst passen natürlich nicht
mehr ganz, aber das hat ja mit der Funktionsfähigkeit nix zu tun).
In Assembler geht es eben nur in kleinsten Schritten und offen gesagt
macht es keine Sinn hier herumzuoptimieren und irgendeine x-beliebige
andere Anzeige zu erzeugen. Du solltest dieses Programm VERSTEHEN, dann
kannst du jederzeit andere Anzeigevarianten "basteln".
@Chris
OK, LCD muss ja noch nicht sein, aber ich hätte es vorgezogen vor dem
ADC die LCD-Ausgabe kennenzulernen.
@ Anton
Anton P. schrieb:> Es tut mir leid aber ich verstehe den Fehler leider nicht was ihr da> meint mit der linksbündigen und rechtsbündigen Ausgabe.
Nochmals rechts-/linksbündig
| ADRESH, ADRESL |
|00000011,11111111|RECHTSbündig
|11111111,11000000|LINKSbündig
Ich hatte doch mein funktionierendes Programm
[Beitrag "Re: Analog Digital Converter kleines Problem (PIC)"]
als Anlage beigefügt. Es mag nicht der Stern am Programmhimmel sein,
aber es funktioniert. Das solltest Du daher auch ausprobieren, wenn
nicht in den Chip gebrannt, dann doch zumindest mit dem Simulator
MPLAB-SIM. Dann wirst Du auch sehen, was die links/rechtsbündige Ausgabe
in ADRESH, ADRESL bewirkt.
Gehe den Code Zeile für Zeile, anhand des Kommentars UND dem Datenblatt
durch, damit Du die Zusammenhänge verstehen kannst.
Chris hat klar mitgeteilt was zu ändern ist um die höherwertigen Bits
auszugeben, wodurch ein erweiterter Spannungsbereich zwischen ca. 5 und
1,25V angezeigt werden kann.
Falls Du mit MPLAB-SIM nicht klarkommen solltest, stelle dazu Deine
Fragen, hier ein paar Links dazu:
{http://www.fernando-heitor.de/index.php/downloads/Dokumente/MPLAB-Tutorial/]
(MPLAB-Tutorial in deutsch herunterladen)
[http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2123¶m=en022520]
(englisch)
mfG Ottmar
Hallo!
Ich möchte nur den Wert des ADC auf die LEDs übertragen ohne
Balkenanzeige oder irgendsowas.
Könnt ihr mir noch einmal helfen habe morgen meine Arbeit darüber und
bekomme es nicht in den Griff!!
BITTE !!!
MFG ANTON
Hallo Anton,
ich versteh Dich nicht! Du hast einen funktionierenden Code erhalten.
Wenn PORTC zur Ausgabe verwendet werden soll, tauscht Du eben PORTB
gegen PORTC im Code. Es ist doch egal ob man die LEDs am Ausgang als
Balkenanzeige oder "Einzel-LEDs" oder sonst wie bezeichnet.
Mehr als bisher gibt es zu diesem Thema ergänzend nichts mehr zu sagen.
mfG Ottmar