PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : kapazitätzmessgerät, 2*27 Anzeige



Xaver
02.01.2006, 15:05
ich arbeite gerade an einem Kapazitätsmessgerät mit eigener kalibrierung. Es funktioniert auch soweit ganz gut, es hat nur einen kleinen schönheitsfehler, den ich nicht finde.

Ich verwende ein 4 * 27 Zeiliges Display von pollin und einen Mega 8.

Beim Start steht, wie es auch soll :
" Das kapazitaetsmessgeraet "
" ***** MEGA 8 ***** "
" (c) Boris Eskin "
" (c) Olaf Petersen "

Dann soll die Zweite Zeile verschwinden und an der Stelle die gemessenen Werte anzeigen. Doch leider sind sie immer in der unteren Displayhälfte.

" Das kapazitaetsmessgeraet "
" ***** MEGA 8 ***** " <-- hier soll es hin
" (c) Boris Eskin "
" 123.00 nF " <-- hier ist es

nun der Code:


$regfile = "m8def.dat" 'Atmel MEGA 8 controller
$crystal = 16000000 'Quarz auf 16MHz


'-- Portbelegung -------------------------------------------------------------
Ddrd.3 = 0 'PD3/INT0 als Eingang deklarieren
Portd.3 = 1 'Pullup Widerstand aktiveren
Taste Alias Pind.3 'Taste zu Kalibrierung

Ddrd.6 = 1 'PD6/INT0 als Ausgang deklarieren
Relais Alias Portd.6 'Ralais zu Kalibrierung
Relais = 0 'Relais ausschalten

'27 x 4 LCD Display angeschlossen
'Festlegen der Verwendeten Ports
'Wenn es nur einen Kontroler gibt das sollte Port E2 der Gleiche wie E sein
Ddrc = &B00111111
Portc.1 = 0 'R/W auf masse
Ddrd.0 = 1
Ddrd.1 = 1

Dim ___lcdno As Bit 'zwischen den LCD kontroler wechseln
Config Lcdpin = Pin , E = Portc.2 , E2 = Portc.3 , Rs = Portc.0 , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portd.1 , Db7 = Portd.0
Config Lcd = 40 * 4


'--Variablen ------------------------------------------------------------------
Dim Counter_ueberlauf As Integer 'anzahl der Überlaufe von timer 1
Dim Timerprescale As Long 'um timer auf 1 sec zu stellen

Dim Frequenz As Single 'momentahne Frequenz
Dim Freq1 As Single 'leerlauf
Dim Freq2 As Single 'mit Relais
Dim Freqx As Single 'kapazität

Dim C1 As Single 'aus der kalibrierung ergebener Wert
Dim Cx As Single 'gemessene kapazität
Dim L1 As Single 'aus der Kalibrierung

Dim Tmp As Single 'variable für Formeln und rechnungen
Dim Tmp2 As Single 'variable für Formeln und rechnungen

Dim Kalibrierung As Bit 'kalibrierung aktiv
Dim K_i As Bit 'so für die kalibrierung
Dim K_r As Bit

Dim S As String * 27 ' String der Angezeigt wird


'--Interrupts------------------------------------------------------------------
On Timer1 Oncounter 'Interrupt anzahl der Impulse
On Timer0 Ontimer 'Interrupt eine Sekunde ermitteln
On Int1 Ontaste 'Interrupt Taste Kalibrierung

Config Timer0 = Timer , Prescale = 1 ' eine Sekunde ermitteln
Const Timervorgabe = 62500 ' 62500 * 265 ergibt 16Mhz
Config Timer1 = Counter , Edge = Rising , Noise Cancel = 1 'Timer als Timer Festlegen

Enable Timer0 'Timer0 Aktivieren
Enable Timer1 'Timer1 aktivieren
Enable Int1 'Taste aktivieren




'--Hauptprogramm--------------------------------------------------------------


Stop Timer1 'erstmal stop damit nicht schon
Stop Timer0 'jetzt interrupts kommen

___lcdno = 0 'Ober Displayhälfte initialisieren, wenn
Initlcd 'das Display 2 Lcd-Controller besitzt
Cursor Off
Cls
___lcdno = 1 'untere Displayhälfte initialisieren,
Initlcd 'das Display 2 LCD-Controller besitzt
Cursor Off
Cls

___lcdno = 0 ' auf obere hälfte den Titel schreiben
Home
Locate 1 , 2
Lcd "Das Kapatitaetsmessgeraet"
Locate 2 , 5
Lcd "***** MEGA 8 *****"

