Ir ao conteúdo
  • Cadastre-se
Rogerio Fiorotti

Comunicação entre PIC´s

Posts recomendados

Prezados estou precisando pra concluir meu projeto exemplos de comunicação entre PIC´s utilizando 1 fio, onde consigo ler e alterar valores gravados na EEprom de uma delas.

 

Abraços.

 

Rogério

Compartilhar este post


Link para o post
Compartilhar em outros sites

De = pra = ...
uma (01) opção...
habilite a comunicação serial e faça no mestre TXREG=valor e no escravo eepromwrite(endereco,RXREG). 'valor' de um vai pro 'endereco' do outro
 

Compartilhar este post


Link para o post
Compartilhar em outros sites
Tenho um código com comunicação I2C entre PICS (o Slave funciona da mesma forma que o DS1307 em termos de recebimento e envio de dados), porém são usados dois fios/pinos.

 

Para um único fio talvez seja legal fazer algo que funcione como o DHT11...

Daí o mestre poderia enviar 1 bit para o comando (ler ou escrever) + 1 byte para o endereço onde a operação vai ocorrer

   Se for escrita + 1 byte com o dado;

   Se for leitura o mestre libera a linha (pino como entrada) e aguarda o Slave enviar o byte...

 

Poderia ser usado um resistor de PULL-UP assim ambos os PICS apenas colocam a linha em nível baixo (nível alto = pino como entrada) evitando curto.

 

Eu estou meio na correria, poderia fazer o exemplo mas acho que quando sobrar tempo você já terá resolvido o problema  :)

Qual compilador você está usando?

Compartilhar este post


Link para o post
Compartilhar em outros sites

De = pra = ...

uma (01) opção...

habilite a comunicação serial e faça no mestre TXREG=valor e no escravo eepromwrite(endereco,RXREG). 'valor' de um vai pro 'endereco' do outro

 

Ok, mas como vou conseguir ler o valor da eeprom no escravo antes de gravar em uma unica via de comunicação?

 

Tenho um código com comunicação I2C entre PICS (o Slave funciona da mesma forma que o DS1307 em termos de recebimento e envio de dados), porém são usados dois fios/pinos.
 
Para um único fio talvez seja legal fazer algo que funcione como o DHT11...
Daí o mestre poderia enviar 1 bit para o comando (ler ou escrever) + 1 byte para o endereço onde a operação vai ocorrer
   Se for escrita + 1 byte com o dado;
   Se for leitura o mestre libera a linha (pino como entrada) e aguarda o Slave enviar o byte...
 
Poderia ser usado um resistor de PULL-UP assim ambos os PICS apenas colocam a linha em nível baixo (nível alto = pino como entrada) evitando curto.
 
Eu estou meio na correria, poderia fazer o exemplo mas acho que quando sobrar tempo você já terá resolvido o problema  :)
Qual compilador você está usando?

 

Estou utilizando CCS e a PIC de onde quero ler e gravar é a 12F1840. Mas quando você tiver um tempinho gostaria de ver seu exemplo, eu aguardo...Obrigado.

Ok, mas como vou conseguir ler o valor da eeprom no escravo antes de gravar em uma unica via de comunicação?

Estou utilizando CCS e a PIC de onde quero ler e gravar é a 12F1840. Mas quando você tiver um tempinho gostaria de ver seu exemplo, eu aguardo...Obrigado.

Ah, tenho que utilizar um fio só mesmo...

Compartilhar este post


Link para o post
Compartilhar em outros sites

não consegue, claro. Peço a gentileza de googlar "1wire protocol". Com um pouco de criatividade, pode até conversar pelo sinal de alimentação ou alimentar pelo sinal não necessariamente nesta odem

Boa sorte!

Compartilhar este post


Link para o post
Compartilhar em outros sites

não consegue, claro. Peço a gentileza de googlar "1wire protocol". Com um pouco de criatividade, pode até conversar pelo sinal de alimentação ou alimentar pelo sinal não necessariamente nesta odem

Boa sorte!

Passei a tarde toda pesquisando, mas não encontrei algo que realmente dê uma luz para o meu caso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Rogerio Fiorotti Vou fazer o exemplo... Depois posto aqui para você! Não vai ficar aquela coisa bonitona  :lol:  mas deve funcionar...

 

O @Isadora Ferraz disse o nome da comunicação... 1-WIRE...

