PIC18F47K42 I2C NEW LIBRARY

Beta Testing discussion on mikroBasic PRO for PIC.
Post Reply
Author
Message
MiguelV
Posts: 12
Joined: 25 Jan 2019 02:02

PIC18F47K42 I2C NEW LIBRARY

#1 Post by MiguelV » 19 Feb 2019 14:54

Could someone give me an example of how to use the new library for the PIC family K42?, i haven't been able to run the I2C1.

User avatar
filip.grujcic
Posts: 822
Joined: 14 May 2018 08:34

Re: PIC18F47K42 I2C NEW LIBRARY

#2 Post by filip.grujcic » 20 Feb 2019 10:35

Hello,

Could you take a look at this post?
viewtopic.php?f=85&p=296907#p296907

If you have further questions you can ask here.

Regards,
Filip Grujcic

Dogfighter
Posts: 3
Joined: 11 Apr 2013 22:20

Re: PIC18F47K42 I2C NEW LIBRARY

#3 Post by Dogfighter » 12 Jun 2019 09:14

Hello Filip,

I'm just trying to get from 18F45K22 to 18F27K42. Unfortunately I have a problem with the I2C routines under mikrobasic. The article viewtopic.php? F = 85 & p = 296907 # p296907 I have looked at and implemented in mikrobasic. When I compile I get in the line 165 when calling the function "I2C1_Remappable_Wr"
the error 327 (complex type to simple type)
and Note 1512 (Warning: Implicit typecast of integral value to pointer).

Unfortunately I have not found an example for I2C under mikrobasic yet ...

Enclosed the code

Yours sincerely
Manfred

Code: Select all

program cricular_ring_buffer

' Declarations section 

dim            tmp_byte,counter as word
dim            a_wert, Pulse_50ms, u1rx_flag as bit
dim            u1rxbuff as char[255]
dim            u1rxidx, u1rxlen as char
dim            u1rxdata, txt, txt_sub ,txt_tmp as char[20]
dim            tmp as byte[20]
dim            TMR_edge, TMR_flag as byte
dim            u1_ser_buff_in as char[512]
dim            u1_write_buffer_pointer, u1_read_buffer_pointer, count as word
dim            u1_read_buffer_pointer_save as word
'******************************************************************************
'Timer0
'Prescaler 1:64; TMR0 Preload = 15536; Actual Interrupt Time : 50 ms
sub procedure InitTimer0()
'******************************************************************************
  T0CON1        = %01100110          'TMR0 configuration
  T0CON0        = %10010000          'TMR0 configuration
  TMR0H         = 0x3C               'TMR0 high byte 0x3C
  TMR0L         = 0xB0               'TMR0 low byte 0xB0
  GIE_bit       = 0                  'disable global interrupts
  TMR0IE_bit    = 1                  'enable TMR0 interrupt
end sub
'******************************************************************************
'******************************************************************************
sub procedure u1_init()
'******************************************************************************
    u1_write_buffer_pointer = 0
    u1_read_buffer_pointer  = 0
    u1_read_buffer_pointer_save  = 0
    for count = 0 to 511
     u1_ser_buff_in[count] = 0
    next count
    u1rxdata = ""
end sub
'******************************************************************************


'******************************************************************************
sub procedure u1_ser_in()
'******************************************************************************
'get character from uart1 circular buffer
'******************************************************************************
  count = 0
  u1_read_buffer_pointer_save = u1_read_buffer_pointer
  
  do                                 'read next character from circular buffer
  txt_tmp[count] = u1_ser_buff_in[u1_read_buffer_pointer]
  Inc(u1_read_buffer_pointer)        'increment read data pointer
  if u1_read_buffer_pointer > 511    'if pointer past end of buffer
     then
     u1_read_buffer_pointer = 0      'reset pointer
  end if
  if (txt_tmp[count] = 0x0D)         'check since data is 0x0D (CR)
     then
     txt_tmp[count] = 0x00           'set last byte as 0 for string end
     u1rxdata =  txt_tmp
     goto M999
  end if
  Inc(count)                         'incerment data pointer
                                     'repeat since pointer equal
  loop until u1_read_buffer_pointer = u1_write_buffer_pointer
  u1_read_buffer_pointer = u1_read_buffer_pointer_save

M999: NOP
end sub

'******************************************************************************
sub procedure interrupt()
'******************************************************************************
  GIE_bit   = 0                    '' Disable GLOBAL interrupts
'******************************************************************************
' TMR0 Interrupt 50ms
   if (TMR0IF_bit) then              'check TMR0IF flag
    TMR0IF_bit = 0                   'clear TMR0IF flag
    TMR0H         = 0x3C             'TMR0 high byte 0x3C
    TMR0L         = 0xB0             'TMR0 low byte 0xB0
    Pulse_50ms = NOT Pulse_50ms      'swap Pulse_50ms flag
    LATB.0 = NOT LATB.0              'tmr0 time for test / oscilloscope
  end if