___lcdno = 1 ' auf untere hälfte die Namen
Home
Locate 1 , 5
Lcd "(c) Boris Eskin"
Locate 2 , 5
Lcd "(c) Olaf Petersen"

Wait 2


'-- Alle werte auf Startwerte setzen ------------------------------------------
___lcdno = 0 'Obere displayhälfte auswählen
Home

Counter_ueberlauf = 0 'startwert festlegen
Timerprescale = 0 'startwert festlegen
Freq1 = 0 'leerlauffrequenz
Freq2 = 0
Freqx = 0
C1 = 0 '~700 nF
Cx = 0
Kalibrierung = 1 'mit der Kalibrierung beginnen

Start Timer1
Start Timer0
Enable Interrupts 'Allgemein Interrupts erlauben



'--jetzt kann es losgehen -----------------------------------------------------
Do

If Kalibrierung = 0 Then
Tmp = Freq1 * Freq1 'Berechnung der Kapazität
Tmp2 = Frequenz * Frequenz
Tmp = Tmp / Tmp2
Tmp = Tmp - 1
Cx = Tmp * C1 'in nF
S = Fusing(cx , "#.####") 'unbekannte Kapazität anzeigen
S = S + " nF"
Else
If K_i = 0 Then 'warten auf den zweiten messwert
K_i = 1
S = "Kalibrierung "
Else
If K_r = 0 Then 'ermitteln der leerlauffrequenz
Freq1 = Frequenz
K_r = 1
Relais = 1
S = "Relais an"
Else
Freq2 = Frequenz 'kalibrierfrequenz
Tmp = Freq2 * Freq2
Tmp2 = Freq1 * Freq1
Tmp2 = Tmp2 - Tmp
Tmp = Tmp / Tmp2
C1 = Tmp * 0.1 'ermittelter wert für C1

Relais = 0 'relais aus
Kalibrierung = 0 'Kalibrierung beenden
Tmp = C1 * 1000
S = Fusing(tmp , "#.##") 'ermittelten wert anzeigen
S = S + " pF "
End If
End If
End If

' anzeige auf dem LCD
___lcdno = 0 'obere Displayhälfte
Locate 2 , 0
Lcd " " 'LCD Zeile löschen
Locate 2 , 8
Lcd S 'Ausgabe am LCD

Wait 1

Loop
End


'-- Interrupthändler für Überlauf an Timer 1 ----------------------------------
Oncounter:
Incr Counter_ueberlauf 'Überlaufe Zählen
Return

'-- Interrupthändler für Überlauf an Timer 0 ----------------------------------
Ontimer:
Incr Timerprescale 'Überlaufzähler um eins erhöhen#

If Timerprescale = Timervorgabe Then 'nach einer Sekunde
Timer0 = Timervorgabe
Frequenz = Counter_ueberlauf * 65536
Frequenz = Timer1 + Frequenz
Frequenz = Frequenz / 1000 'in kHz
Timerprescale = 0
Counter_ueberlauf = 0
Timer1 = 0
End If
Return

'-- Interrupthändler für Taste Kalibrierung -----------------------------------
Ontaste:
Kalibrierung = 1
K_i = 0
K_r = 0
Return


An irgeneiner stelle muss er auf die idee kommen die untere hälfte zu nehmen.

Ratber
02.01.2006, 16:03
Ja das Disp. vomn Pollin sorgt immernoch für verwirrung.


Wenn es nur einen Kontroler gibt das sollte Port E2 der Gleiche wie E sein

Nein ,es sind hier wirklich Zwei.
2x27 Zewichen in den oberen Zeilen und 2x27 unten.

Wenn du beide Enableleitungen zusammenfasst dann behandelst du das Ganze wie zwei parallelgeschaltete Displays.
Damit sind die Doppelten ausgaben erklärt.

Es gibt unterschiedliche Anpassungen für Bascom also Google mal nach "4x27 Pollin Bascom" oder "Wintek 4x27 Bascom" da findet sich einiges.

Aber ich denke mal das dir die "LCD4.Lib" auch schon helfen wird denn die
unterstützt einen zweiten Enableeingang.
Aber vorsicht,beio dieser Lib kann man die Anschlüsse nicht mehr wild am Controller verteilen.

Torsten_G
02.01.2006, 19:40
Hallo Xaver,

ich verwende auch das 4x27-Wintek-Display von Pollin. Funktioniert eigentlich problemlos, ich bin sehr zufrieden.