https://pt.wikipedia.org/wiki/One_wire

 

Se você ler o datasheet do DHT22 entenderá como o protocolo funciona.

http://www.adafruit.com/datasheets/DHT22.pdf

 

Depois posto o código.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Ai está o código, o 12F está operando a 32MHz (8MHz TCY) se essa frequencia for abaixa o código provavelmente apresentará erro, mas se você quiser eliminar o erro conseguirá alterando o código... Outra coisa, a comunicação é extremamente lenta ~100Hz (repare o quadrado vermelho na figura), você conseguirá aumentar essa frequência alterando o código ou entendendo ele e criando um novo... Não há uma verificação de erro, então nada garante que o valor enviado foi igual ao recebido... O escravo usa interrupção externa pino RA2...O código foi muito mas muito pouco testado HEHE!!
 
A comunicação ficou como eu disse acima.
O mestre coloca a linha em nível baixo por 200mS e então a libera;
O escravo confirma a sua rpesença levando a linha para o nível baixo por 10mS e então a libera;
O mestre envia 1 bit indicando a operação (escrita ou leitura);
E então envia 1 byte indicando o endereço;
   Se a operação for de escrita envia um byte com o valor a ser escrito;
   Se a operação for de leitura libera a linha e aguarda o escravo enviar o valor;
 
para representar um bit com o valor 1 é enviado um pulso 2mS em nível baixo e 6mS em nível alto.
para representar um bit com o valor 0 é enviado um pulso 6mS em nível baixo e 4mS em nível alto.
 
Esse PIC possui DAC em? Só faltou o zero crossing detector  ^_^
 
Imagem:
G2I78TJ.png
 
Mestre:

#include <16F628A.h>#FUSES PUT                     //Power Up Timer#FUSES NOMCLR                  //Master Clear pin used for I/O#FUSES BROWNOUT                //Reset when brownout detected#FUSES NOLVP                   //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O#FUSES NOCPD                   //No EE protection#FUSES NOPROTECT               //Code not protected from reading#use delay(internal=4MHz)#define LED PIN_B0#define DELAY 500/******************************************************************************/// O código precisa dos bits dos registradores TRIS e PORT referente ao pino.#bit pino_one_wire    = 0x06.4  // bit 4 do registrador PORTB (PORTB.4)#bit direcao_one_wire = 0x86.4  // bit 4 do registrador TRISB (TRISB.4)#include <EEPROM_ONE_WIRE.c>/******************************************************************************/void main(){  unsigned int valor_lido1, valor_lido2, valor_lido3, status;    inicializar_one_wire();    status = escrever_eeprom_onewire(0, 8); // Escreve 8 na posição 0 da EEPROM do escravo  escrever_eeprom_onewire(1, 5);          // Escreve 5 na posição 1 da EEPROM do escravo  escrever_eeprom_onewire(2, 2);          // Escreve 2 na posição 2 da EEPROM do escravo  //if(status == 1)    // significa que o escravo não respondeu ao chamdo do mestre      // Lendo o valor armezenado na posição 0 da EEPROM do escravo  valor_lido1 = ler_eeprom_onewire(0, status);   // Lendo o valor armezenado na posição 1 da EEPROM do escravo  valor_lido2 = ler_eeprom_onewire(1, status);   // Lendo o valor armezenado na posição 0 da EEPROM do escravo  valor_lido3 = ler_eeprom_onewire(2, status); //if(status == 1)    // significa que o escravo não respondeu ao chamdo do mestre        while(true)  {    output_low(LED);    delay_ms(DELAY);    output_high(LED);    delay_ms(DELAY);  }}

 
Escravo:

#include <12F1840.h>#device ADC=10#FUSES PUT                     //Power Up Timer#FUSES NOMCLR                  //Master Clear pin used for I/O#FUSES NOPROTECT               //Code not protected from reading#FUSES NOCPD                   //No EE protection#FUSES NOBROWNOUT              //No brownout reset#FUSES NOCLKOUT                //I/O function on OSC2#FUSES NOIESO                  //Internal External Switch Over mode disabled#FUSES NOFCMEN                 //Fail-safe clock monitor disabled#FUSES NOWRT                   //Program memory not write protected#FUSES NOSTVREN                //Stack full/underflow will not cause reset#FUSES BORV19                  //Brownout reset at 1.9V#FUSES NOLVP                   //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O#use delay(internal=32MHz)#define LED PIN_A0#define DELAY 500#bit pino_one_wire_escrita = 0X10C.2     // Para escrever LATA.2#bit pino_one_wire_leitura = 0x00C.2     // PARA ler PORTA.2#bit direcao_one_wire      = 0x08C.2     // TRISA bit 2 para mudar a direção do pino#define _input   1#define _output  0#define _low     0#define _high    1#define _escrita 1#define _leitura 0#INT_EXTvoid  EXT_isr(void) {  unsigned int16 _aux = 0;  unsigned int _i, _address = 0, _value = 0, _value_read = 0;  short _operacao;    pino_one_wire_escrita = _low;     // Prepara o pino com o valor 0    while(!pino_one_wire_leitura) {}  // Espera o mestre liberar a linha  delay_ms(1);                        direcao_one_wire = _output;       // Coloca zero na linha para indicar ao mestre                                    // que este escravo está presente  delay_ms(10);                     // Deixa em baixo por 10mS  direcao_one_wire = _input;        // Libera o barramento    while(pino_one_wire_leitura) {}   // Espera o mestre iniciar o envio do bit de comando    // Pegando o bit de comando  do {    delay_us(1);    _aux++;  }while(!pino_one_wire_leitura);   // Conta o tempo em que a linha ficou em nível baixo    if(_aux < 2001) {                 // menor que 2mS (2000uS) é igual a 1 recebido, operação de escrita    _operacao = _escrita;  }    else {                          // maior  que 2mS é igual a 0 recevido, operação de leitura      _operacao = _leitura;    }    // Pegando o endereço da Operação  _aux = 0;  for(_i = 0; _i < 8; _i++) {    while(pino_one_wire_leitura) {} // Espera a linha ser colocada em zero        do {      delay_us(1);      _aux++;    }while(!pino_one_wire_leitura);   // Conta o tempo em que a linha ficou em nível baixo          if(_aux < 2001) {                 // menor que 2mS (2000uS) é igual a 1 recebido      bit_set(_address, _i);          // então seta o bit correspondente.    }    // A variável _address é iniciada com zero então não há a necessidade de zerar    // o bit caso o valor recebido for zero.    _aux = 0;  }    if(_operacao == _escrita) {    // Pega o valor a ser escrito no endereço enviado pelo mestre    _aux = 0;    for(_i = 0; _i < 8; _i++) {      while(pino_one_wire_leitura) {}   // Espera a linha ser colocada em zero            do {        delay_us(1);        _aux++;      }while(!pino_one_wire_leitura);   // Conta o tempo em que a linha ficou em nível baixo              if(_aux < 2001) {                 // menor que 2mS (2000uS) é igual a 1 recebido        bit_set(_value, _i);            // então seta o bit correspondente.      }      // A variável _value é iniciada com zero então não há a necessidade de zerar      // o bit caso o valor recebido for zero.      _aux = 0;    }   write_eeprom (_address, _value);   direcao_one_wire = _output;          // Coloca a linha em zero para indicar que a escrita terminou   delay_us(5);   direcao_one_wire = _input;   }    else {                                // Se a operação for de leitura      _value_read = read_eeprom(_address);// Lê o valor armazenado na posição _address      delay_ms(20);                       // Espera o mestre se preparar para o recebimento            for (_aux = 0; _aux < 8; _aux++) {        if(bit_test(_value_read, _aux)) { // Verifica o bit a ser enviado se for 1          direcao_one_wire = _output;     // Pino em nível baixo 0          delay_ms(2);                    // por 2mS (bit 1)          direcao_one_wire = _input;      // Pino em nível alto 1          delay_ms(8);                    // por 8mS              }          else {                          // Se for 0            direcao_one_wire = _output;   // Pino em nível baixo 0            delay_ms(6);                  // por 6mS (bit 0)            direcao_one_wire = _input;    // Pino em nível alto 1            delay_ms(4);                  // por 4mS          }      }             }}  void main(){  direcao_one_wire = _input;    ext_int_edge(H_TO_L);         // Necessário para o código funcionar corretamente  enable_interrupts(INT_EXT);   // habilita a interrupção externa - Interrupção na transição de ALTO para BAIXO  enable_interrupts(GLOBAL);    // habilita todas as interrupções  //Example blinking LED program  while(true)  {    output_low(LED);    delay_ms(DELAY);    output_high(LED);    delay_ms(DELAY);  }}

 
Download:
 

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Ai está o código, o 12F está operando a 32MHz (8MHz TCY) se essa frequencia for abaixa o código provavelmente apresentará erro, mas se você quiser eliminar o erro conseguirá alterando o código... Outra coisa, a comunicação é extremamente lenta ~100Hz (repare o quadrado vermelho na figura), você conseguirá aumentar essa frequência alterando o código ou entendendo ele e criando um novo... Não há uma verificação de erro, então nada garante que o valor enviado foi igual ao recebido... O escravo usa interrupção externa pino RA2...O código foi muito mas muito pouco testado HEHE!!
 
