News:

;) This forum is the property of Proton software developers

Main Menu

I2C Speed

Started by tolyan249, Today at 03:50 AM

Previous topic - Next topic

tolyan249

---------------------------------------------------------   
   
Device =  16F628A 
Xtal = 20   
 
     
   
   
'-------------------------- --------------------------------
                                                                   
Declare  SHOW_SYSTEM_VARIABLES = OFF 
Declare  FSR_CONTEXT_SAVE = OFF 
Declare  Reminders = OFF   
Declare  Warnings = OFF   
Declare  Optimiser_Level 0   
Declare  Bootloader = OFF 
                                                                   
;--------------------------------------------------------------

Declare PortB_Pullups = OFF 
Declare  All_Digital = On   
                                                                   
'-------------------------- ------------------------
                                                                   
Declare  LCD_Type ALPHA   
Declare  LCD_DTPin  PORTB.0   
Declare  LCD_ENPin  PORTB.5   
Declare  LCD_RSPin  PORTB.4
Declare  LCD_Interface  4   
Declare  LCD_CommandUs  2000   
Declare  LCD_DataUs  50 
Declare  LCD_Lines   2 

   
   
Declare   Slow_Bus  OFF 
Declare   BUS_SCL   OFF   
Declare   BUS_SDA   OFF
Declare   bus_Bitrate 400    '100kHz, 400kHz, 1000kHz  I2C_SPEED_FAST  ;

Dim as n byte
dim v as bit

loop
    BStart
v=1
     I2COut SDA,SCL,n,[0]
    If   BusAck=0 Then  v=0 
    BStop
delayms 500
goto loop

I use I2cOut and I2CIN, the speed is always 100KHz, I can't change this speed, what could be the problem, where should I look?
Thank you.

Is there a description of the I2C library somewhere, or a library file that proton ide uses?

I measure it with an oscilloscope, and the pulse width is 10ms, which should be 2.5ms at 400kHz. Nothing changes when I change Hbus_Bitrate to 400.
BusAck doesn't work either, and there's no confirmation.

Dompie

The program shown above has several errors, so there's no result, and the Positron compiler didn't create a HEX. Therefore, a PIC cannot be programmed. Therefore, you couldn't have measured any results with this program. I think you were using a product other than Positron.

Johan

top204

Is this yet another chatGPT code listing?

Stephen Moss

Quote from: tolyan249 on Today at 03:50 AMI measure it with an oscilloscope, and the pulse width is 10ms, which should be 2.5ms at 400kHz. Nothing changes when I change Hbus_Bitrate to 400.
BusAck doesn't work either, and there's no confirmation.
If you are using Positron then I suggest you read page 152-156 of the manual as some of your declares are not using the correct names or exist at all.

I2Cout & I2Cin are for using a software (bit-bashed) I2C bus, I could be wrong but don't think you can change the speed, it is fixed in the command to the most commonly use speed. If you want to have more flexibility over the transmission speed then you will probably need to use the PICs hardware communications module (typically called MSSP) and configure the relevant register values to get the input/output you want.

The H in HBus_Bitrate (and other peripheral/comms commands) refers to using Hardware (usually the PICs MSSP peripheral module) to transmit/receive data, therefore using it will have no affect on the transmission speed of the software based I2Cin & I2Cout commands. Again, read the manual and ensure you are not mixing up software and hardware based commands I2C commands.

Quote from: top204 on Today at 12:21 PMIs this yet another chatGPT code listing?
Not sure, but I was thinking it looks like something AI would spit out.

tolyan249

#4
I have the PROTON IDE 3.5 compiler

I'm attaching the program along with Proteus, and I've implemented my own I2C, as I couldn't find any descriptions for I2CIN and I2COUT


sendTM_Config:
  If COM_ADDR=0 Then Return
 
;=================================
GoSub I2C_Start2 
    countBUFW=1 
    Command_Byte=2
    GoSub Write_PMBusParam 
    BUF_W
  • = 29
    Command_Byte=2
    GoSub Write_PMBusParam
    BUF_W
  • = 32
    GoSub Write_PMBusParam 
       
GoSub I2C_Stop2
;================================
 Return

The program scans the addresses, finds them, and displays the temperature. If I write to the sensor's registers, the sensor responds to the temperature I set, and the LED on the sensor lights up and goes out when the temperature is set in the registers. However, for some reason, the sensor's temperature is not displayed, and instead, the temperature I set is constantly read from the sensor. I cannot understand the issu.




Dompie