Ich betreibe es mit der "lcd4e2.lbx", wie Ratber schon schrieb, sind dann die Belegungen allerdings festgelegt, es wird der komplette Port B (außer B.1) verwendet.

Du findest die genaue Beschaltung der Port´s in der Bascom-Hilfe.

Der Betrieb parallel zum ISP-Adapter ist problemlos. Zwar zeigt das Display ein paar wirre Zeichen während des Flashens, aber sonst passiert nix.

Das nachfolgende Programm habe ich geschrieben als Testprogramm (Anzeige Portstatus) für mein selbstgebautes Experimentierboard (Mega 8, I2C-Porterweiterung), es sollte aber auch bei Dir funktionieren.

Wenn der Bus nicht aktiv ist, wird der I2C-Status automatisch auf "Fault" gesetzt, der Rest vom Programm läuft trotzdem.

Vielleicht hilft´s Dir ja weiter, viele Grüße

Torsten



'*****************************************
' Test Program for Development Board
' Designed for Atmel AVR Mega 8
' Bascom Version 1.11.7.4
' 24.07.2005 T. Gietenbruch
'
' Hardware Configuration:
' -> LCD-Display at Port B
' -> Switches and LED´s at Port C
' -> Switches and LED´s at Port D
' -> I2C-Bus: SDA at PC4 / SCL at PC5
' -> PCF8574P 8-Bit-Extension at adress 64
'
'******************************************

'==========================================
' System Configurations
'==========================================

'Definition for Mega 8
$regfile "m8def.dat"

$crystal = 8000000
'$baud = 9600

'Library for I2C-Bus
$lib "i2c_twi.lbx"

'Library for 2-Processor LCD-Display
$lib "Lcd4e2.lbx"



'Configuration of LCD-Display
Config Lcd = 20 * 4
'Port Configurations
Config Portc = Input
Config Portd = Output


'==========================================
' Declarations
'==========================================

'Display part selection - variable name is fixed in library!
Dim ___lcde As Byte

'I2C-Bus variables
Dim I2c_ok As Bit
Dim I2c_state As String * 10
Dim Portpcf_1_out As Byte
Dim Portpcf_1_in As Byte

'Program variables
Dim Count As Integer
Dim T_count As Integer
Dim Led_no As Byte


'==========================================
' Initialising
'==========================================

'I2C-Bus write adress for PCF8574P - selectable with jumpers
Const Pcf1w_adr = 64

'Read adress is always write adress + 1
Const Pcf1r_adr = Pcf1w_adr + 1

'Initial values
Portpcf_1_in = &B11111111
Portpcf_1_out = &B10101010
Portd = &B11111111

I2c_ok = 0
Count = 0
Led_no = 0


'==========================================
' Main Program: Building LCD Display Mask
'==========================================

'Selection of upper LCD segment
___lcde = 0

'All following LCD commands are for the upper two lines

Cls
'Text for 1st line
Locate 1 , 1
Lcd "**** ATMEL RISC MEGA 8 ****"

'Text for 2nd line
Locate 2 , 1
Lcd "**** DEVELOPMENT BOARD ****"

'Switching the cursor off
Cursor Off

'Selection of lower LCD segment
___lcde = 1

'All following LCD commands are for the lower two lines

Cls

'Text for 3rd line
Locate 1 , 1
Lcd " I2C-Bus:"

'Text for 4th line
Locate 2 , 1
Lcd " PC: PD:"

'Switching the cursor off
Cursor Off

'==========================================
' Main Program: Initializing I2C-Bus
'==========================================

'Initializing
I2cinit

'Print state "Search"
___lcde = 1
Locate 1 , 12
Lcd "Search..."

'Check if I2C-Bus is OK
While Count < 20 And I2c_ok = 0
Incr Count
I2cstart
I2cwbyte Pcf1w_adr
If Err = 1 Then
I2c_state = "Fault"
I2cstop
Else
I2c_ok = 1
I2c_state = "OK"
I2cwbyte Pcf1w_adr
I2cwbyte Portpcf_1_out
End If

Wend

'Print final state of I2C-Bus
Locate 1 , 12
Lcd " "
Locate 1 , 12
Lcd I2c_state

'==========================================
' Main Program: Monitoring Port States
'==========================================
Do

'Read and print PIN state of PCF8574P
If I2c_ok = 1 Then
If T_count > 30 Then
Toggle Portpcf_1_out
I2cstart
I2cwbyte Pcf1w_adr
I2cwbyte Portpcf_1_out
T_count = 0
End If
I2cstart
I2cwbyte Pcf1r_adr
I2crbyte Portpcf_1_in , Ack
'I2cstop

