Menu

I2C on PIC18F47K40

Help
jackjames
2021-06-19
2021-06-20
  • jackjames

    jackjames - 2021-06-19

    Hello.
    I have a problem using hardware I2C with a PIC18F47K40.
    I use I2C1.
    Basically the program crashes when I go to write the address.
    As a test I adapted a sample program and added an LCD display to it for convenience.
    The serial and the display work perfectly. The problem is on I2C1.
    This is the test program:

            #Option Explicit
    '       -
    '       -
            #Chip 18F47K40, 64
            #Config OSC = INT', MCLR_OFF
    '       -
    '       Configurazione dei pins per la seriale e il bus I2C
            #StartUp InitPPS, 85
            #Define PPSTOOLPART 18f47k40
    
            #Define LCD_IO 4
            #Define LCD_NO_RW
            #Define LCD_SPEED fast
    
            ;Change As necessary
            #Define LCD_RS PORTD.6
            #Define LCD_ENABLE PORTD.7
            #Define LCD_ENABLE2 PORTE.2
    
            #Define LCD_DB4 PORTD.2
            #Define LCD_DB5 PORTD.3
            #Define LCD_DB6 PORTD.4
            #Define LCD_DB7 PORTD.5
    
    '       Define I2C settings
            #Define HI2C_BAUD_RATE 100
            #Define HI2C_DATA PORTC.4
            #Define HI2C_CLOCK PORTC.3
    
    
    '       Initialise I2C - note for the I2C module the ports need to be set to Output.
            Dir HI2C_DATA Out
            Dir HI2C_CLOCK Out
    
    '       Setup Serial port
            #Define USART_BAUD_RATE 9600
            #Define USART_TX_BLOCKING
    
            Dim DeviceID As Byte
            Dim DISPLAYNEWLINE As Byte
    
            Cls
            Print "Start test I2C"
            Do
               HSerPrintCrLf
               HSerPrint "Hardware I2C "
               HSerPrintCrLf 2
    
    '          Now assumes Serial Terminal is operational
               HSerPrintCrLf
               HSerPrint "   "
    '          Create a horizontal row of numbers
               For DeviceID = 0 to 15
                  HSerPrint hex(DeviceID)
                  HSerPrint " "
               Next
    
    '          Create a vertical column of numbers
               For DeviceID = 0 to 255
                  Locate 3,1
                  Print DeviceID
                  DISPLAYNEWLINE = DeviceID % 16
                  If DISPLAYNEWLINE = 0 Then
                     HSerPrintCrLf
                     HSerPrint hex(DeviceID)
                     If DISPLAYNEWLINE > 0 Then
                        HSerPrint " "
                     End If
                  End If
                  HSerPrint " "
    
    '             Do an initial Start
                  HI2CStart
                  If HI2CWaitMSSPTimeout <> TRUE Then
    
    '                Send to address to device
                     HI2CSend ( DeviceID )
    
    '                Did device fail to respond?
                     If HI2CAckPollState = FALSE Then
                        HI2CSend ( 0 )
                        HSerPrint   hex(DeviceID)
                     Else
                        HSerPrint "--"
                     End If
    '                Do a stop.
                     HI2CStop
    
                  Else
                     HSerPrint "! "
                  End If
    
               Next
    
               HSerPrintCrLf 2
               HSerPrint   "End of Search"
               HSerPrintCrLf 2
               Wait 5 s
            Loop
    
    '       -
    '       -
    Sub InitPPS
            UnLockPPS
    'Module: EUSART1
               RC6PPS = 0x0009    'TX1 > RC6 25
               RX1PPS = 0x0017    'RC7 > RX1 26
    'Module: MSSP1
               SSP1DATPPS = 0x0014    'RC4 > SDA1
               RC4PPS     = 0x0010    'SDA1 > RC4 (bi-directional)
               RC3PPS     = 0x000F    'SCL1 > RC3
               SSP1CLKPPS = 0x0013    'RC3 > SCL1 (bi-directional)
            LockPPS
    End Sub
    
     
  • Anobium

    Anobium - 2021-06-19

    What version of the compiler? Compiles ok on ;Program compiled by Great Cow BASIC (0.98.07 2021-06-07 (Windows 64 bit)) for Microchip MPASM

    What do you mean by program crashes is the compiler crashing?

     
  • jackjames

    jackjames - 2021-06-19

    This is my version:
    Compiler Version: 0.98.<<>> 2021-05-21 (Windows 64 bit) Program Memory: 1044/65536 words (1,59%) RAM: 46/3720 bytes (1,24%) OSC: HFINTOSC_1MHZ, 64Mhz (Internal oscillator) Chip: 18F47K40

     
  • jackjames

    jackjames - 2021-06-19

    The compilation is fine.
    Program operation hangs on "HI2CSend"

     
    • Anobium

      Anobium - 2021-06-19

      Upload your HWi2c.h. I will compare to the released version. Then, I can advise.

      I did test the library prior to release but by comparing yours and the released file(s) will help.

       
      • jackjames

        jackjames - 2021-06-19

        Ok.

         
  • Anobium

    Anobium - 2021-06-19

    No issue with the file.

    So, the error is the direction of the I2C ports. They should be IN.

    See demo - C:\GCB@Syn\GreatCowBasic\Demos\vendor_boards\great_cow_basic_demo_board\18f27k40_chiprange_demonstrations\150_show_i2c_devices_to_serial_terminal.gcb

     
    • jackjames

      jackjames - 2021-06-19

      OK. Itest.

       
    • jackjames

      jackjames - 2021-06-19

      Nothing to do!
      the hardware is connected well, there are pullup resistors, I have inserted a PCF8574 in the bus but I can not write or read in any way.
      I tried to use the Mikrobasic compiler as well with the same result.
      I doubt that it could be the micro, but it would be the first time ...
      For the moment I do not have another to try, when I return to Rome I will do some tests.

       
  • Anobium

    Anobium - 2021-06-19

    Your code is missing --- check the demo....

    'MASTER
    HI2CMode Master
    
     
    • jackjames

      jackjames - 2021-06-19

      I have adapted the code for the PIC18F47K40.
      Although there are devices connected to the I2C bus, they are not recognized.
      At this point I think it's the faulty micro

      '       ''
      '       ''******************************************************************
      '       ''
      '       ''
      '       ''
      '       ''  PIC: 18F47K40
      '       ''  Compiler: GCB
      '       ''  IDE: GCB@SYN
      '       ''
      '       ''  Date: 29.8.2019
      '       ''
      
      
      '       ----- Configuration
      '       Chip Settings.
              #Chip 18F47K40,32
              #Option Explicit
              #Config MCLRE=Off
      
      '       Generated by PIC PPS Tool for Great Cow Basic
      '       PPS Tool version: 0.0.5.26
      '       PinManager data: v1.76
      '       Generated for 18F47K42
      '
      '       Template comment at the start of the config file
      '
              #StartUp InitPPS, 85
              #Define PPSToolPart 18F47K40
      
      
      '       ODCC3=1    'Set pin As open drain Output
      '       Template comment at the end of the config file
      
              #Define USART_BAUD_RATE 9600
              #Define USART_BLOCKING
      '       #Define sync SYNC_TX1STA
      
      
              ; ----- Define Hardware settings For hwi2c
      '       Define I2C settings - CHANGE PORTS if required for your specific device.
              #Define hi2c_BAUD_RATE 400
              HI2CMode Master
      
              ; ----- Main body of program commences here.
      '       Now assumes Serial Terminal is operational
              Dim DeviceID As Byte
              Dim DISPLAYNEWLINE As Byte
      '-
      '-
              HSerPrintCrLf
              HSerPrint "Hardware I2C "
              HSerPrintCrLf 2
      '-
              HSerPrint "     "
              For DeviceID = 0 to 15
                 HSerPrint hex(deviceID)
                 HSerPrint " "
              Next
              '-
              For DeviceID = 0 to 255
                 DisplayNewLine = DeviceID % 16
                 If DisplayNewLine = 0 Then
                    HSerPrintCrLf
                    HSerPrint hex(DeviceID)
                    HSerPrint ": "
                 End If
                 HSerPrint " "
                 HI2CStart
                 If HI2CWaitMSSPTimeout <> TRUE Then
                    HI2CSend ( deviceID )
                    If HI2CAckPollState = FALSE Then
                       HSerPrint   hex(deviceID)
                    Else
                       HSerPrint "--"
                    End If
                    HI2CSend ( 0)
                 End If
                 HI2CStop
              Next
      '-
              HSerPrintCrLf 2
              HSerPrint   "End of Search"
              HSerPrintCrLf 2
              Wait 1 s
              End
      '-
      '-
      '-
      Sub InitPPS
      'Module: I2C1
      'Module: MSSP1
      'Module: EUSART1
              RC6PPS = 0x0009    'TX1 > RC6
              RX1PPS = 0x0017    'RC7 > RX1
      'Module: MSSP1
              SSP1DATPPS = 0x0014    'RC4 > SDA1
              RC4PPS = 0x0010    'SDA1 > RC4 (bi-directional)
              RC3PPS = 0x000F    'SCL1 > RC3
              SSP1CLKPPS = 0x0013    'RC3 > SCL1 (bi-directional)
      
      'Module: I2C1 extra settings
      '       This is a dedicated PIC I2C module
      '       The clock speed is 125kHz by default (not 100kHz/400kHz)
      '       See the HWI2C section of the Help, or refer to the chip specific datasheet,  for how to change the clock speed to the desired frequency
              #Define HI2C_DATA PORTC.4    'Define a constant
              Dir HI2C_DATA Out    'Set I2C pin As Output
      '       RC4I2C_TH0=1    'Set the I2C level for the pin
              ODCC4=1    'Set pin As open drain Output
              #Define HI2C_CLOCK PORTC.3    'Define a constant
              Dir HI2C_CLOCK in    'Set I2C pin As Output
      '       RC3I2C_TH0=1    'Set the I2C level for the pin
              ODCC3=1    'Set pin As open drain Output
              Dir PORTC.6 in    ' Make TX1 pin an Output
      End Sub
      
       
  • Anobium

    Anobium - 2021-06-19

    You have mixed up the pps from two totally different chips.

    Go back to the firsr code you posted and add hi2cmode master.

     
  • Anobium

    Anobium - 2021-06-19

    I cannot test, but, this your code. WIth the bits I mentioned sorted.

     
  • Anobium

    Anobium - 2021-06-19

    I assumed you have the original PPS correct but you had SDA and SCL and it should be SDA and SCK.

    I may not have the ports correct.

    Evan

    'Generated by PIC PPS Tool for Great Cow Basic
    'PPS Tool version: 0.0.6.2
    'PinManager data: v1.81.0
    'Generated for 18f47k40
    '
    'Template comment at the start of the config file
    '
    #startup InitPPS, 85
    #define PPSToolPart 18f47k40
    
    Sub InitPPS
    
            'Module: MSSP1
            RC4PPS = 0x0010    'SDA1 > RC4
            SSP1DATPPS = 0x0014    'RC4 > SDA1 (bi-directional)
            SSP1CLKPPS = 0x0013    'RC3 > SCK1
            RC3PPS = 0x000F    'SCK1 > RC3 (bi-directional)
    
    End Sub
    'Template comment at the end of the config file
    
     
  • Anobium

    Anobium - 2021-06-20

    I have taken your program first posted

    Change the PPS, commented out the LCD debug, added the missing DIR and HI2Cmode and most importantly sorted the PPS.

    Works

    Hardware I2C - I have a I2C display connected on addresses 0x78 and 0x79

       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
    00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    10 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70 -- -- -- -- -- -- -- -- 78 79 -- -- -- -- -- --
    80 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    90 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    A0 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    B0 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    C0 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    D0 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    E0 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    F0 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    
    End of Search
    
     
    • jackjames

      jackjames - 2021-06-20

      Hi Evan.
      Thank you so much for the help you gave me, very important.
      A question:
      The micro has two serial ports. Is it possible to access both simultaneously in order to read data from one and, after processing, send them with the other port ?

      Thanks

       
  • Anobium

    Anobium - 2021-06-20

    Yes.

    Use a serial ring buffer one for each serial port, then, send the buffer out on the opposite port. Very simple to implement.

    See the help for the one port implementation. You will need to expand the solution to cover two ports but this is easily doable.

     
    • Anobium

      Anobium - 2021-06-20

      I assumed the ports where bi-directional.

      USART 1 RX > USART 2 TX
      USART 2 RX > USART 1 TX

      So, you (as I wrote) need two buffers driven by the interrupts. When some arrives it gets sent out. YOU CANNOT use one buffer.

      Take the existing Help example code. Adapt all the constants and variables to manage one port. So, rename everything... this is a little example

      Sub readUSART_USART1
      
          buffer_USART1(next_in_USART1) = HSerReceive ( 1 )
          temppnt_USART1 = next_in_USART1
          next_in_USART1 = ( next_in_USART1 + 1 ) % BUFFER_SIZE
          If ( next_in_USART1 = next_out_USART1 ) Then  ' buffer is full!!
              next_in_USART1 = temppnt_USART1
          End If
      
      End Sub
      

      I would convert the existing code using ONE USART (so, it does the loop back as per the Help example) and ONLY when you have the working with all the new constants and variables then expand to USART2. (this is a little piece converted )

      Sub readUSART_USART2
      
          buffer_USART2(next_in_USART2) = HSerReceive ( 2 )
          temppnt_USART2 = next_in_USART2
          next_in_USART2 = ( next_in_USART2 + 1 ) % BUFFER_SIZE
          If ( next_in_USART2 = next_out_USART2 ) Then  ' buffer is full!!
              next_in_USART2 = temppnt_USART2
          End If
      
      End Sub
      
       
      • jackjames

        jackjames - 2021-06-20

        Thank you.
        Now I play with it a little ...

         
        • Anobium

          Anobium - 2021-06-20

          What are you trying to with the serial stuff? You may be able to do this using CLC... essentially, signal in to signal out with zero cpu usage. It all depends on what you are trying to do.

           
          • jackjames

            jackjames - 2021-06-20

            I want to modernize the home automation unit I have in the house by the sea.
            The control unit communicates in RF with various peripherals, from the sectoral irrigation system, to the various thermostats located in each room, to lighting control, opening gates, weather stations, etc.
            All can be controlled remotely by GSM.
            I actually use three serial ports: two hardware and one software. The hardware ports are connected to the GSM modem and the other to the TX that I use to communicate with the peripherals.
            I use the software serial port to communicate with a PIC12F1840 that decodes the signals coming from the various remote controls.

             
            • Anobium

              Anobium - 2021-06-20

              The buffer should work for you, but, if the incoming messages are formatted/structured , or CR/LF terminated then you may be able to use HSerGetString()

               
              • jackjames

                jackjames - 2021-06-20

                Actually I have to read all values from 0 to 255, so I read and parse each byte.
                The protocol is the one developed years ago and which is recognized by all installed devices.
                The message with the commands to be executed normally consists of a preamble of three bytes, a command of twelve bytes followed by the CRC.

                 
                • Anobium

                  Anobium - 2021-06-20

                  Sounds good.

                   

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.