Jaecko
23.12.2007, 20:48
Hiho.
Mal wieder ein Problem.
Ich hab mir mal ein (preislich gesehen) billiges 40x4-LCD (DisplayTech 404B Series) besorgt. Um dieses universell und ohne viel Verkabelungsaufwand verwenden zu können, hab ich auf eine kleine Zusatzplatine nen ATMega8 draufgepackt, der sich wie ein I2C-Slave verhält, die empfangenen Daten umsetzt und auf dem Display darstellt. Mit nem RS232-I2C-Adapter klappt die Ansteuerung auch problemlos.
Nun wollte ich das Teilchen an nem ATMega2560 per I2C ansprechen: Es passiert garnichts. Häng ich statt dem Display das RNKeyLCD hin, rührt sich ebenfalls nix. Mit LED-Überwachung zeigt sich, dass beide Leitungen (SCL/SDA) ständig High sind. Lass ich in dem Code unten den "I2CINIT" weg, so ist SDA = Hi, SCL = Lo.
Verbindungstechnisch hängt die ganze Sache an nem Flachbandkabel mit 3 Steckern; Die Geräte werden alle auch über den Bus mit Strom versorgt.
Stecker 1: Stromversorgung für Bus + 10k-Pullups für SDA/SCL; Zuschaltbarer RS232-I2C-Adapter.
Stecker 2: ATMega2560 (Keine Pullups)
Stecker 3: RNKeyLCD oder 404B (bei letzterem keine Pullups)
Hier mal der bisherige Code:
Die Sub ist noch ein überbleibsel und wird später noch "wegoptimiert".
In der Mainloop soll nur Testweise der Buchstabe X bzw. Y mit 2 verschiedenen Möglichkeiten gesendet werden.
' Wait for I2C-LCD to be ready
Wait 2
$lib "i2c.lbx"
$lib "i2c_twi.lbx"
'-------------------------------------------------------------------------------
' Declarations - SUBs
'-------------------------------------------------------------------------------
Declare SUB I2CLCD_Send
'-------------------------------------------------------------------------------
' Declarations - Ports & Pins
'-------------------------------------------------------------------------------
CONFIG PIND.0 = OUTPUT 'SCL
CONFIG PIND.1 = OUTPUT 'SDA
CONFIG PIND.5 = OUTPUT : LED ALIAS PORTD.5 'Onboard-LED
'-------------------------------------------------------------------------------
' Declarations - Constants
'-------------------------------------------------------------------------------
CONST Timer1Preload = 100
CONST SID_RNKeyLCD = &H40 ' RNKeyLCD
CONST SID_I2CLCD = &H42 ' 404B-Series
CONST SID_Nokia6100 = &H44 ' Nokia 6100 Color LCD
CONST SID_ServoBoard = &H46 ' MicroServo-Board
CONST SID_GeneralCall = &H00 ' General Call
'-------------------------------------------------------------------------------
' Declarations - Variables
'-------------------------------------------------------------------------------
'Counting Variables
DIM i as Byte
DIM i2 as Byte
'Temporary Variables
DIM tmpByte as Byte
DIM tmpString as String * 1
'LCD Text
DIM LCDString(4) AS String * 40
DIM LCDStringOld(4) AS String * 40
'-------------------------------------------------------------------------------
' Configs
'-------------------------------------------------------------------------------
CONFIG SCL = PORTD.0
CONFIG SDA = PORTD.1
CONFIG TIMER1 = TIMER , Prescale = 1024
Config Twi = 100000 '100 kHz Bus Frequency
'-------------------------------------------------------------------------------
' Initialisations
'-------------------------------------------------------------------------------
I2CINIT
TIMER1 = Timer1Preload
On Timer1 ISR_Timer1
ENABLE Timer1
ENABLE Interrupts
'************************************************* ******************************
' MAIN LOOP START
'************************************************* ******************************
DO
I2cstart
I2cwbyte SID_RNKeyLCD
I2cwbyte 88 'Send "X"
I2cstop
I2CSend SID_RNKeyLCD , 89 'Send "Y"
Toggle LED
WAITms 500
LOOP
END
'************************************************* ******************************
' MAIN LOOP END
'************************************************* ******************************
'-------------------------------------------------------------------------------
' SUBs
'-------------------------------------------------------------------------------
SUB I2CLCD_Send
For i = 1 to 4
If LCDString(i) <> LCDStringOld(i) Then
tmpByte = LEN(LCDString(i)) ' Get length of String
tmpByte = 40 - tmpByte ' Chars Needed to 40
if tmpByte > 0 Then LCDString(i) = LCDString(i) + SPACE(tmpByte)
I2CStart 'Set Cursor to Line i
I2CWByte SID_I2CLCD
I2CWByte 027 'Send System-Command
I2CWByte 079 'Set Cursor
I2CWByte 001 'Column 1
I2CWByte i 'Line i
I2CStop
I2CStart 'Transfer selected Line
I2CWByte SID_I2CLCD
I2CWByte 001 'Send Text-Command
I2CWByte 040 'Length: 40 Bytes
For i2 = 1 to 40 'Send Text-Bytes
Toggle LED
tmpString = mid(LCDString(i) , i2 , 1)
tmpByte = ASC(tmpString)
I2CWByte tmpByte
Next
I2cstop
LCDStringOld(i) = LCDString(i)
End If
Next i
END SUB
'-------------------------------------------------------------------------------
' Jump Labels / ISR
'-------------------------------------------------------------------------------
ISR_Timer1:
Timer1 = Timer1Preload
Return
Hab ich mit der Ansteuerung per I2C was übersehen?
Muss jedes Gerät selbst nochmal Pullups haben oder reichen die beiden bei der Versorgung?
MfG
S.C
Mal wieder ein Problem.
Ich hab mir mal ein (preislich gesehen) billiges 40x4-LCD (DisplayTech 404B Series) besorgt. Um dieses universell und ohne viel Verkabelungsaufwand verwenden zu können, hab ich auf eine kleine Zusatzplatine nen ATMega8 draufgepackt, der sich wie ein I2C-Slave verhält, die empfangenen Daten umsetzt und auf dem Display darstellt. Mit nem RS232-I2C-Adapter klappt die Ansteuerung auch problemlos.
Nun wollte ich das Teilchen an nem ATMega2560 per I2C ansprechen: Es passiert garnichts. Häng ich statt dem Display das RNKeyLCD hin, rührt sich ebenfalls nix. Mit LED-Überwachung zeigt sich, dass beide Leitungen (SCL/SDA) ständig High sind. Lass ich in dem Code unten den "I2CINIT" weg, so ist SDA = Hi, SCL = Lo.
Verbindungstechnisch hängt die ganze Sache an nem Flachbandkabel mit 3 Steckern; Die Geräte werden alle auch über den Bus mit Strom versorgt.
Stecker 1: Stromversorgung für Bus + 10k-Pullups für SDA/SCL; Zuschaltbarer RS232-I2C-Adapter.
Stecker 2: ATMega2560 (Keine Pullups)
Stecker 3: RNKeyLCD oder 404B (bei letzterem keine Pullups)
Hier mal der bisherige Code:
Die Sub ist noch ein überbleibsel und wird später noch "wegoptimiert".
In der Mainloop soll nur Testweise der Buchstabe X bzw. Y mit 2 verschiedenen Möglichkeiten gesendet werden.
' Wait for I2C-LCD to be ready
Wait 2
$lib "i2c.lbx"
$lib "i2c_twi.lbx"
'-------------------------------------------------------------------------------
' Declarations - SUBs
'-------------------------------------------------------------------------------
Declare SUB I2CLCD_Send
'-------------------------------------------------------------------------------
' Declarations - Ports & Pins
'-------------------------------------------------------------------------------
CONFIG PIND.0 = OUTPUT 'SCL
CONFIG PIND.1 = OUTPUT 'SDA
CONFIG PIND.5 = OUTPUT : LED ALIAS PORTD.5 'Onboard-LED
'-------------------------------------------------------------------------------
' Declarations - Constants
'-------------------------------------------------------------------------------
CONST Timer1Preload = 100
CONST SID_RNKeyLCD = &H40 ' RNKeyLCD
CONST SID_I2CLCD = &H42 ' 404B-Series
CONST SID_Nokia6100 = &H44 ' Nokia 6100 Color LCD
CONST SID_ServoBoard = &H46 ' MicroServo-Board
CONST SID_GeneralCall = &H00 ' General Call
'-------------------------------------------------------------------------------
' Declarations - Variables
'-------------------------------------------------------------------------------
'Counting Variables
DIM i as Byte
DIM i2 as Byte
'Temporary Variables
DIM tmpByte as Byte
DIM tmpString as String * 1
'LCD Text
DIM LCDString(4) AS String * 40
DIM LCDStringOld(4) AS String * 40
'-------------------------------------------------------------------------------
' Configs
'-------------------------------------------------------------------------------
CONFIG SCL = PORTD.0
CONFIG SDA = PORTD.1
CONFIG TIMER1 = TIMER , Prescale = 1024
Config Twi = 100000 '100 kHz Bus Frequency
'-------------------------------------------------------------------------------
' Initialisations
'-------------------------------------------------------------------------------
I2CINIT
TIMER1 = Timer1Preload
On Timer1 ISR_Timer1
ENABLE Timer1
ENABLE Interrupts
'************************************************* ******************************
' MAIN LOOP START
'************************************************* ******************************
DO
I2cstart
I2cwbyte SID_RNKeyLCD
I2cwbyte 88 'Send "X"
I2cstop
I2CSend SID_RNKeyLCD , 89 'Send "Y"
Toggle LED
WAITms 500
LOOP
END
'************************************************* ******************************
' MAIN LOOP END
'************************************************* ******************************
'-------------------------------------------------------------------------------
' SUBs
'-------------------------------------------------------------------------------
SUB I2CLCD_Send
For i = 1 to 4
If LCDString(i) <> LCDStringOld(i) Then
tmpByte = LEN(LCDString(i)) ' Get length of String
tmpByte = 40 - tmpByte ' Chars Needed to 40
if tmpByte > 0 Then LCDString(i) = LCDString(i) + SPACE(tmpByte)
I2CStart 'Set Cursor to Line i
I2CWByte SID_I2CLCD
I2CWByte 027 'Send System-Command
I2CWByte 079 'Set Cursor
I2CWByte 001 'Column 1
I2CWByte i 'Line i
I2CStop
I2CStart 'Transfer selected Line
I2CWByte SID_I2CLCD
I2CWByte 001 'Send Text-Command
I2CWByte 040 'Length: 40 Bytes
For i2 = 1 to 40 'Send Text-Bytes
Toggle LED
tmpString = mid(LCDString(i) , i2 , 1)
tmpByte = ASC(tmpString)
I2CWByte tmpByte
Next
I2cstop
LCDStringOld(i) = LCDString(i)
End If
Next i
END SUB
'-------------------------------------------------------------------------------
' Jump Labels / ISR
'-------------------------------------------------------------------------------
ISR_Timer1:
Timer1 = Timer1Preload
Return
Hab ich mit der Ansteuerung per I2C was übersehen?
Muss jedes Gerät selbst nochmal Pullups haben oder reichen die beiden bei der Versorgung?
MfG
S.C