Locate 1 , 18
Lcd Bin(portpcf_1_in)

End If

If Count > 5 Then
Toggle Portd.led_no
Count = 0
Incr Led_no
If Led_no > 7 Then
Led_no = 0
End If
End If

'Print PIN state of Port C
Locate 2 , 6
Lcd Bin(pinc)

'Print PIN state of Port D
Locate 2 , 18
Lcd Bin(pind)

'Toggle Live Bit
Incr Count
Incr T_count

'End of main program endless loop
Loop

Xaver
02.01.2006, 19:52
nene,
das Display funktioniert einwandfrei. Alle vier Zeilen können unabhängig angestuert werden. die Ports hab ich mit Config Lcdpin alle unterschiedlich angeschlossen. E1 und E2 haben unterschiedliche anschlüße.
Mit ___lcdno wechsel ich schwischen den Kontrolern.
Das ist alles schon so in Bascom drin, da hab ich nix mehr an den lib's verändert.

bevor die "große" do-scheilfe anfängt habe ich ___lcdno = 0 gesetzt , also obere Display hälfte aktiv. Wenn ich direkt darunter mit LCD etwas hineinschreibe, steht es auch auf der Oberen hälfte.
Nur "Kalibrierung", "Ralais on" und der eigentliche Messwert wollen einfach nicht auf die obere hälfte.

Torsten_G
02.01.2006, 20:06
Ahhh... jetzt, ja... ok, etwas am Thema vorbeigelesen! :oops:

Stimmen die Fusebits und Crystal überein? Also eingestellt auf 16Mhz?

Das Display mag´s nicht, wenn da Unterschiede sind.

Wenn es dann immer noch nicht funzt, dann versuch´s doch mal auf 8Mhz (interner Quarz), ob es dann klappt.

Da hatte ich auch schon mal Probleme mit, dass bei 16 Mhz das Display etwas eigene Wege ging.

Viele Grüße

Torsten

Edit: Und schau doch mal, was passiert, wenn Du vor der LCD-Ausgabe die Interrupts abschaltest...

avrflo
02.01.2006, 21:50
Hallo Xaver ,
ich würd ma probieren, das ganze Display mit cls zu löschen, anstatt die Zeile mit Leerstellen zu überschreiben, vllt funktioniert es dann! Und noch ein Tipp, ich hab mal gehört dass Locate y,x mehr Speicher und Rechenzeit verbraucht als einfach upperline und Lowerline zu schreiben.

Gruß
Florian

Xaver
02.01.2006, 22:41
Vielen Dank für die Hilfe. Hab das mal mit den Interrupts und dem löschen versucht, hat aber nix gebracht.

Habe den Fehler... naja also die Stelle gefunden an der das Programm einfach auf die untere Hälfte springt. Ich bin den Code Stück für Stück durchgegangen und habe ausprobiert an welcher stelle der fehler auftritt.
dies ist die Stelle:


...
'-- Alle werte auf Startwerte setzen ------------------------------------------
...
___lcdno = 0
Home
cls
Lcd "123456"
Wait 1

Kalibrierung = 1 'mit der Kalibrierung beginnen

___lcdno = 0
Home
cls
Lcd "zZzZzZzZzZzZzZzZ"
Wait 1
...


12345 wird in der erten Zeile dargestellt und zZzZzZzZz inder der dritten, der rest ist leer. Beides soll aber in der ersten stehen.
Kalibrierung ist als Bit Variable dimensioniert und soll mir zeigt ob gerade Kalibriert wird oder nicht. wenn ich die Zeile auskommentiere funktioniert es auch richtig.
Ich kann mir den Fehler nicht erklären.

edit:
dabei ist es egal an welcher stelle ich im Code Kalibrierung = 1 gesetzt wird, sobald diese stelle ausgeführt wird, lässt sich das Display nicht mehr richtig ansteuern.

müssen ist als Bit deklarierte variablen auf true oder so was setzten, oder gibt es dabei tücken die man beachten muss?

Hab ihr eine Idee?? vielleicht ein Jahr 2006 bug ;-)[/i]

Torsten_G
03.01.2006, 00:43
Öhh... Sachen gibt´s... :shock:

Nee, Du, Deine Zuweisung ist schon ok so...

Das kann ich mir nur so erklären, dass die Zuweisung von "Kalibrierung" irgendwie über die Speicheradresse von "___lcdno" drüberbügelt!

Arbeitet man mit der Library, muß die Steuervariable für die obere/untere Display-Hälfte als Byte deklariert werden: "Dim ___lcde As Byte"

