I2C Slave por HW no Pic 18F [Resolvido]

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

I2C Slave por HW no Pic 18F [Resolvido]

Mensagempor Alesandro F Zagui » 15 Nov 2009 21:00

Preciso fazer comunicação PIC x PIC por I2C. Do lado Master já está funcionando, vejo isso pelo osciloscópio do Proteus. Mas não consigo fazer o slave funcionar.

Alguém tem algum código de exemplo de configuração dos registradores para modo Slave? Pode ser C ou ASM.

Todo o material que achei só fala da configuração Master.

Obrigado
Editado pela última vez por Alesandro F Zagui em 16 Dez 2009 23:59, em um total de 1 vez.
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Mensagempor tcpipchip » 16 Nov 2009 08:59

Funciona bem...
Com estas rotinas eu transformei uma camera serial em i2c
TCPIPCHIP

Código: Selecionar todos
'BNU 4/3/2004
'Define constantes para I2c em modo slave
I2Caddress CON   $02         ' Endereço I2c

' Definicao dos FLAGS i2c utilizados
SSPIF   VAR     PIR1.3          ' SSP (I2C) interrupt flag
BF      VAR     SSPSTAT.0       ' SSP (I2C) Buffer Full
R_W     VAR     SSPSTAT.2       ' SSP (I2C) Read/Write
D_A     VAR     SSPSTAT.5       ' SSP (I2C) Data/Address
CKP     VAR     SSPCON1.4        ' SSP (I2C) SCK Release Control
SSPEN   VAR     SSPCON1.5        ' SSP (I2C) Enable
SSPOV   VAR     SSPCON1.6        ' SSP (I2C) Receive Overflow Indicator
WCOL    VAR     SSPCON1.7        ' SSP (I2C) Write Collision Detect



' Initializa I2C modo slave

        SSPADD = I2Caddress         ' Seta nosso endereço i2c
        SSPCON2 = 0             ' Chamadas gerais disabilitadas
        SSPCON1 = $36             ' Seta i2c com slave de 7-bits (estranho)


        WHILE TRUE
           CLEARWDT
           IF SSPIF = TRUE Then         ' Aguardar master i2c querer falar comigo
                GoSub i2cslave
           EndIF           
        WEND
       

'************************************************************
'* TRATA I2C SE É ESCRITA, LEITURA OU ID
'************************************************************

i2cslave:                               ' I2C subrotina i2c
      SSPIF = 0                         ' apaga flag indicador tentativa acesso i2c
       
        IF R_W = 1 Then i2crd                ' Le dado

        IF BF = 0 Then i2cexit               ' Nada no buffer, cai fora
       
        IF D_A = 1 Then i2cwr                ' Dado para nos (nao endereço) 1 = data

        IF SSPBUF != I2Caddress Then i2cexit ' Não é para mim
       
        i2c_index = 0                     ' indexador local para guardar sequencia de dados i2c

        GoTo i2cexit

i2cwr:       
                                                    ' escrita I2C para nos
        datain = SSPBUF                         ' poe num vetor
        vetor_i2c_index[i2c_index] = datain
        i2c_index = i2c_index + 1                   'REMOVER COMENTARIO DEPOIS

        if DATAIN = $00 then     
            i2c_index = 0
        endif

        GoTo i2cexit

i2crd:                                            ' I2C read data from us
       
        IF D_A = 0 Then                                ' endereço
                i2c_index = 0                         ' marque como primeira leitura
        EndIF

        SSPBUF = RESULT                                'no caso de leitura, retorne algo para o master
        CKP = 1                                       ' libera SCL
        GoTo i2cexit               ' That's it

i2cexit:
      Return


Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Alesandro F Zagui » 16 Nov 2009 13:53

Estranho que continua sem funcionar, onde será que estou errando?

MASTER
Código: Selecionar todos
; CONFIGURACAO DE I2C
   MOVLW      .9
   MOVWF      SSPADD

   MOVLW      B'00000000'   
   MOVWF      SSPCON2

   MOVLW      B'00101000'   
   MOVWF      SSPCON1

MAIN:
   BTFSC      BOTAO
   BRA         MAIN

   BSF         SSPCON2,SEN

   BTFSC      SSPCON2,SEN
   GOTO      $-2

   MOVLW      0X04
   MOVWF      SSPBUF

   BTFSC      SSPSTAT,BF
   GOTO      $-2

   BTFSC      SSPSTAT,R_W
   GOTO      $-2

   MOVLW      "A"
   MOVWF      SSPBUF

   BTFSC      SSPSTAT,BF
   GOTO      $-2

   BTFSC      SSPSTAT,R_W
   GOTO      $-2

   BSF         SSPCON2,PEN


SLAVE
Código: Selecionar todos
; CONFIGURACAO DE I2C
   MOVLW      0X02
   MOVWF      SSPADD

   MOVLW      B'00000000'   
   MOVWF      SSPCON2

   MOVLW      B'00110110'   
   MOVWF      SSPCON1
   
MAIN:
   BTFSC      PIR1,SSPIF
   BSF         LED
   BRA         MAIN
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Mensagempor Djalma Toledo Rodrigues » 16 Nov 2009 14:03

Código: Selecionar todos
   ()
           {
                {
                     { }
                }
           }   

_ :?: :?:
.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor tcpipchip » 17 Nov 2009 11:39

neste exemplo eu criei um dispositivo I2C que tem a função apenas de gerar PWM em 2 saidas

o pacote é assim

start $02 (escrita, $03 leitura) P 1/0 (motor) PWM (freq) stop

TCPIPCHIP

Código: Selecionar todos
'************************************************************
'*  Nome    : driver.bas                                    *
'*  Author  : Miguel Wisintainer e CIA                      *
'*  Date    : 30/06/2009                                    *
'*  Version : 1.1                                           *
'*  Notes   : CARRINHO DSC.                                 *
'************************************************************
         
INCLUDE "modedefs.bas"

DEFINE  I2C_SLOW 1                                     
'DASABILITE
DEFINE  I2C_HOLD 1

'PWM

DEFINE CCP1_REG PORTC
DEFINE CCP1_BIT 2
DEFINE CCP2_REG PORTC
DEFINE CCP2_BIT 1

'WATCH DOG

DEFINE NO_CLRWDT 0

DEFINE OSC 20

'SERIAL

DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 2400
DEFINE HSER_CLROERR 1
DEFINE HSER_SPBRG 129

TRUE CON 1

' Define constants para I2c slave
I2Caddress CON   $02         ' Make our address 2

' Define used register flags
SSPIF   VAR     PIR1.3          ' SSP (I2C) interrupt flag
BF      VAR     SSPSTAT.0       ' SSP (I2C) Buffer Full
R_W     VAR     SSPSTAT.2       ' SSP (I2C) Read/Write
D_A     VAR     SSPSTAT.5       ' SSP (I2C) Data/Address
CKP     VAR     SSPCON.4        ' SSP (I2C) SCK Release Control
SSPEN   VAR     SSPCON.5        ' SSP (I2C) Enable
SSPOV   VAR     SSPCON.6        ' SSP (I2C) Receive Overflow Indicator
WCOL    VAR     SSPCON.7        ' SSP (I2C) Write Collision Detect

' Allocate RAM

i2c_index       var     byte              'Indice Vector i2c
vetor_i2c_index var     byte[54]          'Vetor I2c
RESULT          VAR     BYTE              ' DISPOSITIVO RESPONDE COM 1 OU TECLA
DATAIN          VAR     BYTE
OPCAO_I2C_PERIF VAR     BYTE

PWM_MOTOR_1      VAR BYTE
PWM_MOTOR_2      VAR BYTE

'PULSOS DE RODAS E DIRECAO

PULSES_RB4 VAR WORD
PULSES_RB5 VAR WORD
PULSES_RB6 VAR WORD
PULSES_RB7 VAR WORD

PULSES VAR WORD
INDEX_PULSES VAR WORD
PESO VAR WORD

STATPORTB VAR BYTE

'COMECA O PROGRAMA AQUI

        PULSES_RB4 = 0
        PULSES_RB5 = 0
        PULSES_RB6 = 0
        PULSES_RB7 = 0
        INDEX_PULSES = 0
        PULSES = 0

        'OPTION_REG = $7f
        OPTION_REG.7 = 0
        ON INTERRUPT GOTO INTERRUPT_ON_CHANGE
        INTCON = %10011000   

        TRISA = 0
        TRISC.1 = 0
        TRISC.2 = 0
        TRISB = %11110001   

        SSPADD = I2Caddress         ' Set our address
        SSPCON2 = 0             ' General call address disabled
        SSPCON = $36             ' Set to I2C slave with 7-bit address

        i2c_index = 0

        ADCON1 = 7                 'ALL PIN DIGITAL (portA)
           
        'I2C PERIPHERAL
        OPCAO_I2C_PERIF = " "

        PORTC.1 = 0
        PORTC.2 = 0

        HPWM 1,PWM_MOTOR_1,0
        HPWM 2,PWM_MOTOR_2,0
       
        WHILE TRUE
           CLEARWDT
           IF SSPIF = TRUE Then         ' Check for I2C interrupt flag
                GoSub i2cslave
           EndIF
        WEND
       
       
'************************************************************
'* TRATA I2C SE É ESCRITA, LEITURA OU ID
'************************************************************
i2cslave:                               ' I2C slave subroutine
      SSPIF = 0                         ' Clear interrupt flag
       
        IF R_W = 1 Then i2crd                ' Read data from us

        IF BF = 0 Then i2cexit               ' Nothing in buffer so exit
       
        IF D_A = 1 Then i2cwr                ' Data for us (not address) 1 = DATA

        IF SSPBUF != I2Caddress Then i2cexit ' Clear the address from the buffer
       
        i2c_index = 0                     ' Mark as first read

        GoTo i2cexit

i2cwr:       

        toggle PORTA.0
                                                    ' I2C write data to us
        datain = SSPBUF                         ' Put data into array
        vetor_i2c_index[i2c_index] = datain
        i2c_index = i2c_index + 1                   'REMOVER COMENTARIO DEPOIS

        if DATAIN = $00 then      'SE DEU LIMITE DO LCD OU NULL
            i2c_index = 0
            gosub Analisa_Pacote_I2c
        endif

        GoTo i2cexit

i2crd:                                            ' I2C read data from us
        toggle PORTA.1

        IF D_A = 0 Then                                ' ADDRESS
                i2c_index = 0                         ' Mark as first read
        EndIF
       
        SSPBUF = 99

        CKP = 1                                       ' Release SCL line

        GoTo i2cexit               ' That's it
i2cexit:
      Return

'**********************************************************
'ANALISA O QUE MASTER QUER DO DISPOSITIVO I2C
'**********************************************************
Analisa_Pacote_I2c:
        IF vetor_i2c_index[0] = "P" THEN               
            IF vetor_i2c_index[1] = 1 THEN               
                HPWM 1,vetor_i2c_index[2],2000
                PWM_MOTOR_1 = VETOR_I2C_INDEX[2]
                RETURN
            ENDIF
            IF vetor_i2c_index[1] = 2 THEN               
                HPWM 2,vetor_i2c_index[2],2000
                PWM_MOTOR_2 = VETOR_I2C_INDEX[2]
                RETURN
            ENDIF
            IF vetor_i2c_index[1] = 3 THEN               
                HPWM 1,vetor_i2c_index[2],2000
                HPWM 2,vetor_i2c_index[2],2000
                PWM_MOTOR_1 = VETOR_I2C_INDEX[2]
                PWM_MOTOR_2 = VETOR_I2C_INDEX[2]               
                RETURN
            ENDIF
        endif

        IF vetor_i2c_index[0] = "F" THEN               
            IF vetor_i2c_index[1] = 4 THEN             
                INDEX_PULSES = 0
                PULSES = PULSES_RB4
                PULSES_RB4 = 0
                'PULSES = 44444
                RETURN
            ENDIF
            IF vetor_i2c_index[1] = 5 THEN             
                INDEX_PULSES = 0
                PULSES = PULSES_RB5
                PULSES_RB5 = 0
                'PULSES = 55555
                RETURN
            ENDIF
            IF vetor_i2c_index[1] = 6 THEN               
                INDEX_PULSES = 0
                PULSES = PULSES_RB6
                PULSES_RB6 = 0
                'PULSES = 33333
                RETURN
            ENDIF
            IF vetor_i2c_index[1] = 7 THEN               
                INDEX_PULSES = 0
                PULSES = PULSES_RB7
                PULSES_RB7 = 0
                'PULSES = 43690
                RETURN
            ENDIF
        endif
        return
     END       
     
    DISABLE
INTERRUPT_ON_CHANGE:
    if INTCON.0 = 1 THEN  'RBIF
        ASM
           MOVF PORTB,1
        ENDASM
           
        if PORTB.4 = 1 THEN
            PULSES_RB4 = PULSES_RB4 + 1
            TOGGLE PORTA.2
            GOTO SAIDA
        ENDIF

        if PORTB.5 = 1 THEN
            PULSES_RB5 = PULSES_RB5 + 1
            TOGGLE PORTA.1
            GOTO SAIDA
        ENDIF

        if PORTB.6 = 1 THEN
            PULSES_RB6 = PULSES_RB6 + 1
            GOTO SAIDA
        ENDIF

        if PORTB.7 = 1 THEN
            PULSES_RB7 = PULSES_RB7 + 1
            GOTO SAIDA
        ENDIF
SAIDA:
        INTCON.0 =    0            'APAGA BIT INDICADOR INTERRUPCAO
        GOTO SAI_INTERRUPT
    ENDIF

    IF INTCON.1 = 1 THEN       
       LOOKUP2 INDEX_PULSES,[1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768],PESO
       'HSEROUT [DEC PESO, " ", DEC (PULSES & PESO), " ",13,10 ]
       IF (PULSES & PESO) = 0 THEN
          PORTB.1 = 0
       ELSE
          PORTB.1 = 1
       ENDIF
       INDEX_PULSES = INDEX_PULSES + 1
       IF INDEX_PULSES > 15 THEN
          INDEX_PULSES = 0
       ENDIF             
       INTCON.1 = 0 'APAGA FLAG SINALIZA INTERRUPT RB0
    ENDIF
SAI_INTERRUPT:   
    RESUME     
    ENABLE     
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Alesandro F Zagui » 17 Nov 2009 12:34

Obrigado pela ajuda TCP, mas o problema é que o slave não recebe os dados, vejo pelo osciloscópio do proteus que o master envia corretamente, mas o slave não recebe. Veja que o programa que postei, a unica coisa que ele faz é ligar um led quando o flag PIR1,SSPIF for setado, nem isso ta fazendo.
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Mensagempor tcpipchip » 17 Nov 2009 16:06

Voce colocou os OBJETOS PULLUP do PROTEUS nos PINOS SDA e SCL ?
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Alesandro F Zagui » 18 Nov 2009 07:37

Olha o esquema:

Imagem

Veja que a transmissão acontece:

Imagem
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Mensagempor tcpipchip » 18 Nov 2009 12:57

É para funcionar amigo. Tem erro no teu software.

Eu fiz um projeto 2 anos atras em que eu fiz 2 pics serem SLAVE de um MASTER, via i2c
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Sergio38br » 18 Nov 2009 13:54

Pergunta meio besta mas teus pullups não estão um pouco baixo..

[ ]'s
Sergio
Avatar do usuário
Sergio38br
Word
 
Mensagens: 759
Registrado em: 22 Nov 2007 13:39
Localização: São Paulo - SP

Mensagempor tcpipchip » 18 Nov 2009 20:15

Hummm, tem isto...

Mas faz o seguinte...ativa o I2C ANALYZER no PROTEUS, ok ?
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Alesandro F Zagui » 19 Nov 2009 07:37

Seria isso TCPIP?

Imagem

Em relação ao resistores pullups, eu estou usando 1K, é que nessa imagem eu havia abaixado o valor para fazer um teste.

Uma duvida, vejam quem no meu exemplo, o Slave eu estou configurando com o endereço 0x02, e no Master eu devo chamar o Slave pelo endereço 0x02 ou 0x04? Pois os bits de endereço são os 7 mais significativos.
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Mensagempor ze » 19 Nov 2009 09:22

talvez num tenha relação mas não use resistor. use o OBJETO PULLUP propriamente dito pelo nosso amigo tc. Faz MUITA dif. pois ele é um resistor "digital" e torna a simulação + rápida.
Também existe PULLDOWN . prrrrrrrrrrrrrrrrrrrrrrrrrr. desculpe...
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor tcpipchip » 19 Nov 2009 19:09

analisando o i2c, nao consigo achar o START, o endereço, o ACK, o STOP...está muito estranho

Eu testei aqui com um exemplo que fiz, onde criei um teclado I2C e funcou 100%

Imagem

O exemplo, eu configurei um dispositivo i2c como slave.

Vendo o exemplo, eu mando um START (S) seguido do endereço do disposito (2), ai ele responde com ACK (A), ai mando o endereço 44 e ele responde com ACK (A), entao mando 3 dados (FE,01,00) com ACK recebidos, entao um STOP (P)

Fiz uma escrita, ok ?

Abraços

TCPIPCHIPTCPIPCHIPTCPIPCHIP
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Alesandro F Zagui » 19 Nov 2009 20:36

Não querendo abusar, mas já abusando da sua boa vontade, você poderia postar o código do Master e do Slave desse exemplo?

Estou achando que o problema esta no master e não no slave.

Atenciosamente
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Próximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Google [Bot] e 1 visitante

cron

x