A comunicação ficou como eu disse acima.
O mestre coloca a linha em nível baixo por 200mS e então a libera;
O escravo confirma a sua rpesença levando a linha para o nível baixo por 10mS e então a libera;
O mestre envia 1 bit indicando a operação (escrita ou leitura);
E então envia 1 byte indicando o endereço;
   Se a operação for de escrita envia um byte com o valor a ser escrito;
   Se a operação for de leitura libera a linha e aguarda o escravo enviar o valor;
 
para representar um bit com o valor 1 é enviado um pulso 2mS em nível baixo e 6mS em nível alto.
para representar um bit com o valor 0 é enviado um pulso 6mS em nível baixo e 4mS em nível alto.
 
Esse PIC possui DAC em? Só faltou o zero crossing detector  ^_^
 
Imagem:
G2I78TJ.png
 
Mestre:

#include <16F628A.h>#FUSES PUT                     //Power Up Timer#FUSES NOMCLR                  //Master Clear pin used for I/O#FUSES BROWNOUT                //Reset when brownout detected#FUSES NOLVP                   //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O#FUSES NOCPD                   //No EE protection#FUSES NOPROTECT               //Code not protected from reading#use delay(internal=4MHz)#define LED PIN_B0#define DELAY 500/******************************************************************************/// O código precisa dos bits dos registradores TRIS e PORT referente ao pino.#bit pino_one_wire    = 0x06.4  // bit 4 do registrador PORTB (PORTB.4)#bit direcao_one_wire = 0x86.4  // bit 4 do registrador TRISB (TRISB.4)#include <EEPROM_ONE_WIRE.c>/******************************************************************************/void main(){  unsigned int valor_lido1, valor_lido2, valor_lido3, status;    inicializar_one_wire();    status = escrever_eeprom_onewire(0, 8); // Escreve 8 na posição 0 da EEPROM do escravo  escrever_eeprom_onewire(1, 5);          // Escreve 5 na posição 1 da EEPROM do escravo  escrever_eeprom_onewire(2, 2);          // Escreve 2 na posição 2 da EEPROM do escravo  //if(status == 1)    // significa que o escravo não respondeu ao chamdo do mestre      // Lendo o valor armezenado na posição 0 da EEPROM do escravo  valor_lido1 = ler_eeprom_onewire(0, status);   // Lendo o valor armezenado na posição 1 da EEPROM do escravo  valor_lido2 = ler_eeprom_onewire(1, status);   // Lendo o valor armezenado na posição 0 da EEPROM do escravo  valor_lido3 = ler_eeprom_onewire(2, status); //if(status == 1)    // significa que o escravo não respondeu ao chamdo do mestre        while(true)  {    output_low(LED);    delay_ms(DELAY);    output_high(LED);    delay_ms(DELAY);  }}

 
Escravo:

#include <12F1840.h>#device ADC=10#FUSES PUT                     //Power Up Timer#FUSES NOMCLR                  //Master Clear pin used for I/O#FUSES NOPROTECT               //Code not protected from reading#FUSES NOCPD                   //No EE protection#FUSES NOBROWNOUT              //No brownout reset#FUSES NOCLKOUT                //I/O function on OSC2#FUSES NOIESO                  //Internal External Switch Over mode disabled#FUSES NOFCMEN                 //Fail-safe clock monitor disabled#FUSES NOWRT                   //Program memory not write protected#FUSES NOSTVREN                //Stack full/underflow will not cause reset#FUSES BORV19                  //Brownout reset at 1.9V#FUSES NOLVP                   //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O#use delay(internal=32MHz)#define LED PIN_A0#define DELAY 500#bit pino_one_wire_escrita = 0X10C.2     // Para escrever LATA.2#bit pino_one_wire_leitura = 0x00C.2     // PARA ler PORTA.2#bit direcao_one_wire      = 0x08C.2     // TRISA bit 2 para mudar a direção do pino#define _input   1#define _output  0#define _low     0#define _high    1#define _escrita 1#define _leitura 0#INT_EXTvoid  EXT_isr(void) {  unsigned int16 _aux = 0;  unsigned int _i, _address = 0, _value = 0, _value_read = 0;  short _operacao;    pino_one_wire_escrita = _low;     // Prepara o pino com o valor 0    while(!pino_one_wire_leitura) {}  // Espera o mestre liberar a linha  delay_ms(1);                        direcao_one_wire = _output;       // Coloca zero na linha para indicar ao mestre                                    // que este escravo está presente  delay_ms(10);                     // Deixa em baixo por 10mS  direcao_one_wire = _input;        // Libera o barramento    while(pino_one_wire_leitura) {}   // Espera o mestre iniciar o envio do bit de comando    // Pegando o bit de comando  do {    delay_us(1);    _aux++;  }while(!pino_one_wire_leitura);   // Conta o tempo em que a linha ficou em nível baixo    if(_aux < 2001) {                 // menor que 2mS (2000uS) é igual a 1 recebido, operação de escrita    _operacao = _escrita;  }    else {                          // maior  que 2mS é igual a 0 recevido, operação de leitura      _operacao = _leitura;    }    // Pegando o endereço da Operação  _aux = 0;  for(_i = 0; _i < 8; _i++) {    while(pino_one_wire_leitura) {} // Espera a linha ser colocada em zero        do {      delay_us(1);      _aux++;    }while(!pino_one_wire_leitura);   // Conta o tempo em que a linha ficou em nível baixo          if(_aux < 2001) {                 // menor que 2mS (2000uS) é igual a 1 recebido      bit_set(_address, _i);          // então seta o bit correspondente.    }    // A variável _address é iniciada com zero então não há a necessidade de zerar    // o bit caso o valor recebido for zero.    _aux = 0;  }    if(_operacao == _escrita) {    // Pega o valor a ser escrito no endereço enviado pelo mestre    _aux = 0;    for(_i = 0; _i < 8; _i++) {      while(pino_one_wire_leitura) {}   // Espera a linha ser colocada em zero            do {        delay_us(1);        _aux++;      }while(!pino_one_wire_leitura);   // Conta o tempo em que a linha ficou em nível baixo              if(_aux < 2001) {                 // menor que 2mS (2000uS) é igual a 1 recebido        bit_set(_value, _i);            // então seta o bit correspondente.      }      // A variável _value é iniciada com zero então não há a necessidade de zerar      // o bit caso o valor recebido for zero.      _aux = 0;    }   write_eeprom (_address, _value);   direcao_one_wire = _output;          // Coloca a linha em zero para indicar que a escrita terminou   delay_us(5);   direcao_one_wire = _input;   }    else {                                // Se a operação for de leitura      _value_read = read_eeprom(_address);// Lê o valor armazenado na posição _address      delay_ms(20);                       // Espera o mestre se preparar para o recebimento            for (_aux = 0; _aux < 8; _aux++) {        if(bit_test(_value_read, _aux)) { // Verifica o bit a ser enviado se for 1          direcao_one_wire = _output;     // Pino em nível baixo 0          delay_ms(2);                    // por 2mS (bit 1)          direcao_one_wire = _input;      // Pino em nível alto 1          delay_ms(8);                    // por 8mS              }          else {                          // Se for 0            direcao_one_wire = _output;   // Pino em nível baixo 0            delay_ms(6);                  // por 6mS (bit 0)            direcao_one_wire = _input;    // Pino em nível alto 1            delay_ms(4);                  // por 4mS          }      }             }}  void main(){  direcao_one_wire = _input;    ext_int_edge(H_TO_L);         // Necessário para o código funcionar corretamente  enable_interrupts(INT_EXT);   // habilita a interrupção externa - Interrupção na transição de ALTO para BAIXO  enable_interrupts(GLOBAL);    // habilita todas as interrupções  //Example blinking LED program  while(true)  {    output_low(LED);    delay_ms(DELAY);    output_high(LED);    delay_ms(DELAY);  }}

 
Download:

 

Putz, fantástico!!!!! Sabe quando eu iria conseguir desenvolver isso, levaria um mês no mínimo...rssss

 

Muito obrigado, vou implementar e depois retorno com o resultado.

 

Rogério

Compartilhar este post


Link para o post
Compartilhar em outros sites

Putz, fantástico!!!!! Sabe quando eu iria conseguir desenvolver isso, levaria um mês no mínimo...rssss

 

Muito obrigado, vou implementar e depois retorno com o resultado.

 

Rogério

Estou com um problema na inicialização do one_wire onde a porta que estou utilizando não vai pra zero.

 

Utilizo um 18F2550 e a porta é a B3 segundo manual os endereços dos registradores são:

 

/******************************************************************************/
// O código precisa dos bits dos registradores TRIS e PORT referente ao pino.
#bit pino_one_wire    = 0x81.3  // bit 3 do registrador PORTB (PORTB.3)
#bit direcao_one_wire = 0x93.3  // bit 3 do registrador TRISB (TRISB.3)
#include <EEPROM_ONE_WIRE.c>
/******************************************************************************/
 
Devo estar fazendo algo de errado...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Os endereços dos registradores variam de família para família... Você pode ver os endereços na "TABLE 5-1: SPECIAL FUNCTION REGISTER MAP" do datasheet do PIC18F2550.

 

Ficaria assim:

#bit pino_one_wire    = 0xF81.3  // bit 3 do registrador PORTB (PORTB.3)#bit direcao_one_wire = 0xF93.3  // bit 3 do registrador TRISB (TRISB.3)

 

 

Estou com um problema na inicialização do one_wire onde a porta que estou utilizando não vai pra zero.

 

Repare que o pino só irá para zero quando ele for saída (TRISB.3 = 0) caso contrário (TRISB.3 = 1) ele ficará como entrada (alta impedância) e flutuará para para nível alto por causa do PULL-UP.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Os endereços dos registradores variam de família para família... Você pode ver os endereços na "TABLE 5-1: SPECIAL FUNCTION REGISTER MAP" do datasheet do PIC18F2550.

 

Ficaria assim:

#bit pino_one_wire    = 0xF81.3  // bit 3 do registrador PORTB (PORTB.3)#bit direcao_one_wire = 0xF93.3  // bit 3 do registrador TRISB (TRISB.3)

Repare que o pino só irá para zero quando ele for saída (TRISB.3 = 0) caso contrário (TRISB.3 = 1) ele ficará como entrada (alta impedância) e flutuará para para nível alto por causa do PULL-UP.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vixi xD, foi falha minha (fiz o código muito tarde HEHE), o mestre estava esperando o escravo indicar o término da escrita na EEPROM mas não esta esperando ele liberar a linha... E isso estava causando problema... Segue o novo código:

 

http://www.4shared.com/rar/b4ySljv6ce/18F2550_12F1840_ONEW.html?

 

Linha adicionada:

  // Espera o escravo colocar a linha em low para indicar que que a  // escrita na EEPROM terminou.  while(pino_one_wire) {}  //espera o escravo liberar a linha  while(!pino_one_wire) {} // <<--- ESTA LINHA FOI ADICIONADA

By5uRzE.png

 

Uma coisa... Se você escrever 'zero' ou 'um' em um pino (registrador LATX ou PORTX) o sinal só irá para o valor escrito após o pino ser colocado como saída...

 

Qualquer coisa posta ai (enquanto ainda tenho tempo :lol: )

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vixi xD, foi falha minha (fiz o código muito tarde HEHE), o mestre estava esperando o escravo indicar o término da escrita na EEPROM mas não esta esperando ele liberar a linha... E isso estava causando problema... Segue o novo código:

 

http://www.4shared.com/rar/b4ySljv6ce/18F2550_12F1840_ONEW.html?

 

Linha adicionada:

  // Espera o escravo colocar a linha em low para indicar que que a  // escrita na EEPROM terminou.  while(pino_one_wire) {}  //espera o escravo liberar a linha  while(!pino_one_wire) {} // <<--- ESTA LINHA FOI ADICIONADA

By5uRzE.png

 

Uma coisa... Se você escrever 'zero' ou 'um' em um pino (registrador LATX ou PORTX) o sinal só irá para o valor escrito após o pino ser colocado como saída...

 

Qualquer coisa posta ai (enquanto ainda tenho tempo :lol: )

Algumas dúvidas:

 

1)

 

Utilizando o simulador do Proteus funciona uma beleza, mas no hardware não vai.

 

Na compilação aparece a seguinte mensagem:

 