Du deklarierst "___lcdno" nur als Bit. Könnte das der Fehler sein?

Mir fehlt da jetzt die Erfahrung mit den frei konfigurierten Displays.
Sag doch mal bitte, auf welchem Bascom-Beispiel Du aufgebaut hast (wenn Du hast...).

Und was passiert denn, wenn Du den Spieß mal rumdrehst -> ___lcdno=1 und Kalibrierung=0 ?

Viele Grüße

Torsten

Marco78
03.01.2006, 05:20
vielleicht ein Jahr 2006 bug
Oder ein Bascom-Bug?

Wenn du nur ein Bit verwendest, wird ein Byte im Speicher belegt. Acht Bit belegen auch ein Byte. Bascom fasst acht Bits zu einem Byte zusammen. (Nachzlesen irgendwo in der Mailinglist auf Grote.net)
Es kann ja sein, das irgendwo im Assemblercode später das Bit im Byte an der falschen Stelle geändert wird?!
Änder mal die Reihenfolge der Dimensionierung der Bits, mal schauen was dann passiert. Ob dann ein anderes Bit faslch gesetzt wird.

Sollte es so sein (und selbst wenn nicht) kannst du für E2 ja ein Byte nehmen. Der Mega8 hat ja genug Speicher.

Xaver
03.01.2006, 09:26
Juhu!!

Das Dim ___lcdno as Bit war der Bösewicht mit Dim as Byte funktioniert wieder alles. Warscheinlich hat Kalibrieren auch mit auf dem Byte gesessen und die LCD routine durcheinander gebracht.

Vielen Danke

Marco78
03.01.2006, 20:33
Warscheinlich hat Kalibrieren auch mit auf dem Byte gesessen
Da du nur 4 Bits hast ist das sehr wahrscheinlich.

Aber magst du es bei Gelegenheit trotzdem mal ausprobieren, die Reihenfolge der Bit-Dimensionierung zu ändern und zu schauen, ob dann was anderes nicht geht?

Es könnte ja ein Bug sein, der schon vielen anderen die Nerven gekostet hat und dann weiss man es.

Torsten_G
03.01.2006, 21:11
"___lcdno" wird so eine Art Systemvariable sein, die Bascom für das Display braucht.
Fragt mich bloß jetzt nicht, was damit genau angestellt wird, aber der Name ist sicher so festgelegt, und auch, dass es ein Byte sein muß.

Im Bascom-Programm greift der Anwender ja immer nur schreibend darauf zu, aber irgendwo "im Hintergrund" muß der Tag ja auch abgefragt werden.
Und wenn dann im erwarteteten Byte nur ein Bit geliefert wird und der Rest des Bytes durch irgendwelche anderen Bit-Variablen "aufgefüllt" wird, gibt´s logischerweise Tote...

Von daher ist Deine Vermutung sicher naheliegend, Marco.

Man müsste mal wissen, was alles mit dem "___lcdno"-Byte gesteuert werden kann bzw. wie das Display reagiert, wenn andere Werte als 0 oder 1 in "___lcdno" stehen.

Viele Grüße

Torsten

Marco78
03.01.2006, 21:55
Fragt mich bloß jetzt nicht, was damit genau angestellt wird, aber der Name ist sicher so festgelegt, und auch, dass es ein Byte sein muß.

Guter Einwand. In den Beispielen ist es auch ein Byte. Auch wenn es nur mit 0 und 1 verwendet wird.
Aber wie der Assemblercode dahinter aussieht weiss man ja nicht. Zumindest wir Basic-Programmierer wissen es nicht und werden deshalb ab und zu mal als etwas schlechtere Programmierer dargestellt ;)

Mit der Variable wird ja im Prinzip nur eingestellt, welche der beiden Controller aktiv ist. 0 und 1 würde ja reichen. Aber Mark hat sich sicherlich so seine Gedanken gemacht.

Also doch kein Bug :)

Torsten_G
03.01.2006, 22:29
"It´s not a bug, it´s a feature...", wie man so sagt... :P



...
Zumindest wir Basic-Programmierer wissen es nicht und werden deshalb ab und zu mal als etwas schlechtere Programmierer dargestellt ;)
...

Und vollkommen zu Recht, wir sollten uns mehr in Demut üben!

Schau uns doch an:
Wir hadern hier mit den Bits und Bytes rum, während andere bereits mit einem Mega 8 den Raum krümmen! :shock:

Tja... für Profi-Systeme wie "C" gibt es halt die besseren Libraries... :frown: