Biblioteca MikroC PRO for PIC: I2C
BIBLIOTECA I2C
MikroC PRO for PIC oferece a biblioteca que suporta o modo master I2C.
Alguns MCUs ter vários módulos I2C. A fim de utilizar o desejadorotina da biblioteca, basta alterar o número 1 no protótipo com o número do módulo adequado.
Rotinas
I2C1_Init(const unsigned long clock) - Inicializa o módulo I2C com o clock desejado
clock- Clock em Hertz;I2C1_Start() - Determina o barramento como livre, e envia um sinal de START;I2C1_Repeated_Start() - Repete o sinal de START;I2C1_Is_Idle() - Retorna 1 se o barramento estiver livre caso contrário 0;I2C1_Rd(unsigned short ack) - Lê um byte do escravo e não envia um sinal dereconhecimento se ack for 0, ou seja, termina a leitura, caso contrário ele envia
um sinal acknowledge e prepara para fazer a próxima leitura.ack- sinal de reconhecimento (acknowledge);EXEMPLO:I2C1_Wr(unsigned short data) - Envia um byte para o escravo.data- byte a ser enviado ao escravo; I2C1_Stop() - Envia um sinal de STOP.void main(){ ANSEL = 0; // Configure AN pins as digital I/O ANSELH = 0; PORTB = 0; TRISB = 0; // Configure PORTB as output I2C1_Init(100000); // initialize I2C communication I2C1_Start(); // issue I2C start signal I2C1_Wr(0xA2); // send byte via I2C (device address + W) I2C1_Wr(2); // send byte (address of EEPROM location) I2C1_Wr(0xAA); // send data (data to be written) I2C1_Stop(); // issue I2C stop signal Delay_100ms(); I2C1_Start(); // issue I2C start signal I2C1_Wr(0xA2); // send byte via I2C (device address + W) I2C1_Wr(2); // send byte (data address) I2C1_Repeated_Start(); // issue I2C signal repeated start I2C1_Wr(0xA3); // send byte (device address + R) PORTB = I2C1_Rd(0u); // Read the data (NO acknowledge) I2C1_Stop(); // issue I2C stop signal }
caro colega voce pode escrever um codigo utilizando memeoria E2prom 25AA320, essa memoria utiliza o protocolo SPI.
ResponderExcluirolá, talvez hoje mesmo faço isso. Abraços.
ExcluirEstou tendo alguns problemas para comunicar o PIC 18f4550 com um módulo I2C (PCF8574AT) e um LCD 16x2. Consegui utilizar o Arduino Mega e a biblioteca LiquidCrystal I2C, mas no MikroC e Proteus não funciona seu eu coloco o endereço do Ci do módulo (0x3f). No datasheet mostra que esse endereço ignora o último bit do byte, justamente o que define se será leitura ou escrita (R/W). Se eu utilizo outro endereço a simulação funciona, mas na prática não. Com Arduino da certo, mas no PIC não. Estou utilizando uma biblioteca que baixei do canal Vitor Santos do Youtube, onde ele mostra uma aplicação com esse CI e um PIC16. Será que alguém poderia me ajudar?
ResponderExcluirConseguiu resolver o problema ? estou tendo o mesmo problema que vc.
Excluiratt
Cara, eu resolvi, mas faz muito tempo já. Nem lembro como fiz. O que recomendo é que vc use Arduino para descobrir o endereço do PCF8574 e olhar no datasheet qual configuracao para esse endereço.
ExcluirAmigo bom dia. Como eu faria para enviar um hexa do tipo 0x1C2A? Eu tento enviar mas só vai os últimos 2 dígitos...
ResponderExcluirAmigo bom dia. Como eu faria para enviar um hexa do tipo 0x1C2A? Eu tento enviar mas só vai os últimos 2 dígitos...
ResponderExcluirI2C1_Wr(0x2A);
ExcluirI2C1_Wr(0x1C);
Tiago obrigado pela pronta resposta. Realmente funciona, entretanto eu recebo um numero de 16 bits que gera um hexa com 2 nibbles, exemplo: 0x1234 como separo os nibbles antes de enviar via I2C ? Obrigado!
Excluirunsigned int valor = 0x1234; //valor inteiro de 16bits
ExcluirI2C1_Wr( valor & 0x0F ); //4, nibble menos significativo
I2C1_Wr( (valor >> 4) & 0x0F ); //3
I2C1_Wr( (valor >> 8) & 0x0F ); //2
I2C1_Wr( (valor >> 12) & 0x0F ); //1, nibble mais significativo
Tiago bom dia!! Muito obrigado pela resposta consegui resolver usando sua ideia, mas com a seguinte modificação:
ResponderExcluirI2C1_Wr( valor & 0xFF ); //4, nibble menos significativo
I2C1_Wr( (valor >> 8) & 0xFF ); //2 nibble mais significativo
Aproveitando, eu agora estou com dificuldade na leitura....
Só estou conseguindo ler 1 nibble....
unsigned int retornomem;
I2C1_Start();
I2C1_Wr(0xA0 | (DEVICE << 1));
I2C1_Wr(((char *)&address)[1]);
I2C1_Wr(((char *)&address)[0]);
I2C1_Repeated_Start();
I2C1_Wr(0xA1 | (DEVICE << 1));//Envia o endereço, device e comando de leitura
retornomem = I2C1_Rd(0);
I2C1_Stop();
delay_ms(15);
Gostaria de ler novamente o valor inteiro.... ex: 0xABCD