16F690 and i2c Com


Closed Thread
Results 1 to 10 of 10

Hybrid View

  1. #1
    Join Date
    May 2010
    Posts
    20

    Default 16F690 and i2c Com

    Hi again everyone, I've been trying to interface my PIC16F690 with a DS1621 Digital Thermometer. I haven't been able to find many resources and the code I have found within the forum I could not get to work. The code which I have tried to adapt now is for a DS1624 and the commands seem identical to me but yet it returns "0.00". my serial communication is working 100% and I have gone over my wiring a lot. Open to any suggestions/changes. I have got A0, A1, A2 all grounded which gives the device an address of %10010000. Aswell as 4.7k pick ups on the sda scl lines. I thought it possibly could be because I am using Port A.0 and A.1? Not sure.

    Code:
    DEFINE OSC 4
    DEFINE HSER_RCSTA 90h
    DEFINE HSER_TXSTA 20h
    DEFINE HSER_SPBRG 25
    DEFINE HSER_CLROERR 1
    
    SDA VAR PORTA.0         
    SCL VAR PORTA.1         
    
    i2c_read CON 1          'R/W configuration bit (1 = read)
    i2c_write CON 0         'R/W configuration bit (0 = write)
    i2c_out VAR BYTE        'data to sent over I2C bus
    i2c_in  VAR BYTE[2]     'data received over I2C bus
    i2c_ack VAR BIT         'acknowledgement bit
    temp VAR WORD
    
        Hserout ["Starting"]
        GOSUB Config_Register   'Set Configuration
        GOSUB Start_Convert     'Start continuous conversion
     
    TOP:
        PAUSE 2000
        GOSUB Read_Temp     'Read the current temperature
        i2c_in[2] = i2c_in[1] >> 3 'Shift 5 decimal bits to LS position
        temp = (i2c_in[1]*1000) 'PIC Doesn’t like decimals, but there is a way to work around this
        HSEROUT [DEC i2c_in[0],".",DEC2 (temp ** 2048)/100,13,10]'Outputs temperature to termina
        GOTO top            'Loops forever
                    
    Config_Register:        'Set continuous conversion
        GOSUB I2C_START     'Start Condition
        i2c_out = %10010000 'Send Address, (device= %1001, A0= 0, A1= 0, A2= 0, R/W= 0)                        
        GOSUB I2C_TX        'Send data in “i2c_out” 
        i2c_out = $AC       'Send “Access Configuration” command
        GOSUB I2C_TX        'Send data in “i2c_out”
        i2c_out = $00       'Send “Continuous Conversion” command
        GOSUB I2C_TX        'Send data in “i2c_out”
        GOSUB I2C_STOP      'Stop Condition
        RETURN
     
    Start_Convert:          'Start Conversion
        GOSUB I2C_START
        i2c_out = %10010000 'Send Address, (device= %1001, A0= 0, A1= 0, A2= 0, R/W= 0)
        GOSUB I2C_TX
        i2c_out = $EE       'Send “Start to Convert” command
        GOSUB I2C_TX
        GOSUB I2C_STOP
        RETURN
     
    Read_Temp:              'Read temperature
        GOSUB I2C_START
        i2c_out = %10010000 'You must “write” the command to read the temperature before
        GOSUB I2C_TX        'reading it, therefore R/W still is 0
        i2c_out = $AA       'Send “Read Temperature” command
        GOSUB I2C_TX
        GOSUB I2C_START     '* Reissue Start Condition *
        i2c_out = %10010001 'Send Address, (device= %1001, A0= 0, A1= 0, A2= 0, R/W= *1*)
        GOSUB I2C_TX        'Transmit address with R/W bit as 1 (“read”)
        GOSUB I2C_RX        'Start getting data coming in
        GOSUB I2C_STOP      'Issue stop condition
        RETURN
     
    I2C_START:              'I2C start (start communication on I2C bus)
        HIGH SDA
        HIGH SCL
        LOW SDA
        LOW SCL
        RETURN
     
    I2C_STOP:               'I2C stop (terminate communication on I2C bus)
        LOW SDA
        HIGH SCL
        HIGH SDA
        PAUSE 1
        RETURN
     
    I2C_RX:                           'I2C receive -> receive data from slave
        SHIFTIN SDA,SCL,0,[i2c_in[0]] 'Shift in first byte MSBpre
        SHIFTOUT SDA,SCL,1,[%0\1]     'Send acknowledge (ACK) = 0
        SHIFTIN SDA,SCL,0,[i2c_in[1]] 'Shift in second byte MSBpre
        SHIFTOUT SDA,SCL,1,[%1\1]     'Send not acknowledge (NACK) = 1
        RETURN
     
    I2C_TX:                           'I2C transmit -> send data to the slave
        SHIFTOUT SDA,SCL,1,[i2c_out]  'Shift out “i2c_out” MSBfirst
        SHIFTIN SDA,SCL,0,[i2c_ack\1] 'Receive ACK bit          
        RETURN
    
    
    END

  2. #2
    Join Date
    Mar 2006
    Location
    China
    Posts
    266


    Did you find this post helpful? Yes | No

    Default Port A .....

    Read this..http://www.picbasic.co.uk/forum/show...8252#post88252

    Read the datasheet

    Pull some hair from the head... read some more datasheet...

    Port A could have some extra features... also a search for "all digital" might give a few answers as well

  3. #3
    Join Date
    May 2010
    Posts
    20


    Did you find this post helpful? Yes | No

    Default

    OK the hair is pulled

    From all my reading I *think* what I need to do is add

    Code:
    ANSEL=%00000000
    ADCON1=%00000111
    Will be giving it a try when I get home, I appreciate the type of reply it is way better to be steered in the right direction compared to being given the answer. I struggle to make sense of the datasheets sometimes and I cant figure out why, it may be my lack of electronic knowledge or maybe it just takes time and practice.

    I understand what the registers do but I don't understand where the value "7" comes in, why not another value.
    Last edited by ross246; - 24th May 2010 at 11:07.

  4. #4
    Join Date
    Sep 2009
    Posts
    19


    Did you find this post helpful? Yes | No

    Default

    Hello.
    Decimal 7 is same as binary 00000111, that's why mr. Jumper provided the link above. In order to disable analog functions of the portA you have to set first three bits (i.e. bit0, bit1, bit2) of the register, which is described in a datasheet.

  5. #5
    Join Date
    May 2010
    Posts
    20


    Did you find this post helpful? Yes | No

    Default Another little question

    It worked perfectly thank you for explaining. I wanted to ask another question I thought I would just keep it in this thread since its small.

    I am thinking of ways to hook up a 3 digit seven segment display to my pic, it has a common cathode. I was wondering if it would work to hook up each anode to lets say portc.0 through to portc.7 (the dot) and connect the cathode for each digit to a different port say portb.4 through to say portb.6. That way when I want to write something to the first digit I set portb.4 low and set portb.5 and portb.6 to high. When I tried to connect it up this way, the numbers appeared very dim. I think I have the right idea because I can decrease the pause between switching to each digit and to the human eye it would appear like they are all on at the same time? I am new to both electronics and microcontrollers so i apologise if it's a stupid question I will post the code I was fiddling with:

    Code:
    define OSC 4
    
    LEDTOP         var     PORTC.0   
    LEDTOPLEFT     var     PORTC.1
    LEDTOPRIGHT    VAR     PORTC.2
    
    LEDMIDDLE      VAR     PORTC.3
    
    LEDBOTTOMRIGHT VAR     PORTC.4
    LEDBOTTOM      VAR     PORTC.5
    LEDBOTTOMLEFT  VAR     PORTC.6
    
    SEG1 VAR PORTB.4
    SEG2 VAR PORTB.5
    SEG3 VAR PORTB.6
    
    TRISC = %00000000       
    TRISB = %00000000
    
    ADCON1=%00000111
    ANSELH=0
    ANSEL=0
    CM1CON0=0
    CM2CON0=0
    
    
           
    loop:   
           gosub Selseg1
           gosub DisNo5
           pause 500
           
           goto Selseg2
           goto DisNo5
           pause 500
           
           goto Selseg3
           goto DisNo5
           pause 500
            
           goto loop  
    
    Selseg1:
         seg1 = 0
         seg2 = 1
         seg3 = 1
         RETURN
         
    Selseg2:
         seg1 = 1
         seg2 = 0
         seg3 = 1
         Return
         
    Selseg3:
         seg1 = 1
         seg2 = 1
         seg3 = 0
         RETURN
         
    DisNo1:
         LEDTOP = 0
         LEDTOPLEFT = 0
         LEDTOPRIGHT = 1
         LEDMIDDLE = 0
         LEDBOTTOMRIGHT = 1
         LEDBOTTOM = 0
         LEDBOTTOMLEFT = 0
         return
    
         
    DisNo2:
         LEDTOP = 1
         LEDTOPLEFT = 0
         LEDTOPRIGHT = 1
         LEDMIDDLE = 1
         LEDBOTTOMRIGHT = 0
         LEDBOTTOM = 1
         LEDBOTTOMLEFT = 1      
         return
         
    DisNo3:
         LEDTOP = 1
         LEDTOPLEFT = 0
         LEDTOPRIGHT = 1
         LEDMIDDLE = 1
         LEDBOTTOMRIGHT = 1
         LEDBOTTOM = 1
         LEDBOTTOMLEFT = 0      
          return
          
     DisNo4:
         LEDTOP = 0
         LEDTOPLEFT = 1
         LEDTOPRIGHT = 1
         LEDMIDDLE = 1
         LEDBOTTOMRIGHT = 1
         LEDBOTTOM = 0
         LEDBOTTOMLEFT = 0      
         return
         
    DisNo5:
         LEDTOP = 1
         LEDTOPLEFT = 1
         LEDTOPRIGHT = 0
         LEDMIDDLE = 1
         LEDBOTTOMRIGHT = 1
         LEDBOTTOM = 1
         LEDBOTTOMLEFT = 0      
         return
         
     DisNo6:
         LEDTOP = 0
         LEDTOPLEFT = 1
         LEDTOPRIGHT = 0
         LEDMIDDLE = 1
         LEDBOTTOMRIGHT = 1
         LEDBOTTOM = 1
         LEDBOTTOMLEFT = 1      
         return
         
      DisNo7: 
          LEDTOP = 1
         LEDTOPLEFT = 0
         LEDTOPRIGHT = 1
         LEDMIDDLE = 0
         LEDBOTTOMRIGHT = 1
         LEDBOTTOM = 0
         LEDBOTTOMLEFT = 0      
         return
         
     DisNo8:
          LEDTOP = 1
         LEDTOPLEFT = 1
         LEDTOPRIGHT = 1
         LEDMIDDLE = 1
         LEDBOTTOMRIGHT = 1
         LEDBOTTOM = 1
         LEDBOTTOMLEFT = 1      
         return
         
     DisNo9: 
         LEDTOP = 1
         LEDTOPLEFT = 1
         LEDTOPRIGHT = 1
         LEDMIDDLE = 1
         LEDBOTTOMRIGHT = 1
         LEDBOTTOM = 0
         LEDBOTTOMLEFT = 0              
         return        
    End

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default

    Hi,
    I haven't looked at your code but remember that the pins can source and sink 25mA. This is probably enough for direct driving the segments but if you have 10mA thru each segment and all seven segments lit up the poor pin on PortB that is trying to sink 70mA is going to have a hard time.

    Otherwise your aproach is correct, called multiplexing. Since each digit is only "on" 1/3 of the time (or less) it's quite common to drive the segments harder than their continous rating to get more light out of them. That way the average current thru the segments is still kept below their rating.

    /Henrik.

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts