Tonen generen met PIC16F628A

Arco

Special Member

PORTA is toch ook output? (ik zie TRISA = 0...)
LATx is inderdaad output. Voorkomt RMW problemen...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

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:

pic basic code:

 PORTA =  %11111111 

[Bericht gewijzigd door Bavelt op vrijdag 1 november 2019 15:19:55 (16%)

Fouten zijn het bewijs dat je het probeert..
Arco

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...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik heb het in ieder geval aangepast.

Fouten zijn het bewijs dat je het probeert..
Bavelt

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.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Da's gebruikelijk met de meeste libraries dat i2c dan hangt... ;)
Daarom heb ik zelf een vervangende versie gemaakt...

pic basic code:


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.

'==================================================================================================
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Dat is een leuke om eens uit te proberen eerdaags...

Fouten zijn het bewijs dat je het probeert..