PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit AD-Wandler (TLC549) an AT-Tiny2313



oiermann
11.03.2007, 15:34
Zu aller erst, ich bin bei Microcontrollern noch blutiger Anfänger und das ist meine erste Schaltung damit. Ich habe allerdings vorher schon mit FreeBASIC unter Linux und Windows ein bisschen programmiert, darum jetzt auch Bascom.

Ich habe jetzt ein HD44780 Display an meinen 2313 angeschlossen (hiernach: https://www.roboternetz.de/wissen/index.php/Bascom_und_LCD's , genau wie beschrieben, nur dass es ein andere Microcontroller ist). Damit kann ich auch wunderbar anzeigen lassen, was ich will.
Jetzt habe ich noch einen AD-Wandler TLC549 mit angeschlossen und möchte mir Spannungen anzeigen lassen.

Jetzt das Problem. Abgeguckt habe ich hier: http://www.skilltronics.de/versuch/elektronik_pc/ad.html

der wichtige Teil des Originalcodes in FreeBASIC/QuickBasic:


volt = 0

OUT 1020, 2 'Strobe an
OUT 1020, 0 'Strobe aus

FOR leitung = 7 TO 0 STEP -1 'Der IC sendet das hoechste Bit zuerst,
'darum laeuft die Schleife rueckwaerts

ein = (INP(ba + 6) AND 16) / 16 'Daten werden ueber CTS eingelesen
volt = volt + ein * 2 ^ leitung 'Jedes Bit bekommt seinen Dezimalwert
OUT 1020, 1 'Clock an
OUT 1020, 0 'Clock aus

NEXT

LOCATE 10, 14
PRINT USING "###"; volt


Und nun mein Code für den AT-Tiny2313:



$regfile = "2313def.dat"

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4
Config Lcdbus = 4

Config Portb.3 = Output
Portb.3 = 0
Config Portb.2 = Input
Portb.2 = 0
Config Portb.1 = Output
Portb.1 = 0

Dim Volt As Single
Dim Leitung As Single
Dim Ein As Single

Do

Volt = 0
Portb.3 = 1
Portb.3 = 0
For Leitung = 7 To 0 Step -1
Ein = Portb.2 / 16
Volt = Volt + Ein * 2 ^ Leitung
Portb.1 = 1
Portb.2 = 0
Next
Cls
Locate 1 , 1
Lcd Volt

Loop


Und hier die Fehlermeldung vom Compiler:

http://www.imageup.de/my.php?image=bcerr.JP.76xi.jpg (tut mir leid wegen der Werbung, aber imageshack war im moment nicht zu erreichen *wunder*)

Hier noch die jeweiligen Zeilen, die die Fehler enthalten:


Zeile 24:
Ein = Portb.2 / 16



Zeile 25:
Volt = Volt + Ein * 2 ^ Leitung


Ich werd aus diesen Meldungen nicht schlau... Ich hoff' ihr könnt mir dabei helfen :)

Dirk
11.03.2007, 15:41
Mach's so für alle Pins:

Config Pinb.2 = Input

Die Zeile Ein = Portb.2 / 16 verstehe ich nicht.

Gruß Dirk

oiermann
11.03.2007, 15:43
Dann kommt die Fehlermeldung immer noch. Und ausserdem lese ich ja an PB2 die Daten vom ADC ein. Was hat das dann für einen Sinn?

Dirk
11.03.2007, 18:47
Was hat das dann für einen Sinn?

Du hattest doch nach Kompilierungsfehlern gefragt.

CONFIG Portb.7 = Input ist ein Syntaxfehler

Es muss heissen:
CONFIG Pinb.7 = Input

Das must du bei allen Pin-Definitionen so machen.
Dann gibt's noch:
CONFIG PortB = Output
Der ganze Port B wird zur Ausgabe genutzt (d.h. Pinb.0 .. 7)

Gruß Dirk

oiermann
11.03.2007, 19:07
Du hattest doch nach Kompilierungsfehlern gefragt.

Ja, wie gesagt, die sind immer noch da.

Ich komme damit irgendwie nicht klar, probier auch schon die ganze Zeit herum, aber das hat weder Hand noch Fuss...

jar_
11.03.2007, 19:38
Ich komme damit irgendwie nicht klar, probier auch schon die ganze Zeit herum, aber das hat weder Hand noch Fuss...

ja Bascom ist irgendwie eigen, ich blicke auch noch nicht volltändig durch, aber der Code funktioniert


$regfile = "2313def.dat" ' specify the used micro
$crystal = 4000000 ' used crystal frequency
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space

Ddrb = &HFF
Ddrd = &H01

Config Rc5 = Pind.2
Portd.2 = 1

Enable Interrupts

Declare Sub Dimm_pwm

Dim Address As Byte , Command As Byte
Dim Oldaddress As Byte , Oldcommand As Byte

Oldaddress = 0
Oldcommand = 0




'$lib"lcd4busy.lib"

'define the used constants
'I used portA for testing
'Const _lcdport = Portb
'Const _lcdddr = Ddrb
'Const _lcdin = Pinb
'Const _lcd_e = 1
'Const _lcd_rw = 2
'Const _lcd_rs = 3

'this is like always, define the kind of LCD
Config Lcd = 20 * 4
'other options are 16 * 2 , 16 * 4 and 20 * 4, 20 * 2 , 16 * 1a

Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down , Prescale = 8


Dim A As Byte , Count As Long
Dim Strcount As String * 12

Portb.0 = 1

'and here some simple lcd code
Cursor Off Noblink
Cls
Locate 1 , 1 : Lcd "17tes " 'display this at the top line
Wait 1
Locate 2 , 1 : Lcd "im LOOP LED blinkt1"
A = Portd
Portd = 1
Waitms 500
Portd = 0
Waitms 500
'Loop
Locate 2 , 1 : Lcd "Waiting for RC5..."
Count = 0

Call Dimm_pwm

Do

Getrc5(address , Command)
If Address < 255 Then
Count = Count + 1
'If Count.0 = 0 Then
' Compare1a = 128
'Else
' Compare1a = 32
'End If
Strcount = Str(count)
A = 20 - Len(strcount)
Locate 1 , 8
Lcd " "
Locate 1 , A
Lcd Strcount
End If

Locate 3 , 1 : Lcd "Address=" ;
Locate 4 , 1 : Lcd "Command=" ;
If Address < 255 Then
If Address = 54 And Command = 7 Then
Toggle Portb.0
Waitms 500
Toggle Portb.0
End If
If Address = 7 And Command = 54 Then
Toggle Portb.0
Waitms 500
Toggle Portb.0
End If

Locate 3 , 9 : Lcd Address
If Command.7 = 1 Then
Portd = 1 : Command.7 = 0
Compare1a = 200
Else
Portd = 0
Compare1a = 8
End If
Locate 4 , 9 : Lcd Command
If Command <> Oldcommand Or Address <> Oldaddress Then
Oldcommand = Command
Oldaddress = Address
Locate 2 , 1 : Lcd " "
Locate 2 , 1 : Lcd "Old..."
Locate 2 , 7 : Lcd Oldaddress ; " ..."
Locate 2 , 11 : Lcd Oldcommand ; " ..."
Locate 2 , 15 : Lcd "Wait"
Count = 0
End If
Else
Locate 3 , 9 : Lcd " "
Locate 4 , 9 : Lcd " "
End If
Loop
End

Sub Dimm_pwm

Dim I As Byte , J As Byte

For I = 1 To 2
For J = 255 To 64 Step -10
Compare1a = J
Waitms 10
Next J
Wait 1
For J = 64 To 255 Step 10
Compare1a = J
Waitms 10
Next J
Wait 1
Next I


End Sub

Problem ist die Sprache als solches

folgendes wollte ich, gab Fehlermeldungen,

If ((Address = 54 And Command = 7) or (Address = 7 And Command = 54 ))Then

dieses funzt, ist aber doofer Stil

If Address = 54 And Command = 7 Then
Toggle Portb.0
Waitms 500
Toggle Portb.0
End If
If Address = 7 And Command = 54 Then
Toggle Portb.0
Waitms 500
Toggle Portb.0
End If

usw.

oiermann
11.03.2007, 19:45
So, das compilieren hab ich nun hinbekommen und in der Hilfe auch ein bisschen gestöbert, aber das bringt mich nun auch nicht weiter.
Mit diesem Code kommen nur 1er auf dem Display, egal ob ich am Eingang des ADC etwas anlege oder frei lasse.


$regfile = "2313def.dat"

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4
Config Lcdbus = 4

Dim Leitung As Byte
Dim A As Byte
Dim Ein As Byte
Dim Ein2 As Integer
Dim Ein3 As Byte
Dim Volt As Byte

Dim Volt2 As Byte
Dim Volt3 As Byte


Do
Portb.3 = 1
Portb.3 = 0
For Leitung = 7 To 0 Step -1
If Pinb.2 = 0 Then A = 0
If Pinb.2 = 1 Then A = 1
Ein = A * 16
Ein2 = Ein And 16
Ein3 = Ein2 / 16
Volt = Volt + Ein3
Volt2 = Volt * 2
Volt3 = Volt2 ^ Leitung
Portb.1 = 1
Portb.1 = 0
Next
Lcd Volt3
Loop


Was mir auch noch komisch vorkommt, ist soewtwas hier:


a = a + b
a2 = a * c
a3= a2 ^ d

In FreeBASIC wäre das so a = a + b * c ^ d gewesen, aber wenn ich das so reinschreibe, bringt der Compiler wieder Fehlermeldungen

//edit2:

jar_: Ja der Dialekt ist eigen, aber dein Code hat doch hoffentlich nichts mit meinem Problem zu tun oder? Da komm ich nich mit...

jar_
11.03.2007, 20:20
So, das compilieren hab ich nun hinbekommen und in der Hilfe auch ein bisschen gestöbert, aber das bringt mich nun auch nicht weiter.
Mit diesem Code kommen nur 1er auf dem Display, egal ob ich am Eingang des ADC etwas anlege oder frei lasse.

jar_: Ja der Dialekt ist eigen, aber dein Code hat doch hoffentlich nichts mit meinem Problem zu tun oder? Da komm ich nich mit...

mein code hat nix mit deinem zu tun, wollte nur zeigen was als alter basic progger zu Fehlermeldungen vom bascom führt

zu deinem Problem, warum nicht erst mal ADC lesen und ausgeben, warum schon vorher in IF abfragen verstecken und rechnen, muss man sich nicht über Fehler wundern, ich würde erst den ADC Port mit Multimeter versehen und schaun das ich passende Digiwerte lese

Dirk
11.03.2007, 20:20
Hallo oiermann,

das sieht doch schon gut aus.
Ich kenne den TLC549 nicht, aber er gibt doch nur 8 Bits beginnend mit dem MSB aus. Oder?

Da reicht eine Schleife, wie du sie schon hast (0..7).
Darin sind die Hauptbefehle
SHIFT Ergebnis , LEFT , 1
Ergebnis = Ergebnis + Eingabepin

Ergebnis ist deine 8-Bit-Variable für das Ergebnis (0..255), Eingabepin war ja bei dir Pinb.2
Das ist alles.

Schau dir den Befehl SHIFT in der Bascom-Hilfe an.

Gruß Dirk

oiermann
12.03.2007, 07:01
Jar_: achsoo, ich hab' mich schon gewundert...

Dirk: jetzt muss ich in die Schule, werd mir das heute Mittag mal ansehen. Hier ist er nocheinmal gut erklärt http://www.franksteinberg.de/SOURCE/TLC549.TXT

jar
12.03.2007, 15:26
ich bin nun jar ohne _

Dirk
12.03.2007, 18:23
Hallo oiermann,

ah ja, jetzt kapiere ich den TLC549.

Probier mal mit folgendem rum (keine Garantie, ich kanns ja nicht testen!):

$regfile = "2313def.dat"

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4
Config Lcdbus = 4

Config Pinb.3 = Output
Cs Alias Portb.3
Cs = 0 'Strobe low

Config Pinb.2 = Input
Eingabepin Alias Portb.2

Config Pinb.1 = Output
Io_clock Alias Portb.1
Io_clock = 0 'Clock low

Dim Cntr As Byte
Dim Ergebnis As Byte

Do
Cs = 1 'Strobe high
Cs = 0 'Strobe low
Ergebnis = 0
For Cntr = 0 To 7
Shift Ergebnis , Left , 1
Ergebnis = Ergebnis + Eingabepin
Io_clock = 1 'Clock high
Io_clock = 0 'Clock low
Next Cntr
' Waitus 17 '17us warten
' (Nur nötig, wenn sofort eine neue Messung erfolgt!)
Cls
Locate 1 , 1
Lcd Ergebnis
Wait 3
Loop
Die Ausgabe ist natürlich jetzt noch nicht in Volt, sondern der Digitalwert (0..255), der in eine Spannung umgerechnet werden muss.

Gruß Dirk

oiermann
12.03.2007, 21:14
Cool, danke Dirk :) Das werde ich morgen Nachmittag ausprobieren, jetzt hab ich noch einiges an Schulzeug zu machen (in 7 Wochen Prüfungen und bis dahin schreiben wir noch so einiges...).