Interrupts disable during call to prevent re_entrancy (@delay-1ms)

 

E creio que isso não está deixando a PIC funcionar.

 

 

2) Quando tento mudar o bit da porta A do escravo pra utilizar outro pino ai nem no proteus funciona.

 

 

Sei que estou sendo muito exigente, mas reconheço que sua boa vontade está sendo super preciosa.

 

Muito Obrigado. 

Compartilhar este post


Link para o post
Compartilhar em outros sites
1) Sobre a mensagem de erro do CCS:


 

Repare que a comunicação acontece baseada no tempo então se uma interrupção ocorrer durante a comunicação (provavelmente ocorrerá pois a comunicação é extremamente lenta) a comunicação falhará e o escravo não receberá o dado corretamente, pior ainda, o mestre ou o escravo pode travar em alguma das função 'while', essa é a desvantagem de não haver um linha para o clock  :(

 

Se fosse algo por hardware beleza você carregaria o valor e o hardware o enviaria, como não é, você deverá desabilitar as interrupções antes de de escrever ou ler algo do escravo.

 

---

 

2) Sim, se você mudar o pino (do escravo) não funcionará mesmo, como eu disse em algum dos posts anteriores... Repare que o escravo usa interrupção externa (que é um pino fixo) se você colocar em outro a interrupção não ocorre e o escravo se quer notará que o mestre tentou se comunicar, quando isso ocorre a função ler ou escrever retornará o valor 1 para indicar que o escravo não respondeu.

 

Para não usar a interrupção externa seria necessário o escravo verificar a cada 200mS (no máximo) se o mestre está tentado se comunicar... Alterando o código dá para fazer isso...

 

Quanto ao hardware não funcionar...

Qual a velocidade do oscilador e a configuração (XT, HS... PLL, CPUDIV) que você está usando no hardware real?

Como não tenho um PIC12F1840 não é possível eu montar o hardware real para fazer o teste :( minha única ideia é algum erro nos FUSES referentes ao oscilador. 

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

1) Sobre a mensagem de erro do CCS:
 
Repare que a comunicação acontece baseada no tempo então se uma interrupção ocorrer durante a comunicação (provavelmente ocorrerá pois a comunicação é extremamente lenta) a comunicação falhará e o escravo não receberá o dado corretamente, pior ainda, o mestre ou o escravo pode travar em alguma das função 'while', essa é a desvantagem de não haver um linha para o clock  :(
 
Se fosse algo por hardware beleza você carregaria o valor e o hardware o enviaria, como não é, você deverá desabilitar as interrupções antes de de escrever ou ler algo do escravo.
 
---
 
2) Sim, se você mudar o pino (do escravo) não funcionará mesmo, como eu disse em algum dos posts anteriores... Repare que o escravo usa interrupção externa (que é um pino fixo) se você colocar em outro a interrupção não ocorre e o escravo se quer notará que o mestre tentou se comunicar, quando isso ocorre a função ler ou escrever retornará o valor 1 para indicar que o escravo não respondeu.
 
Para não usar a interrupção externa seria necessário o escravo verificar a cada 200mS (no máximo) se o mestre está tentado se comunicar... Alterando o código dá para fazer isso...
 
Quanto ao hardware não funcionar...
Qual a velocidade do oscilador e a configuração (XT, HS... PLL, CPUDIV) que você está usando no hardware real?
Como não tenho um PIC12F1840 não é possível eu montar o hardware real para fazer o teste :( minha única ideia é algum erro nos FUSES referentes ao oscilador. 

 

Bom....a velocidade no escravo está em 32Mhz e o fuse #FUSES INTRC_IO, reparei que quando tiro o fio de comunicação a PIC volta a funcionar (o Led pisca)  então deve haver algo na interrupção externa.

 

Eu não preciso de velocidade na comunicação e sim precisão nos dados lidos e escritos na memória do escravo. Talvez não utilizar a interrupção externa seria mais estável..

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

GRÁTIS: minicurso “Como ganhar dinheiro montando computadores”

Gabriel TorresGabriel Torres, fundador e editor executivo do Clube do Hardware, acaba de lançar um minicurso totalmente gratuito: "Como ganhar dinheiro montando computadores".

Você aprenderá sobre o quanto pode ganhar, como cobrar, como lidar com a concorrência, como se tornar um profissional altamente qualificado e muito mais!

Inscreva-se agora!