We're now living 14-15 years later, so a lot has changed. I recommend buying a new Positron compiler.
Proton no longer exists, and I'm guessing the Proton version you use, is 3.5.2.7. The Installation.txt file shows November 15, 2011!
The contents of this Installation.txt file:
Proton Development Suite 3.5.2.7
Download Link:
Compiler V3.5.2.7: http://www.compile-it.com/pdsbeta/PDS/Version%203_5_2_7/Proton%20Compiler%20Setup%203.5.2.7%20-%20Win7%20%2832-bit%29.exe
Patch : http://www.mediafire.com/file/6ovav13ndeg11v7/XP%203.5.2.7.zip

Installation
•Install the Compiler and replace ProtonIDE.exe and PrPlus.exe with cracked version.
•Now you have an up-to-date full working version
 
« Last Edit: November 15, 2011, 05:15:42 17:15 by Ahmad_k » 
 

I (and many other forum members) would be happy to help you if you have a recent Positron version.

Johan

top204

Creating a software (bit-bashed) I2C interface in Positron is relatively straightforward, as the code listing below illustrates. It is a library that implements all the elements of I2C, and can be slowed down or speeded up by changing values in the delays between pin toggles. :-)

$ifndef _I2C_SOFTWARE_INC_
$define _I2C_SOFTWARE_INC_
'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' I2C_Software.inc
' Software I2C writing and reading routines.
' Written for the Positron8 BASIC compiler by Les Johnson.
'
' Setup the default pins for SDA and SCL
'
$ifndef I2C_SDA_Pin
    $define I2C_SDA_Pin PORTC.4
    $SendWarning "$define I2C_SDA_Pin missing from main program, so using the default pin of PORTC.4"
$endif

$ifndef I2C_SCL_Pin
    $define I2C_SCL_Pin PORTC.3
    $SendWarning "$define I2C_SCL_Pin missing from main program, so using the default pin of PORTC.3"
$endif

'----------------------------------------------------------------------------------------------
' Delay a fixed number of microseconds and clock cycles
'
$define I2C_hDelayUs() DelayUS 3                        ' Delay a number of microseconds
$define I2C_hDelayCs() DelayCs 1                        ' Delay a number of clock cycles

'----------------------------------------------------------------------------------------------
' Send a single byte to the I2C bus
' Input     : pData holds the byte to write
' Output    : None
' Notes     : MSB first
'
Proc I2C_WriteByte(pData As Byte)
    Dim bIndex As Byte

    For bIndex = 7 Downto 0                             ' Create a loop for the 8-bits
        If pData.7 = 1 Then
            PinInput I2C_SDA_Pin                        ' Make the SDA pin an Input (High)
        Else
            PinOutput I2C_SDA_Pin                       ' Make the SDA pin an Output (Low)
        EndIf
        I2C_hDelayUs()
        PinInput I2C_SCL_Pin                            ' Make the SCL pin an Input (High)
        I2C_hDelayUs()
        PinOutput I2C_SCL_Pin                           ' Make the SCL pin an Output
        I2C_hDelayUs()
        pData = pData << 1
    Next
'
' Close up
'
    PinInput I2C_SDA_Pin                                ' Make the SDA pin an Input (High)
    PinInput I2C_SCL_Pin                                ' Make the SCL pin an Input (High)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinOutput I2C_SCL_Pin                               ' Make the SCL pin an Output
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
EndProc

'----------------------------------------------------------------------------------------------
' Read a single byte from the I2C bus
' Input     : None
' Output    : Returns the byte received
' Notes     : MSB first, sample before clock
'
Proc I2C_ReadByte(), Byte
    Dim bIndex   As Byte
    Dim wTimeOut As Word

    Result = 0
    PinInput I2C_SDA_Pin                                ' Make the SDA pin an Input (High)
    For bIndex = 7 Downto 0                             ' Create a loop for the 8-bits
        Result = Result << 1
        '
        ' Wait for any clock stretching
        '
        wTimeOut = $FFFF
        Repeat                                          ' Create a loop
            PinInput I2C_SCL_Pin                        ' Make the SCL pin an Input
            Dec wTimeOut                                ' \
            If wTimeOut = 0 Then Break                  ' / Exit the loop if the timeout reaches 0
        Until I2C_SCL_Pin = 1                           ' Until the SCL pin is high
        '
        ' Read the data
        '
        I2C_hDelayUs()
        Result.0 = I2C_SDA_Pin
        PinOutput I2C_SCL_Pin                           ' Make the SCL pin an Output (Low)
        I2C_hDelayUs()
    Next
EndProc