Heute Nachmittag habe ich einen Wecker gebastelt, das ging relativ einfach und schnell, ich glaube mit Software in BASCOM hatte es das in 2 Stunden.
Die AVRs haben es mir angetan :)

oiermann
13.03.2007, 18:06
So, ich habe das nun mal ausprobiert und im Code steige ich auch einnigermassen durch. Nur gibts da jetzt ein Problem... Es steht immer null auf dem Display.
Richtig angeschlossen ist er auf jeden Fall, ich hab es dreimal mindestens überprüft und auch einen anderen TLC549 mal reingesteckt, den ich vorher noch am PC ausprobiert habe. Da haben beide funktioniert.

//edit: google hat mir das noch gebracht, wunderbar habe ich gedacht und die pins angepasst, aber Pustekuchen. Es zeigt immer 5.10V an...
http://www.qsl.net/dg1xpz/elektronik/avr/tlc549.html

Dirk
13.03.2007, 21:01
Ist ja wunderbar! Ein Bascom-Beispiel!

Das sähe bei uns ja so aus:

Cs = 1 'Strobe high
Io_clock = 0 'Clock low
Do
Cs = 0 'Strobe low
Ergebnis = 0
Waitus 2
For Cntr = 0 To 7
Io_clock = 1 'Clock high
Shift Ergebnis , Left , 1
Ergebnis = Ergebnis + Eingabepin
Io_clock = 0 'Clock low
Next Cntr
' Waitus 17 '17us warten
' (Nur nötig, wenn sofort eine neue Messung erfolgt!)
Cs = 1
Io_clock = 1
Cls
Locate 1 , 1
Lcd Ergebnis
Wait 3
Loop

