Ir ao conteúdo
  • Cadastre-se

Comunicação entre PIC´s


Posts recomendados

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?

Link para o comentário
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...

Link para o comentário
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.

Link para o comentário
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.

Link para o comentário
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:
 
Link para o comentário
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

Link para o comentário
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...
Link para o comentário
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.

Link para o comentário
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.

Link para o comentário
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
Link para o comentário
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. 

Link para o comentário
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. 

Link para o comentário
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..

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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...