'----------------------------------------------------------------------------------------------
' Send an I2C bus Start condition
' Input     : None
' Output    : None
' Notes     : A Start condition is high to low of SDA when SCL is high
'
Proc I2C_Start()
    PinInput I2C_SDA_Pin                                ' Make the SDA pin an Input (High)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinInput I2C_SCL_Pin                                ' Make the SCL pin an Input (High)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinOutput I2C_SDA_Pin                               ' Make the SDA pin an Output (Low)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinOutput I2C_SCL_Pin                               ' Make the SCL pin an Output (Low)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
EndProc

'----------------------------------------------------------------------------------------------
' Send an I2C bus restart condition
' Input     : None
' Output    : None
' Notes     : None
'
$define I2C_ReStart() I2C_Start()

'----------------------------------------------------------------------------------------------
' Send an I2C bus Stop condition
' Input     : None
' Output    : None
' Notes     : A Stop condition is low to high of SDA when SCL is high
'
Proc I2C_Stop()
    PinOutput I2C_SDA_Pin                               ' Make the SDA pin an Output (Low)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinInput I2C_SCL_Pin                                ' Make the SCL pin an Input (High)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinInput I2C_SDA_Pin                                ' Make the SDA pin an Input (High)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
EndProc

'----------------------------------------------------------------------------------------------
' Initiate an I2C Acknowledge
' Input     : None
' Output    : None
' Notes     : None
'
Proc I2C_Ack()
    I2C_hDelayCs()
    PinOutput I2C_SDA_Pin                               ' Make the SDA pin an Output (Low)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinInput I2C_SCL_Pin                                ' Make the SCL pin an Input (High)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinOutput I2C_SCL_Pin                               ' Make the SCL pin an Output (Low)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinInput I2C_SDA_Pin                                ' Make the SDA pin an Input (High)
EndProc

'----------------------------------------------------------------------------------------------
' Initiate an I2C Not Acknowledge
' Input     : None
' Output    : None
' Notes     : None
'
Proc I2C_NAck()
    PinInput I2C_SDA_Pin                                ' Make the SDA pin an Input (High)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinInput I2C_SCL_Pin                                ' Make the SCL pin an Input (High)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinOutput I2C_SCL_Pin                               ' Make the SCL pin an Output (Low)
    I2C_hDelayCs()                                      ' Delay a few clock cycles between pin state changes
    PinInput I2C_SDA_Pin                                ' Make the SDA pin an Input (High)
EndProc

'----------------------------------------------------------------------------------------------
' Setup the SDA and SCL pins for the software I2C interface
' Input     : None
' Output    : None
' Notes     : None
'
Proc I2C_SetupPins()
    PinOutput I2C_SDA_Pin                               ' Make the I2C SDA pin an output
    PinOutput I2C_SCL_Pin                               ' Make the I2C SCL pin an output
EndProc

'----------------------------------------------------------------------------------------------
' Startup section
'
_I2C_Main_:
    I2C_SetupPins()                                     ' Setup the SDA and SCL pins for the software I2C interface

$endif      ' _I2C_SOFTWARE_INC_

A demo program that uses the above library is listed below:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Write and read an I2C EEPROM using the software I2C library routines
' Written for the Positron8 BASIC compiler by Les Johnson
'
    Device = 18F25K22                           ' Tell the compiler what device to compile for
    Declare Xtal = 64                           ' Tell the compiler what frequency the device is operating at (in MHz)
'
' Setup the pins to use for the I2C interface
'
$define I2C_SDA_Pin PORTC.4                     ' Set the SDA pin for the I2C library
$define I2C_SCL_Pin PORTC.3                     ' Set the SCL pin for the I2C library

    Include "I2C_Software.inc"                  ' Load the software I2C library routines
'
' Create variables for the demo
'
    Dim bAddress As Byte
    Dim ByteIn   As Byte
    Dim ByteOut  As Byte

'---------------------------------------------------------------------------------------------
Main:
'
' Write bytes to the I2C EEPROM
'
    I2C_Start()                                 ' Send a Start condition
    I2C_WriteByte(%10100000)                    ' Target an EEPROM, and send a Write command
    I2C_WriteByte(0)                            ' Send the High Byte of the address
    I2C_WriteByte(0)                            ' Send the Low Byte of the address
    For ByteIn = 0 To 9                         ' Create a loop
        I2C_WriteByte(ByteIn)                   ' Send the value of ByteIn to the EEPROM
    Next                                        ' Close the loop
    I2C_Stop()                                  ' Send a Stop condition
    DelayMS 5                                   ' Wait for the data to be entered into the EEPROM matrix