'******************************************************************************
'******************************************************************************
' Interrupt Receive UART 1
'******************************************************************************
   if(U1RXIF_bit = 1) then           'Checks for Receive Interrupt Flag bit
     LATB.1 = NOT LATB.1             'for test / oscilloscope
     u1_ser_buff_in[u1_write_buffer_pointer] = UART1_Remappable_Read()
                                     'put received chart in circular buffer

     Inc(u1_write_buffer_pointer)    'increment write data pointer
     if u1_write_buffer_pointer > 511'if pointer past end of buffer
        then
        u1_write_buffer_pointer = 0  'reset pointer
     end if
   end if
'******************************************************************************
  GIE_bit   = 1                     ' Enable GLOBAL interrupts
end sub
'******************************************************************************
main:
'   Main program


'******************************************************************************
'clock speed 64 MHz internal
     OSCCON1 = %01100000
'******************************************************************************

     'u1rxidx  = 0                  ' Initialisation of variable
     'u1rxdata = ""
     'u1rxbuff =""
     u1_init()
     counter = 0
     PORTA = %00000000              'set PORT REGISTER A
     PORTB = %00000000              'set PORT REGISTER B
     PORTC = %00000000              'set PORT REGISTER C
     LATA  = %00000000              'set LATCH REGISTER A
     LATB  = %00000000              'set LATCH REGISTER B
     LATC  = %00000000              'set LATCH REGISTER C
     ANSELA = %00000000             'set ANALOG SELECT REGISTER A
     ANSELB = %00000000             'set ANALOG SELECT REGISTER B
     ANSELC = %00000000             'set ANALOG SELECT REGISTER C
     TRISA = %00000000              'set TRI-STATE CONTROL REGISTER A
     TRISB = %00000000              'set TRI-STATE CONTROL REGISTER B
     TRISC = %01000000              'set TRI-STATE CONTROL REGISTER C
 '*****************************************************************************
     InitTimer0()                   ' interrupt timer 0 50ms
     
     
 '*****************************************************************************
     Unlock_IOLOCK()
     PPS_Mapping_NoLock(_RC7, _INPUT, _RX1)
     ' Sets pin RC7 to be Input, and maps RX1 Input to it
     PPS_Mapping_NoLock(_RC6, _OUTPUT, _TX1PPS)
     ' Sets pin RC6 to be Output, and maps TX1PPS Output to it
     'PPS_Mapping_NoLock(_RB7, _INPUT, _RX2)
     ' Sets pin RB7 to be Input, and maps RX2 Input to it
     PPS_Mapping_NoLock(_RB7, _OUTPUT, _TX2PPS)
     ' Sets pin RB6 to be Output, and maps TX2PPS Output to it
     PPS_Mapping_NoLock(_RC3, _OUTPUT, _SCL1_out)
     ' Sets pin RC3 to be Output, and maps SCL1 Output to it
     PPS_Mapping_NoLock(_RC4, _OUTPUT, _SDA1_in)
     ' Sets pin RC4 to be Output, and maps SDA1 Output to it
     Lock_IOLOCK()
 '*****************************************************************************
     ODCC3_bit = 1                  'OPEN-DRAIN CONTROL REGISTER PORTC.3
     ODCC4_bit = 1                  'OPEN-DRAIN CONTROL REGISTER PORTC.4
'******************************************************************************

     UART1_Remappable_Init(115200)
     Delay_100ms
'******************************************************************************
     UART2_Remappable_Init(115200)
     Delay_100ms
'******************************************************************************
     UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
     UART1_Remappable_Write_Text("Schneider Programming Service 2019")
     UART1_Remappable_Write(13)
 '*****************************************************************************
     I2C1_Remappable_Init()
       tmp[0] = 0x10
       I2C1_Remappable_Wr( 0x41, tmp, 1, _I2C_END_MODE_RESTART)
       'I2C1_Rd( 0x41, tmp, 3, _I2C_END_MODE_STOP )


'******************************************************************************
'Interrupt init
     INTCON0 = %00000000
     'U1RXIF_bit = 0                  'reset U1RXIF flag not possible see page 140
     U1RXIE_bit = 1                   'enable U1RXIE interrupt
     U1RXIP_bit = 1                   'UART1 Receive Interrupt Priority high
     GIE_bit   = 1                    ' Enable GLOBAL interrupts
'******************************************************************************
'Loop
     while true
      PORTB.B5 = NOT PORTB.B5         'cycle time for test / oscilloscope
      'positive edge evaluation Timer 0 only for one cycle
      TMR_edge.B0 = Pulse_50ms AND NOT TMR_flag.B0
      TMR_flag.B0 = Pulse_50ms
'******************************************************************************
      if TMR_edge.B0
         then inc(counter)            '100ms counter
      end if
'******************************************************************************
      if (counter >= 10)
         then
             PORTA = NOT PORTA
             counter = 0
      end if
'******************************************************************************
      if u1_read_buffer_pointer <> u1_write_buffer_pointer
         then
