PIC: EEPROM I2C
Neste post, irei falar sobre como trabalhar com memórias externas.
24C32
Esta memória possui as seguintes características:
- Comunicação via protocolo I2C;
- Possui uma memória de 32K(4096 x 8);
- Vida útil de mais de 1000000 de ciclos de escrita;
- Data Protect;
- Pode-se conectar até 8 memórias no mesmo barramento.
CONTROL BYTE é formado pelo SLAVE ADDRESS(1010), pelo DEVICE SELECT(A2, A1, A0) e um comando (Escrita = 0, Leitura = 1).
Veja que o DEVICE SELECT é definido ligando os pinos A2, A1 e A0 da memória.
O pino WP quando no nível alto, projete a memória contra a gravação.
DOWNLOAD:
Projeto: I2C_Eeprom.zip
BIBLIOTECA:
#define Lo(param) ((char *)¶m)[0] #define Hi(param) ((char *)¶m)[1] void Eeprom_24C32A_WriteByte(char DEVICE, unsigned address, char wData) { I2C1_Start();// Envia um sinal de Start I2C1_Wr(0xA0 | (DEVICE << 1));//Envia o endereço, device e comando de escrita I2C1_Wr(Hi(address)); //envia o byte mais significativo do endereço I2C1_Wr(Lo(address)); //envia o byte menos significativo do endereço I2C1_Wr(wData); //envia o dado a ser gravado I2C1_Stop(); //sinal de stop Delay_ms(5); //tempo de uma gravação } char Eeprom_24C32A_ReadByte(char DEVICE, unsigned address) { char rData; I2C1_Start(); I2C1_Wr(0xA0 | (DEVICE << 1)); I2C1_Wr(Hi(address)); I2C1_Wr(Lo(Address)); I2C1_Repeated_Start(); I2C1_Wr(0xA1 | (DEVICE << 1));//Envia o endereço, device e comando de leitura rData = I2C1_Rd(0); I2C1_Stop(); return rData; } void Eeprom_24C32A_WriteString(char DEVICE, unsigned address, char *wData) { while(*wData != 0) { Eeprom_24C32A_WriteByte(DEVICE, address++, *(wData++)); } } void Eeprom_24C32A_ReadString(char DEVICE, unsigned address, char *rData, char Size) { char i; while(i < Size) { rData[i++] = Eeprom_24C32A_ReadByte(DEVICE, address++); } } char Eeprom_24C32A_Connected(char DEVICE) { char ack; I2C1_Start(); ack = I2C1_Wr(0xA0 | (DEVICE << 1));//retorna 0 se nao houver erro I2C1_Stop(); return !ack; }
EXEMPLO
char nome[16]; void main() { I2C1_Init(100000);//inicia modulo i2c UART1_Init(9600); delay_ms(10); Eeprom_24C32A_WriteByte(0, 0, 0x05);//escreve o valor 0x05 no endereço 0 do dispositivo 0 Eeprom_24C32A_WriteByte(1, 0, 0x01);//escreve o valor 0x01 no endereço 0 do dispositivo 1 Eeprom_24C32A_WriteString(0, 1, "TiagoHenrique");//escreve uma string a partir do endereço 1 Eeprom_24C32A_ReadString(0, 1, nome, 13);//faz a leitura de 13 caracter a partir do endereço 1 Uart1_write_text(nome); }
24C04
Esta memória possui as seguintes características:
- Comunicação via protocolo I2C;
- Possui uma memória de 4K(512 x 8);
- Vida útil de mais de 1000000 de ciclos de escrita;
- Data Protect;
- Pode-se conectar até 4 memórias no mesmo barramento.
a sequencia de escrita e leitura é a mesma para o 24C32, mas o CONTROL BYTE diferencia pelo bit 1, que é o bit de seleção do banco de memória.
BIBLIOTECA
void Eeprom_24C04_WriteByte( char DEVICE, unsigned Address, char _data ) { I2C1_Start();// Envia um sinal de Start //Envia o device, Select Bank, e comando de escrita I2C1_Wr(0xA0 | (DEVICE << 2) | ( ((char*)&Address)[1].B0 << 1) ); I2C1_Wr( ((char*)&Address)[0] ); //envia o endereço I2C1_Wr( _data ); //envia o dado a ser gravado I2C1_Stop(); //sinal de stop Delay_ms(5); //tempo de uma gravação } char Eeprom_24C04_ReadByte( char DEVICE, unsigned Address ) { char device_addr = 0xA0 | (DEVICE << 2) | ( ((char*)&Address)[1].B0 << 1); char _data; I2C1_Start();// Envia um sinal de Start //Envia o device, Select Bank, e comando de escrita I2C1_Wr( device_addr ); I2C1_Wr( ((char*)&Address)[0] ); //envia o endereço I2C1_Repeated_Start(); I2C1_Wr( device_addr | 1 ); _data = I2C1_Rd(0); I2C1_Stop(); //sinal de stop return _data; }
ola
ResponderExcluirgostei do blog ta show.
agora me diz como faço para gravar um valor de 32bit ex um valor de 0 ate 999999 utilizando a memoria 24c04 ,você poderia postar um exemplo pra mim ter uma noção ? Pois ainda sou iniciante em C
obrigado
Olá, obrigado.
Excluirum valor de 32bits possui 4 bytes, entao voce tem que enviar um byte de cada vez.
((char*)&Valor)[0] - é o byte menos significativo ( 0xDD )
((char*)&Valor)[3] - é o byte mais significativo ( 0xAA )
Exemplo:
unsigned long Valor = 0xAABBCCDD;
for( i = 0 ; i < 4 ; i++ )
{
Eeprom_24C04_WriteByte( _device, _address++, ((char*)&Valor)[i] );
}
Ola não entendi ,eu tenho um codigo simples por ex um receptor de fm que funciona em 88,000 ate 108000 mhz,queria gravar frequencias preferidas na memoria eeprom do pic ,seria possível me dizer como devo proceder uma rotina para fazer isso ?
Excluirex
88000 =00000000 00000001 01010111 11000000
108000=00000000 00000001 10100101 11100000
unsigned long frequencia = 88000;
Excluir//Grava no endereço 0, o byte menos significativo
Eeprom_24C04_WriteByte( DEVICE, 0, ((char*)&Frequencia)[0] ); //00000000
//Grava no endereço 1, o segundo byte
Eeprom_24C04_WriteByte( DEVICE, 1, ((char*)&Frequencia)[1] ); //00000001
//Grava no endereço 2, o terceiro byte
Eeprom_24C04_WriteByte( DEVICE, 2, ((char*)&Frequencia)[2] ); //01010111
//Grava no endereço 3, o byte mais significativo
Eeprom_24C04_WriteByte( DEVICE, 3, ((char*)&Frequencia)[3] ); //11000000
Para fazer a leitura
((char*)&Frequencia)[0] = Eeprom_24C04_ReadByte( DEVICE, 0 );
((char*)&Frequencia)[1] = Eeprom_24C04_ReadByte( DEVICE, 1 );
((char*)&Frequencia)[2] = Eeprom_24C04_ReadByte( DEVICE, 2 );
((char*)&Frequencia)[3] = Eeprom_24C04_ReadByte( DEVICE, 3 );
Ok ,deu pra entender ,se caso eu resolver gravar na memoria eeprom do pic ,e o mesmo procedimento ?
Excluirposso enviar para o seu email o Código fonte para que voce possa analisar ?
ExcluirPara realizar a gravação na eeprom pode utilizar o mesmo procedimento. E pode enviar pro meu email sim.
ExcluirOla amigo fiz assim mais não funciona
ResponderExcluirvoid grava (void)
//Gravar
{
EEPROM_Write(0,(unsigned char)((freq & [0]);//>>24));
EEPROM_Write(1,(unsigned char)((freq & [1]);//>>16));
EEPROM_Write(2,(unsigned char)((freq& [2]);//>>8));
EEPROM_Write(3,(unsigned char)((freq & [3]);
//////////////////////////////////////////////////////
}
void leitura (void)
//Ler
{
freq = (unsigned long)(EEPROM_Read(0)<<24);
freq = (unsigned long)(EEPROM_Read(1)<<16);
freq = (unsigned long)(EEPROM_Read(2)<<8);
freq = (unsigned long)(EEPROM_Read(3));
}*/
tem que ser assim:
Excluirvoid grava (void)
//Gravar
{
EEPROM_Write(0, ((char*)&freq)[0] ); //byte menos significativo
EEPROM_Write(1, ((char*)&freq)[1] );
EEPROM_Write(2, ((char*)&freq)[2] );
EEPROM_Write(3, ((char*)&freq)[3] ); //byte mais significativo
//////////////////////////////////////////////////////
}
void leitura (void)
//Ler
{
((char*)&freq)[0] = EEPROM_Read(0); //byte menos significativo
((char*)&freq)[1] = EEPROM_Read(1);
((char*)&freq)[2] = EEPROM_Read(2);
((char*)&freq)[3] = EEPROM_Read(3); //byte mais significativo
}
Explicação:
Excluir( (char*) &freq )[0]
(char*) - Cria um ponteiro e aponta para o endereço de "freq" &freq . Um valor será gravado no endereço de "freq" + 0 [0]
Legal funcionou !!
ResponderExcluirobrigado
Ola poderia me ajudar com devo proceder para incrementar um botao para alterar a banda do radio ?
ResponderExcluirpressiona o botao entra no loop do programa pressiona novamente sai do loop ,a função seria alterar a banda do radio fm/am seria bom também memorizar o estado da chave na eeprom .
obrigado
Boa tarde. Quanto a ligação entre um PIC18F2550 e um 24C32, é obrigatório ligar nos pinos SDA e SCL do PIC ou se ligar em outros pinos do PIC vai funcionar também?
ResponderExcluirAtt,
Isso vai depender de como voce ira programar. Se voce utilizar o módulo I2C interno do pic para realizar a comunicação I2C, DEVERÁ utilizar os pinos SDA e SCL, pois são os pinos do módulo.
ExcluirVocê também pode emular o I2C( principalmente em pics que não suportam o I2C ) na qual você pode utilizar quaisquer pino. Para emular você utiliza a biblioteca "Soft_I2C" do MikroC PRO PIC.
OLa
ResponderExcluirVoce teria uma biblioteca pronta para incluir memoria 24c04 ,vi a sua mais aqui não funcionou me parece que e para ser utilizada com mais de 1 eprom não e isso ? seria Possível fazer para usar somente 1 eeprom ?
obrigado
Esta biblioteca pode comandar ate 4 memorias eeproms. Verifica se definiu o endereço do dispositivo no barramento corretamente.
Excluiracho que sim amigo ,veja abaixo a blioteca e minha rotina .
Excluirvoid Eeprom_24C04_WriteByte( char DEVICE, unsigned Address, char _data )
{
Soft_I2C_Start();// Envia um sinal de Start
//Envia o device, Select Bank, e comando de escrita
Soft_I2C_Write(0xA0 | (DEVICE << 2) | ( ((char*)&Address)[1].B0 << 1) );
Soft_I2C_Write( ((char*)&Address)[0] ); //envia o endereço
Soft_I2C_Write( _data ); //envia o dado a ser gravado
Soft_I2C__Stop(); //sinal de stop
Delay_ms(5); //tempo de uma gravação
}
char Eeprom_24C04_ReadByte( char DEVICE, unsigned Address )
{
char device_addr = 0xA0 | (DEVICE << 2) | ( ((char*)&Address)[1].B0 << 1);
char _data;
Soft_I2C_Start();// Envia um sinal de Start
//Envia o device, Select Bank, e comando de escrita
Soft_I2C_Write( device_addr );
Soft_I2C_Write( ((char*)&Address)[0] ); //envia o endereço
Soft_I2C_Start();
Soft_I2C_Write( device_addr | 1 );
_data = I2C1_Rd(0);
Soft_I2C_Stop(); //sinal de stop
return _data;
}
/////////minha rotina para ler e gravar////////////
void salvarm (void)
//Gravar
{
nr=chl*4; //variar o valor da eeprom para gravação. Inicia com o zero
Eeprom_24C04_WriteByte(nr, ((char*)&freq)[0] ); //byte menos significativo
Eeprom_24C04_WriteByte(nr+1, ((char*)&freq)[1] );
Eeprom_24C04_WriteByte(nr+2, ((char*)&freq)[2] );
Eeprom_24C04_WriteByte(nr+3, ((char*)&freq)[3] ); //byte mais significativo
//delay_ms(20);
//////////////////////////////////////////////////////
//grava_lcd();
if (nr <= 4){
nr = 4;
}
if (nr > 80){
nr = 80;
}
if (chl <= 1){
chl = 1;
}
if (chl > 20){
chl = 20;
}
grava_lcd();
}
void leituram (void)
//Ler
{
nr=chl*4; //variar o valor da eeprom para gravação. Inicia com o zero
((char*)&freq)[0] = Eeprom_24C04_ReadByte(nr); //byte menos significativo
((char*)&freq)[1] = Eeprom_24C04_ReadByte(nr+1);
((char*)&freq)[2] = Eeprom_24C04_ReadByte(nr+2);
((char*)&freq)[3] = Eeprom_24C04_ReadByte(nr+3); //byte mais significativo
//delay_ms(90);
if (nr <= 4){
nr = 4;
}
if (nr > 80){
nr = 80;
}
if (chl <= 1){
chl = 1;
}
//}
if (chl >=20){
chl = 20;
}
ler_lcd();
}
Como eu faria para escrever 3 nomes na 24C04, e que tivessem dois botões, clicando no primeiro botão eu ficaria mostrando os nomes da memória em um lcd 16x2, e apertando o segundo eu apagaria e gravaria esses nomes?
ResponderExcluirOlá, o blog é muito bom!
ResponderExcluirMas tenho uma dúvida, gostaria de escrever no meu PIC (não importando qual memória) Dados provenientes das entradas analógicas dele. Como posso proceder?
Olá, muito boa sua biblioteca, parabéns, funciona certinho.
ResponderExcluirSó uma dúvida que tenho aqui, como eu faria para guardar uma imagem gerada pelo utilitário do KS0108 dentro da eeprom? e como ler ela depois?
Primeiro voce deve gravar a imagem dentro da eeprom utilizando um gravador de EEPROM.
ExcluirDepois para ler,você usa as funções da biblioteca acima.
Obrigado pela velocidade da resposta, mas como eu não tenho um gravador de eeprom, pensei em fazer o seguinte:
ExcluirMétodo preguiçoso: Compilo o código com duas imagens e mando escrever elas na eeprom pelo próprio PIC, em tempo de execução. Troco os vetores das imagens, trocos os endereços, compilo, e escrevo elas na eeprom... E assim por diante, até ter todas na eeprom, aí faço o programa que só lê e joga no meu LCD... Será que dá certo?
Dá certo sim :) É melhor do que comprar um gravador né!
ExcluirSim rsrs... Obrigadão... Abraços.
Excluirola, vc conseguiu fazer leitura das imagem do glcd , mas como consigo ler varias imagem dentro da memoria AT24c512
ExcluirAmigo para 24c1024 ou 24c512 seria a mesma coisa ou mudaria algo no hardware e software ,se não vc poderia me dar um exemplo.Desde já agradeço.
ResponderExcluirOlá gostaria de saber como faço pra criar um código para sensor de irrigação usando microcontrolador pic12f675 usando compilador mikroC.
ResponderExcluirEste comentário foi removido pelo autor.
ResponderExcluirExelente Amigo
ResponderExcluircomo eu faço para incluir outra memoria que não sejam as citadas acima? exemplo, se eu quisesse usar uma 24lc512? somente ela sem outra memoria junto
ResponderExcluirUma ideia era o projeto de um sensor de irrigação inteligente. Uma boa tarde
ResponderExcluir