'
' Read bytes from the I2C EEPROM and display them on a serial terminal
'
    I2C_Start()                                 ' Send a Start condition
    I2C_WriteByte(%10100000)                    ' Target an EEPROM, and send a Write command
    I2C_WriteByte(0)                            ' Send the High Byte of the address
    I2C_WriteByte(0)                            ' Send the Low Byte of the address
    I2C_ReStart()                               ' Send a Restart condition
    I2C_WriteByte(%10100001)                    ' Target an EEPROM, and send a Read command
    For bAddress = 0 To 9                       ' Create a loop
        ByteOut = I2C_ReadByte()                ' Load ByteOut with the byte received
        If bAddress = 9 Then                    ' Are we at the end of the reads?
            I2C_Stop()                          ' Yes. So send a Stop command
        Else                                    ' Otherwise...
            I2C_Ack()                           ' Send an Ack command
        EndIf
        HRSOutLn Dec ByteOut                    ' Display ByteOut on the serial terminal
    Next                                        ' Close the loop
    HRsout 13

'------------------------------------------------------------------------------
' Setup the config fuses for a PIC18F25K22 device to operate with an external crystal with the 4xPLL enabled
'
Config_Start
    FOSC     = HSHP                             ' HS oscillator (high power > 16 MHz)
    PLLCFG   = On                               ' Oscillator multiplied by 4
    PRICLKEN = On                               ' Primary clock enabled
    FCMEN    = Off                              ' Fail-Safe Clock Monitor disabled
    IESO     = Off                              ' Internal/External Oscillator Switchover mode disabled
    PWRTEN   = On                               ' Power up timer enabled
    BOREN    = SBORDIS                          ' Brown-out Reset enabled in hardware only (SBOREN is disabled)
    BORV     = 190                              ' Brown Out Reset Voltage set to 1.90 V nominal
    WDTEN    = Off                              ' Watch dog timer is always disabled. SWDTEN has no effect.
    WDTPS    = 128                              ' Watchdog Timer Postscale 1:128
    CCP2MX   = PORTC1                           ' CCP2 input/output is multiplexed with RC1
    PBADEN   = Off                              ' PORTB<5:0> pins are configured as digital I/O on Reset
    CCP3MX   = PORTB5                           ' P3A/CCP3 input/output is multiplexed with RB5
    HFOFST   = On                               ' HFINTOSC output and ready status are not delayed by the oscillator stable status
    T3CMX    = PORTC0                           ' Timer3 Clock Input (T3CKI) is on RC0
    P2BMX    = PORTB5                           ' ECCP2 B (P2B) is on RB5
    MCLRE    = EXTMCLR                          ' MCLR pin enabled, RE3 input pin disabled
    STVREN   = Off                              ' Stack full/underflow will not cause Reset
    LVP      = Off                              ' Single-Supply ICSP disabled
    XINST    = Off                              ' Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
    Debug    = Off                              ' Debug disabled
    Cp0      = Off                              ' Block 0 (000800-001FFF) not code-protected
    CP1      = Off                              ' Block 1 (002000-003FFF) not code-protected
    CP2      = Off                              ' Block 2 (004000-005FFF) not code-protected
    CP3      = Off                              ' Block 3 (006000-007FFF) not code-protected
    CPB      = Off                              ' Boot block (000000-0007FF) not code-protected
    CPD      = Off                              ' Data EEPROM not code-protected
    WRT0     = Off                              ' Block 0 (000800-001FFF) not write-protected
    WRT1     = Off                              ' Block 1 (002000-003FFF) not write-protected
    WRT2     = Off                              ' Block 2 (004000-005FFF) not write-protected
    WRT3     = Off                              ' Block 3 (006000-007FFF) not write-protected
    WRTC     = Off                              ' Configuration registers (300000-3000FF) not write-protected
    WRTB     = Off                              ' Boot Block (000000-0007FF) not write-protected
    WRTD     = Off                              ' Data EEPROM not write-protected
    EBTR0    = Off                              ' Block 0 (000800-001FFF) not protected from table reads executed in other blocks
    EBTR1    = Off                              ' Block 1 (002000-003FFF) not protected from table reads executed in other blocks
    EBTR2    = Off                              ' Block 2 (004000-005FFF) not protected from table reads executed in other blocks
    EBTR3    = Off                              ' Block 3 (006000-007FFF) not protected from table reads executed in other blocks
    EBTRB    = Off                              ' Boot Block (000000-0007FF) not protected from table reads executed in other blocks
Config_End