Ir ao conteúdo

Posts recomendados

Postado

Boa noite pessoal!

Não entendo bulufas de linguagem C, de lógica de programação e de um monte de outras coisas.

Até o momento, o que aprendi sobre pic foi acessando os fóruns, you tube e batendo a cabeça! Sei que estou fazendo errado, que ao queimar etapas o processo de aprendizagem fica comprometido, mas, como sou teimoso!

 

Estou desenvolvendo um pequeno dispositivo que tem a função de controlar o tempo de uso de uns equipamentos e programar as manutenções preventivas.

 

O motor funciona 30 horas e pede manutenção;

após a manutenção ser executada, ele grava na eeprom as horas de uso e programa a próxima parada para 300 horas depois (isso mesmo, 300 horas) e assim sucessivamente.

 

Como tenho limite de 8 bits para um endereço da eeprom, como faço para gravar uma variável com números superiores a 255?

 

Utilizo o MikroC e estou usando um PIC 18F4520 que tenho aqui para teste.

 

OBS> as gravações feitas na EEprom são de 10 em 10 horas de uso.

 

 

Postado

Oá  amigo. Tu está fazendo certo. Colocando a mão na massa.

 

E não entendo bulhufas de microC.

 

Mas digamos que tu queira armazenar um valor de uma variavel de 16 bits numa posição da EEPROM.

 

Tu utiliza a EEPROM de endereço 0x10 para gravar a parte alta da variável e o endereço 0x11 para armazenar a parte baixa.

 

EX: Valor: 0xABCD 

 

0x10 = 0xAB

0x11 = 0xCD

 

Utiliza os operadores << e >> para isso.

 

OBS: Tem que cuidar o limite de vezes que se grava na EEPROM (dependendo do pic, é 1 milhão de vezes)

O ideal é tu fazer um código que leia o valor que está na EEPROM e caso seja diferente, daí sim, efetuar o armazenamento. 

 

Enfim, qualquer coisa estamos ae

  • Curtir 2
  • Membro VIP
Postado

boa rafa!

void grava16(unsigned int dado,unsigned char endereco){eepromwrite(endereco,dado);dado>>=8;eepromwrite(endereco+1,dado);}  unsigned int le16(unsigned char endereco){unsigned int dado;dado=eepromread(endereco+1);dado<<=8;dado|=eepromread(endereco);return dado;}

Sem comentários...(!)

  • Curtir 3
Postado

Oá  amigo. Tu está fazendo certo. Colocando a mão na massa.

 

E não entendo bulhufas de microC.

 

Mas digamos que tu queira armazenar um valor de uma variavel de 16 bits numa posição da EEPROM.

 

Tu utiliza a EEPROM de endereço 0x10 para gravar a parte alta da variável e o endereço 0x11 para armazenar a parte baixa.

 

EX: Valor: 0xABCD 

 

0x10 = 0xAB

0x11 = 0xCD

 

Utiliza os operadores << e >> para isso.

 

OBS: Tem que cuidar o limite de vezes que se grava na EEPROM (dependendo do pic, é 1 milhão de vezes)

O ideal é tu fazer um código que leia o valor que está na EEPROM e caso seja diferente, daí sim, efetuar o armazenamento. 

 

Enfim, qualquer coisa estamos ae

 

boa rafa!

void grava16(unsigned int dado,unsigned char endereco){eepromwrite(endereco,dado);dado>>=8;eepromwrite(endereco+1,dado);}  unsigned int le16(unsigned char endereco){unsigned int dado;dado=eepromread(endereco+1);dado<<=8;dado|=eepromread(endereco);return dado;}

Sem comentários...(!)

 

 

 

Oi Rafa, já tinha visto em um post semelhante esta solução que você sugeriu. Como meu problema é justamente o conhecimento básico, terei que bater mais a cabeça! Minha principal dúvida é como fazer a união das duas variáveis alta e baixa em uma nova variável. Quanto a eeprom estou ciente desta limitação, no entanto este programa funcionará de forma semelhante ao marcador de km dos carros, ou seja, ficará sempre registrando os valores (10 em 10 horas) para que em uma falta de energia eles não se percam. Abs e obrigado!

  • Membro VIP
Postado

Oá  amigo. Tu está fazendo certo. Colocando a mão na massa.

 

E não entendo bulhufas de microC.

 

Mas digamos que tu queira armazenar um valor de uma variavel de 16 bits numa posição da EEPROM.

 

Tu utiliza a EEPROM de endereço 0x10 para gravar a parte alta da variável e o endereço 0x11 para armazenar a parte baixa.

 

EX: Valor: 0xABCD 

 

0x10 = 0xAB

0x11 = 0xCD

 

Utiliza os operadores << e >> para isso.

 

OBS: Tem que cuidar o limite de vezes que se grava na EEPROM (dependendo do pic, é 1 milhão de vezes)

O ideal é tu fazer um código que leia o valor que está na EEPROM e caso seja diferente, daí sim, efetuar o armazenamento. 

 

Enfim, qualquer coisa estamos ae

@André Leal

E na hora que for ler, crie uma variável tipo WORD como X16 e 2 tipo byte como Xh e Xl.

Leia o valor armazenado em 0x10 da eeprom e multiplique por 256.

X16=Xh * 256

 

Agora é só ler o valor do endereço 0x11 e somar.

X16=X16+Xl.

 

Bom... a sintaxe em C é com vocês.

  • Curtir 1
Postado

Oá  amigo. Tu está fazendo certo. Colocando a mão na massa.

 

E não entendo bulhufas de microC.

 

Mas digamos que tu queira armazenar um valor de uma variavel de 16 bits numa posição da EEPROM.

 

Tu utiliza a EEPROM de endereço 0x10 para gravar a parte alta da variável e o endereço 0x11 para armazenar a parte baixa.

 

EX: Valor: 0xABCD 

 

0x10 = 0xAB

0x11 = 0xCD

 

Utiliza os operadores << e >> para isso.

 

OBS: Tem que cuidar o limite de vezes que se grava na EEPROM (dependendo do pic, é 1 milhão de vezes)

O ideal é tu fazer um código que leia o valor que está na EEPROM e caso seja diferente, daí sim, efetuar o armazenamento. 

 

Enfim, qualquer coisa estamos ae

 

boa rafa!

void grava16(unsigned int dado,unsigned char endereco){eepromwrite(endereco,dado);dado>>=8;eepromwrite(endereco+1,dado);}  unsigned int le16(unsigned char endereco){unsigned int dado;dado=eepromread(endereco+1);dado<<=8;dado|=eepromread(endereco);return dado;}

Sem comentários...(!)

 

 

Oi Isadora você deu um nó no tico e no teco!

Na primeira parte eu entendi o seguinte: você grava na eeprom o que tiver na variável dado, depois desloca 8 bits para a direita (talvez seja para limpar a memória) certo? e o que sobrar você salva na variável dado no (endereço + 1) EX: quero salvar o número 256, ele grava em endereço: "11111111" depois grava em (endereço + 1) "00000001" seria isso?

Já na outra parte eu estou tentando entender mas antes preciso saber se meu raciocínio está correto.

A propósito, Tico e Teco são meus dois neurônios!

 

Obrigado,

André Leal.

 

 

 

 

  • Membro VIP
Postado

Multiplicar um valor por 256 (2^8) é o mesmo que deslocar 8 bits a esquerda, só que já verifiquei que é mais rápido multiplicfar do que deslocar.

  • Curtir 2
Postado

Multiplicar um valor por 256 (2^8) é o mesmo que deslocar 8 bits a esquerda, só que já verifiquei que é mais rápido multiplicfar do que deslocar.

 

Muito boa essa. Vivendo e aprendendo

  • Curtir 1
  • Membro VIP
Postado

A lógica é simples:

Toda vez que se desloca o conteúdo de uma variável a esquerda, o resultado é o dobro do valor contido antes.

Deslocando 8 vezes é o mesmo que fazer x = x * (2^8).

Claro que a variável tem que caber o número de bits do resultado final.

O deslocamento à direita é o mesmo que dividir por 2 em cada deslocamento. Claro que se o bit mais a direita for 1, ele será perdido.

Por que multiplicar é mais rápido?

Porque a maioria dos MCUs atuais, a multiplicação pode ser feita num unico ciclo de máquina, já para deslocar 8x seria necessário uma rotina com 8 deslocamentos individuais ou um loop FOR com 8 ciclos.

  • Curtir 1
  • Membro VIP
Postado

é... principalmente se o mc tiver incorporado um multiplicador 8 bits no hw.

Amigo @André Leal meu tico morreu e o teco teve um treco. Então eu tenho teco treco (aff fraquinha esta). Tentemos com comentários então. Também com a maneira do amigo @_xyko_

void grava16(unsigned int dado,unsigned char endereco){eepromwrite(endereco,dado); //grava LSB - byte menos siginificativo. A rotina eepromwrite deve desconsiderar o MSBdado=dado/256;//move o MSB - dado mais siginificativo para a direita. Ficará na direita LSBeepromwrite(endereco+1,dado);//grava o dado no endereço seguinte}  unsigned int le16(unsigned char endereco){unsigned int dado;dado=eepromread(endereco+1);//lê 1º o MSB gravado previamentedado=dado*256;//desloca pra posição corretadado=dado+eepromread(endereco);//soma (ou concantena) com o LSBreturn dado;}

 

Uma 'taquigrafia' pra ler uma variável int da eeprom seria

unsigned int le16(unsigned char endereco){return eepromread(endereco+1)*256 + eepromread(endereco);}

Digito online... não me importo (muito) com enganos


chico quase nos sincronizamos...

  • Curtir 1
Postado

é... principalmente se o mc tiver incorporado um multiplicador 8 bits no hw.

Amigo @André Leal meu tico morreu e o teco teve um treco. Então eu tenho teco treco (aff fraquinha esta). Tentemos com comentários então. Também com a maneira do amigo @_xyko_

void grava16(unsigned int dado,unsigned char endereco){eepromwrite(endereco,dado); //grava LSB - byte menos siginificativo. A rotina eepromwrite deve desconsiderar o MSBdado=dado/256;//move o MSB - dado mais siginificativo para a direita. Ficará na direita LSBeepromwrite(endereco+1,dado);//grava o dado no endereço seguinte}  unsigned int le16(unsigned char endereco){unsigned int dado;dado=eepromread(endereco+1);//lê 1º o MSB gravado previamentedado=dado*256;//desloca pra posição corretadado=dado+eepromread(endereco);//soma (ou concantena) com o LSBreturn dado;}

Uma 'taquigrafia' pra ler uma variável int da eeprom seria

unsigned int le16(unsigned char endereco){return eepromread(endereco+1)*256 + eepromread(endereco);}

Digito online... não me importo (muito) com enganos

chico quase nos sincronizamos...

Ok pessoal. Vou procurar um prédio para acelerar em 9,8 m/s² minha eutanásia. Caso não encontre-o voltarei aqui no fórum. E eu que me senti importante quando fiz um led piscar com um pic! Agora toma! Muito obrigado a todos!

  • Membro VIP
Postado

Pra fazer um serviço bem feito, pratique primeiro amigo. Ah mas antes também pratique um pouco mais de linguagem c. Se estiver achando difícil, parta pro basic. Mas lembre-se que não existiria basic se não fosse o c.

Seria basi

Postado

é... principalmente se o mc tiver incorporado um multiplicador 8 bits no hw.

Amigo @André Leal meu tico morreu e o teco teve um treco. Então eu tenho teco treco (aff fraquinha esta). Tentemos com comentários então. Também com a maneira do amigo @_xyko_

void grava16(unsigned int dado,unsigned char endereco){eepromwrite(endereco,dado); //grava LSB - byte menos siginificativo. A rotina eepromwrite deve desconsiderar o MSBdado=dado/256;//move o MSB - dado mais siginificativo para a direita. Ficará na direita LSBeepromwrite(endereco+1,dado);//grava o dado no endereço seguinte}  unsigned int le16(unsigned char endereco){unsigned int dado;dado=eepromread(endereco+1);//lê 1º o MSB gravado previamentedado=dado*256;//desloca pra posição corretadado=dado+eepromread(endereco);//soma (ou concantena) com o LSBreturn dado;}

Uma 'taquigrafia' pra ler uma variável int da eeprom seria

unsigned int le16(unsigned char endereco){return eepromread(endereco+1)*256 + eepromread(endereco);}

Digito online... não me importo (muito) com enganos

chico quase nos sincronizamos...

 

Vamos ver se entendi:

 

Supondo que dado == 260:

 

dado = 260

eepromwrite(17,260);

dado = 4/256;          // aqui dado assume valor == 0.

eeprom_write(18,0); //grava o dado no endereço seguinte

}

 

 

 

dado = eeprom_read(18);                                //lê 1º o MSB gravado previamente

dado = 0 * 256;                                                  //desloca pra posição correta

dado = 0 + eeprom_read(17);                           //soma (ou concantena) com o LSB

return dado;

dado == 4

}

 

Desta forma não estou conseguindo obter o resultado correto!

 

Onde meu raciocínio está errado?

  • Membro VIP
Postado

vamos lá...

260 é 0x0104 em hex. espero que não precise explicar isso...

eepromwrite(17,0x0104);//260 em hex

neste caso como a rotina eepromwrite espera um dado tipo char no segundo argumento, ela vai considerar APENAS o 0x04 e nem vai dar bola pro 0x01
Não é 4/256 e sim 260/256 vai dar 1 inteiro=0x01. MC´s normais não gostam e nem trabalham com fracionários
eepromwrite(18,0x01);//grava o dado no endereço seguinte

Portanto você vai ter 0x01 no end 18 e 0x04 no end 17

 

**********  Tarefa ***********

Tente agora entender como fazer a recomposição da variável inteira (unsigned int) a partir de dois bytes (unsigned char)

Dica: não é 0*256. É dado*256.  dado=dado*256 é o mesmo que dado*=256 ou dado=dado<<8 ou dado<<=8 em c. São hábitos programacionais (inventei isso agora) .

 

Se ainda não entendeu, paciência ... é meu sobrenome

 

Em tempo... hábitos no início são teias de aranha. Com o tempo se tornam fios de arame

  • Obrigado 1
Postado

vamos lá...

260 é 0x0104 em hex. espero que não precise explicar isso...

eepromwrite(17,0x0104);//260 em hex

neste caso como a rotina eepromwrite espera um dado tipo char no segundo argumento, ela vai considerar APENAS o 0x04 e nem vai dar bola pro 0x01

Não é 4/256 e sim 260/256 vai dar 1 inteiro=0x01. MC´s normais não gostam e nem trabalham com fracionários

eepromwrite(18,0x01);//grava o dado no endereço seguinte

Portanto você vai ter 0x01 no end 18 e 0x04 no end 17

 

**********  Tarefa ***********

Tente agora entender como fazer a recomposição da variável inteira (unsigned int) a partir de dois bytes (unsigned char)

Dica: não é 0*256. É dado*256.  dado=dado*256 é o mesmo que dado*=256 ou dado=dado<<8 ou dado<<=8 em c. São hábitos programacionais (inventei isso agora) .

 

Se ainda não entendeu, paciência ... é meu sobrenome

 

Em tempo... hábitos no início são teias de aranha. Com o tempo se tornam fios de arame

Obrigado Isadora P. Ferraz,

continuarei aqui com suas explicações.

Postado

vamos lá...

260 é 0x0104 em hex. espero que não precise explicar isso...

eepromwrite(17,0x0104);//260 em hex

neste caso como a rotina eepromwrite espera um dado tipo char no segundo argumento, ela vai considerar APENAS o 0x04 e nem vai dar bola pro 0x01

Não é 4/256 e sim 260/256 vai dar 1 inteiro=0x01. MC´s normais não gostam e nem trabalham com fracionários

eepromwrite(18,0x01);//grava o dado no endereço seguinte

Portanto você vai ter 0x01 no end 18 e 0x04 no end 17

 

**********  Tarefa ***********

Tente agora entender como fazer a recomposição da variável inteira (unsigned int) a partir de dois bytes (unsigned char)

Dica: não é 0*256. É dado*256.  dado=dado*256 é o mesmo que dado*=256 ou dado=dado<<8 ou dado<<=8 em c. São hábitos programacionais (inventei isso agora) .

 

Se ainda não entendeu, paciência ... é meu sobrenome

 

Em tempo... hábitos no início são teias de aranha. Com o tempo se tornam fios de arame

Prezada Izadora e prezados Rafael e Xyco. Agradeço muito a paciência e atenção de vocês. Bati muito a cabeça e mesmo com as dicas que recebi não estava obtendo êxito. Não sei se tem alguma coisa relacionada com o simulador ou com o próprio PIC mas quando estava quase desistindo ( digo quase porque nunca desisto) resolvi inserir um delay de 2segundos e aí começou a funcionar! Talvez não seja a solução certa mas digo a vocês uma coisa, ninguém vai tirar aquele delayzinho dali nem na marra!!! Obrigado mais uma vez!

  • Membro VIP
Postado

 

Após escritas consecutivas na EEPROM é bom esperar o término da escrita anterior.

while(EECON1.WR){} //PIC16F877A

E o resultado  ???

Compartilha.

  • Curtir 1
  • mês depois...
Postado

Eu faço assim pra gravar uma valor maior que 255 na eeprom usando o CCS

int16 conta=1023;//para gravar:write_eeprom(0,conta % 256); // grava resto da divisão de conta por 256 na posição 0 write_eeprom(1,conta / 256); // grava quociente da div. Inteira de conta por 256 na posição 1//para ler:conta = read_eeprom(0) + (long) read_eeprom(1)*256; // lê valor do endereço 0 e 1, recompondo-o. 

Espero ter ajudado..

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...