PORTA is toch ook output? (ik zie TRISA = 0...)
LATx is inderdaad output. Voorkomt RMW problemen...
Special Member
PORTA is toch ook output? (ik zie TRISA = 0...)
LATx is inderdaad output. Voorkomt RMW problemen...
Golden Member
Je hebt gelijk; er staat TRISA = 0.
Ik gebruik PORTA voor het afvragen van de schakelaar, dus input.
Maar het werkt wel.
Dan zal de status vermoedelijk automatisch op input worden gezet?
Wellicht hierdoor:
PORTA = %11111111
[Bericht gewijzigd door Bavelt op vrijdag 1 november 2019 15:19:55 (16%)
Special Member
Je leest gewoon de pin status uit. Als die als output staat, zul je die (met de schakelaar) met geweld naar beneden trekken.
Dat vinden de output drivers niet fijn (die proberen de pin hoog te houden), maar ze overleven het meestal wel...
Golden Member
Ik heb het in ieder geval aangepast.
Golden Member
Ik heb de schakeling even getest zonder de RTC- DS3231 module erin. Dan blijft de processor wachten tot hij iets krijgt. Eeuwig dus.
Is er wellicht iets te bedenken dat je een afvraging kunt doen of de I2C Lees of schrijfopdracht wel is gelukt? Of een vorm van Time-out (waarbij je dan bv een LEDje kan laten branden bij een mislukte I/O).
Want stel je voor dat zo'n moduultje stuk is, dan hangt de boel dus ook.
In de Arduino is er een programmaatje dan alle adressen afspeurt of er een I2c Device is gevonden. (I2C-scanner).
Die zal ook wel iets in de geest doen of een I/O is gelukt, ACKnowledge, o.i.d.
Special Member
Da's gebruikelijk met de meeste libraries dat i2c dan hangt...
Daarom heb ik zelf een vervangende versie gemaakt...
module lib_i2c
Const I2CTimeOut = 200
Dim I2cStatus As Byte
'Statusbits: 00000001 - Start
' 00000010 - Restart
' 00000100 - Stop
' 00001000 - Write
' 00010000 - Read
' 00100000 - Idle
' 01000000 - Receive buffer
' 10000000 - Busy
Sub Procedure I2CInit()
Sub Procedure I2CStart()
Sub Procedure I2CRestart()
Sub Procedure I2CStop()
Sub Procedure I2CWrite(Dim pDat As Byte)
Sub Procedure I2CIdle()
Sub Function I2CRead(Dim pAck As Byte) As Byte
implements
'==================================================================================================
Sub Procedure I2CIdle() 'Wait for bus idle
'--------------------------------------------------------------------------------------------------
Dim lCnt As Word '
For lCnt = 0 To I2CTimeout '
If (I2C1CON And 0x1F) = 0 then break end if '
Next lCnt '
I2cStatus.5 = (I2C1CON And 0x1F) '
End Sub '
'==================================================================================================
Sub Procedure I2Cinit() 'Init I2C1 peripheral (400kHz)
'--------------------------------------------------------------------------------------------------
I2C1BRG = 0x0025 '(Fcy/scl)-(Fcy/10000000) -1
I2CEN_Bit = 1 'Enable I2C1
Delay_ms(10) '
I2C1STAT = 0 '
End Sub '
'==================================================================================================
Sub Procedure I2CStart() 'Start bus
'--------------------------------------------------------------------------------------------------
Dim lCnt As Word '
I2cStatus = 0x80
I2CIdle() 'Wait for bus idle
SEN_Bit = 1 'Set start bit
For lCnt = 0 To I2CTimeout 'Wait for bit to clear
If (SEN_Bit = 0) Then Break End If '
Next lCnt '
I2cStatus.0 = SEN_bit 'Errorstatus
End Sub '
'==================================================================================================
Sub Procedure I2CRestart() 'Restart bus
'--------------------------------------------------------------------------------------------------
Dim lCnt As Word '
I2CIdle() 'Wait for bus idle
RSEN_Bit = 1 'Set repeated start bit
For lCnt = 0 To I2CTimeout 'Wait for bit to clear
If (RSEN_Bit = 0) Then Break End If '
Next lCnt '
I2cStatus.1 = RSEN_bit 'Errorstatus
End Sub '
'==================================================================================================
Sub Procedure I2CStop() 'Stop bus
'--------------------------------------------------------------------------------------------------
Dim lCnt As Word '
I2CIdle() 'Wait for bus idle
PEN_Bit = 1 'Set stop bit
For lCnt = 0 To I2CTimeout 'Wait for bit to clear
If (PEN_Bit = 0) Then Break End If '
Next lCnt '
I2cStatus.2 = PEN_Bit 'Errorstatus
I2cStatus.7 = 0 '
End Sub '
'==================================================================================================
Sub Procedure I2CWrite(Dim pDat As Byte) 'Write byte pDat to bus
'--------------------------------------------------------------------------------------------------
Dim lCnt As Word '
I2CIdle() 'Wait for bus idle
MI2C1IF_Bit = 0 'Clear interruptflag
I2C1TRN = pDat 'Data to send into buffer
For lCnt = 0 To I2CTimeout 'Wait for interruptflag to
If MI2C1IF_bit Then Break End If 'get set
Next lCnt '
I2cStatus.3 = MI2C1IF_Bit Xor 1 'Errorstatus
End Sub
'==================================================================================================
Sub Function I2CRead(Dim pAck As Byte) As Byte 'Read byte of bus(1=Nack/0=Ack)
'--------------------------------------------------------------------------------------------------
Dim lCnt As Word '
I2CIdle() 'Wait for bus idle
MI2C1IF_Bit = 0 'Clear interruptflag
RCEN_Bit = 1 '
For lCnt = 0 To I2cTimeout 'Wait for buffer
If RBF_Bit Then Break End If '
Next lCnt '
I2cStatus.6 = RBF_Bit Xor 1 'Errorstatus
Result = I2C1RCV 'Get received byte
ACKDT_Bit = pAck 'Send Ack/Nack
ACKEN_Bit = 1 '
For lCnt = 0 To I2CTimeout '
If MI2C1IF_Bit Then Break End If '
Next lCnt '
I2cStatus.4 = MI2C1IF_Bit Xor 1 'Errorstatus
End Sub '
end.
'==================================================================================================
Golden Member
Dat is een leuke om eens uit te proberen eerdaags...