Die wichtigste Änderung dürfte das Warten für 2 us vor Abfragen des 1. Bits sein. Vielleicht klappts ja so.

Gruß Dirk

oiermann
14.03.2007, 20:58
Ne, das ist es auch nicht... Ich glaub ich geb das auf und besorg mich noch einen, der schon einen ADC eingebaut hat.

//edit: verdammt. Irgendwas war/ist kaputt. Ich hab die Schaltung genau wie in dem Link mit dem Bascom-Beispiel nochmal aufgebaut. Und es funktioniert. Nochmal so aufgebaut wie ich sie gelötet habe, Software angepasst und funktioniert auch.

Vielen Dank Dirk :) Ich hoffe, ich hab dir nicht allzuviel Mühe umsonst gemacht...

oiermann
15.03.2007, 17:35
So, jetzt stehe ich vor dem nächsten Problem *verdammt*...
Ich will natürlich nicht nur Spannungen von 0 bis 5V messen können, sondern 0..10V sollten es schon sein. Also habe ich im code folgendes gemacht:


U = Ad / 50
Lcd "Spannung: "; U ; "."
U = Ad Mod 100
Lcd U ; " V"

(vorher war statt der 50 eine hundert da)

Und an der Elektronik hab ich einen Spannungsteiler mit zwei 10K-Widerständen hingemacht, die die Spannung halbieren. Gut und recht, nur hier mal ein paar ergebnisse:
Links die Spannung wie sie das regelbare Netzteil anzeigt, rechts die vom uC


3.56 3.72
6.9 6.36
7.12 6.46
8.91 8.34
10.21 9.96
...
...

Was mich stutzig macht, ist der erste Wert, die einen sind immer ein bisschen kleiner (gut, das kann durch den Spannungsteiler und einen 10K Schutzwiderstand zu verlusten führen, denk ich jetzt mal so)
und der erste ist grösser.
hier noch ein bisschen mehr:


3.71 3.8
3.90 3.90

ab 3.90Volt geht es wieder Bergab mit den Werten, an was liegt das bzw wie bekomm ich das weg?
Liegt das eher an der Software oder der Elektronik?