'test output data for ring buffer
          'UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
          'WordToStr(u1_read_buffer_pointer, txt_sub)
          'UART1_Remappable_Write_Text("read pointer 1 = " + txt_sub + ", ")
          'WordToStr(u1_write_buffer_pointer, txt_sub)
          'UART1_Remappable_Write_Text("write pointer 1 = " + txt_sub)
          'UART1_Remappable_Write(13)
          u1_ser_in()                'extract serial data from ring buffer
'test output data for ring buffer
          'ByteToStr(u1_read_buffer_pointer, txt_sub)
          'UART1_Remappable_Write_Text("read pointer 2 = " + txt_sub + ", ")
          'ByteToStr(u1_write_buffer_pointer, txt_sub)
          'UART1_Remappable_Write_Text("write pointer 2 = " + txt_sub)
          'UART1_Remappable_Write(13)
          'u1rx_flag = 0
      end if
'******************************************************************************
      u1rxlen = strlen(u1rxdata)     'check of serial data from u1_ser_in()
      if u1rxlen > 0
         then                        'echo data for test
          UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
          UART1_Remappable_Write_Text("echo " + u1rxdata)
          UART1_Remappable_Write(13)
          u1rxdata = ""              'clear string
      end if
'******************************************************************************
      'UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
      'UART1_Remappable_Write_Text("Step 1")
      'UART1_Write(13)
      'UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle)
      'UART2_Remappable_Write_Text("UART 2 Step 1")
      'UART2_Write(13)

      

      'PORTB = %00000000
      'PORTC = %01010101
      'UART1_Write_Text("Step 2")
      'UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
      'UART1_Remappable_Write_Text("Step 2")
      'UART1_Remappable_Write(13)
      'UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle)
      'UART2_Remappable_Write_Text("UART 2 Step 2")
      'UART2_Remappable_Write(13)
      'UART1_Write(13)
      

     
     
     wend
     
 
end.
Attachments
circular_ring_buffer.zip
(63.53 KiB) Downloaded 125 times

User avatar
filip.grujcic
Posts: 822
Joined: 14 May 2018 08:34

Re: PIC18F47K42 I2C NEW LIBRARY

#4 Post by filip.grujcic » 13 Jun 2019 09:00

Hello,

Just pass a pointer to tmp instead of tmp itself and it will compile.

Your write/read functions should look like this:
I2C1_Wr( 0x41, @tmp, 1, _I2C_END_MODE_RESTART )

I2C1_Wr and I2C1_Remappable_Wr are the same, so it doesn't matter which one you use.

Init function is the only one where it matters whether you use the Remappable version of it or not. Remappable version doesn't do the necessary pin mapping for you, so you need to do it manually before calling this function.

Let me know if you have any other questions.

Kind regards,
Filip Grujcic

Dogfighter
Posts: 3
Joined: 11 Apr 2013 22:20

Re: PIC18F47K42 I2C NEW LIBRARY

#5 Post by Dogfighter » 13 Jun 2019 09:13

Hello Filip,

Thank you for the info.
I have not worked much with pointers yet. :-(
Then I will continue and test.
SPI is also on the "to do" list.

Yours sincerely

Manfred

P.S. Please ignore this morning's post in this thread. I thought the first post had not arrived. Sorry.

User avatar
filip.grujcic
Posts: 822
Joined: 14 May 2018 08:34

Re: PIC18F47K42 I2C NEW LIBRARY

#6 Post by filip.grujcic » 13 Jun 2019 09:47

Hi,

No problem.
I2C library for K42/K83 is really the only library that's drastically different from what you might be used to on other PIC18.

SPI library shouldn't give you any trouble, but if you come across any issues, don't hesitate to post them here and we'll do our best to try and help out.

Kind regards,
Filip Grujcic

Dogfighter
Posts: 3
Joined: 11 Apr 2013 22:20

Re: PIC18F47K42 I2C NEW LIBRARY

#7 Post by Dogfighter » 14 Jun 2019 10:12

Hello Filip,

after I'm almost maddened with the I2C features it works now!
But there have been questions again.

Since my main loop in my example is very fast, I always had I2C timeouts when reading the 24C08 on the EaysPIC V7.

after I read the 24C08 about my TMR0 interrupt every 100ms (positive edge) everything is OK and no timeouts!
Questions:
Thus, I can only start reading the 24C08 again when the previous reading is done?
Is there a flag indicating the end of the I2C read (I2C_rd bussy or ready)?
The frequency of the I2C bus is fixed at 100KHz (in the future ....)?
If I write my own routine for the frequency, e.g. 400KHz then run the WR / RD functions?

See you

Manfred

User avatar
filip.grujcic
Posts: 822
Joined: 14 May 2018 08:34

Re: PIC18F47K42 I2C NEW LIBRARY

#8 Post by filip.grujcic » 17 Jun 2019 09:30

Hello,

-Yes, you have to let the read finish before starting another one.
-There are no flags in the library, if that's what you mean.
-Currently the frequency is fixed at 100KHz in the library, yes.
I believe 24C08 only supports 100KHz, you should check the datasheet for more information.

Kind regards,
Filip Grujcic

Post Reply

Return to “mikroBasic PRO for PIC Beta Testing”