I2C Baud Rate + # Define statement

Discussion in 'Programmer's Corner' started by Tobytyke, Oct 16, 2014.

  1. Tobytyke

    Thread Starter New Member

    Oct 20, 2013
    Hi All

    I have been working on a project for some time but due to time constraints have not had time to pursue for some months

    My project involves sending data too and from a Master / Slave using two PICS

    But for the time being I found a nice write up on the web to send a piece of data to an EPROM, read it back and then light 8 LEDS on the PIC

    The code uses a PIC16F877 (which I have not currently got)

    I do have several 16F887's with internal clock

    So I decided to modify the code to fit

    When I compiled it, it did not like the #Define statements

    Much research on the web did not enlighten me (It looks like C language or a macro)

    So I cheated and used CBLOCK to define the labels then moved the values into the labels using
    movlw 0x34
    movlf DATA
    where before they used #Define DATA
    #define LC01DATA H’34’ ; Sample data to write to EEPROM

    I cut out the baud rate part of the program because the compiler did not like it, and it all passes

    So now I need to put the clock speed back in and simulate the program

    Did the same trick with cblock but the compiler complained

    I think that I was trying to put 4,000,000 into memory of 8 BITS
    This is 3D0900 in Hex

    I guess with CBLOCK I have sequentially used memory in blocks of 8 BITS

    So the maximum value is FF per memory address

    The D'100' should work as Binary 64

    The formula seems to be FOSC divided by 4* (SSPADD +1)

    Basically resulting in 100 MHZ Clock Rate for a 4MHZ Oscillator

    Is there a simpler way to program this statement in (using assembler)

    Can someone explain the #DEFINE and why MPLABSIM will not compile it

    I am confused about this statement
    movlw (FOSC / (4 * BAUD)) - 1 ; Calculates SSPADD
    movwf SSPADD ; for desired Baud rate
    ; and sets up SSPADD

    Can they not say
    In effect 4,000,000 / (400))
    = 100,000
    minus 1

    So SSPADD = 99999
    11000011010011111 in binary

    Which is surely too large for the SSPADD register ??

    Confused ?

    I know I am

    Any help appreciated

    For info I found the tutorial program here

    It is a copy of the original Microchip document

  2. Papabravo


    Feb 24, 2006
    You need to distinguish between arithmetic done by the compiler at compile time on a desktop PC, and arithmetic done at runtime on the PIC processor itself. Although #define is a construct from the C language, many assemblers have adopted the syntax and semantics for TEXT SUBSTITUTION MACROS. A text substitution macro operates in a pass over the source code BEFORE any actual compilation or assembly happens. Once the source code has been pre-processed it is passed to the assembly or compilation phase with ALL symbolic constants replaced by their equivalent numeric strings. Sting substitution has no knowledge of word sizes or processor word length. It is completely independent. You need to start over again with the original source code, understand the operation of text substitution macros, and adapt the code to your environment. What you have now is probably too hacked up to recover.

    BTW -- Nobody would run I2C at 100 baud. 100k to 400k would be typical. In this hardware 100 baud would be un-realizable as you have already observed
  3. Tobytyke

    Thread Starter New Member

    Oct 20, 2013
    Ok thanks for the input. I keep coming across the #Define syntax in a lot of code. I will have to try and find a good tutorial.

    I use the MPLAB asm compiler

    As this code originated from a Microchip tutorial, I thought it would just compile straight away without modification. I must admit I did not try it using the PIC16F877 which should just compile

    I am aiming for 100khz baud rate (standard I2C)

    There is lots of info about baud rate and I2C I just need to find a post with all the info in one place.

    AN735 has some useful info although based on another PIC

    There are a few things unclear

    Do I use OSCON register to setup the clock or is this not required for I2C ?

    I assumed I would need to specify XT as in the Microchip example the configure shows XT

    However this is based on a chip with external clock vs one with internal

    I was going to go with
    BIT 0= Internal Oscillator used for system clock (SET TO 1)
    BIT 1=LTS LFINTOSC is not stable (SET TO 0) as not using low freq ??
    BIT 2=HTS HFINTOSC is stable (SET TO 1) as using 100khz ??
    BIT 3=OSTS Device is running from Internal Oscilator (SET To 0)
    BIT 4-6=IRCF 4 MHZ (SET TO 110)
    BIT 7 not used (SET TO 0)

    Equally I could be completely wrong

    The equation for BIT rate appears to be (from AN75)

    ;Bit rate calc
    SSPADD=( (FOSC/BIT RATE)/4) -1

    ;Bit rate setup
    Movlw b'00001001'
    Banksel SSPADD
    movwf; baud rate =400 kHz@ 16MHZ

    It then sets the slew rate, but I would need to set this different to the application note as using a lower speed

    So for this example FOSC = 16MHZ (clock speed)
    BIT RATE = 400khz ( desired baud rate)
    (16,000,000 / 400,000) = 40
    40/4= 10
    10 -1 =9
    Therefore SSPADD = 9
    Hence movlw b'00001001' as this = decimal 9

    So in my case

    FOSC=4 MHZ (clock speed)
    BIT RATE = 100khz

    (4,000,000 / 100,000) = 40
    40/4= 10
    Therefore SSPADD =9

    If I was to increase my clock to 8MHZ
    BIT RATE = 100 KHz
    (8,000,000 / 100,000)=80
    80/4 = 20
    20 - 1 = 19
    Therefore SSPADD = 19

    Movlw b'001001111'
    Movwf SSPADD

    So hopefully this is the gist of the baud rate, I just need to now work out the config declaration ( as in the case of the PIC16F887 there are two words)

    And if I need to setup OSCON or anything else