Ir ao conteúdo
  • Cadastre-se
Ofioneu

Float na eeprom arduino

Recommended Posts

Veja isso vindo do c que surreal...
 

float float_na_eeprom;
unsigned char ponteiro;
ponteiro = &float_na_eeprom;

eepwrite(0,*((unsigned char *)(ponteiro)+0));
eepwrite(1,*((unsigned char *)(ponteiro)+1));
eepwrite(2,*((unsigned char *)(ponteiro)+2));
eepwrite(3,*((unsigned char *)(ponteiro)+3));

Ponteiros, vetores em c .. até hoje tenho 'pavor' deles!

 

Esta abaixo foi criação 100% minha mesmo. struct union me só 'muito medo'

Verifique se a linguagem do arduino que se  se assemelha ao C tem as outras apavorantes "palavras mágicas" struct e union e se sua estrutura é igual à do C
 

struct float_struct        //estrutura de 4 bytes do float 32 bits
{
unsigned char _byte0;
unsigned char _byte1;
unsigned char _byte2;
unsigned char _byte3;
};
union  
{
struct float_struct float_byte;  //4 bytes contidos em...
float _float;      //32 bits
} float_union; //união dos 4 bytes

#define float0 float_union._float  //float todo dividido em
#define byte0 float_union.float_byte._byte0    //4 bytes
#define byte1 float_union.float_byte._byte1
#define byte2 float_union.float_byte._byte2
#define byte3 float_union.float_byte._byte3

 

Ao gravar/acessar os 4 bytes, a variável float_union é montada/desmembrada automaticamente. Grave byte3...0 na eeprom e estará gravando a float. Leia byte3...0 da eeprom e estará lendo a float

Se não der certo avise

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu poderia até te te explicar o lance do struct union mas pra quem tá ainda na 'mamadeira' penso que vamos ter dificuldades recíprocas. E trocar fraldas não me pertende mais kk.

Mas o que posso comentar é o seguinte: aquilo é linguagem 'in natura' do C. Resumindo 'union' apenas "engloba" variáveis pequenas dentro de uma grande fazendo-as ocupar o mesmo espaço de memória. Isso significa que o compilador (de verdade) vai otimizar ao seu extremo - apenas manipulando os 4 bytes de ram pra eeprom(rotina a parte). Já as rotinas mastigadas que paulão sugeriu, fica-se na dúvida. Ou seja, o mc vai sim fazer o que tem que fazer mas pode dar muitas "voltas" pela memória e pelo tempo (minha teoria)

Por curiosidade 1 do 6   2 me dá um exemplo de como é gravar float na eeprom em bascom o mais  'in natura' possível

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

O link que o @aphawk colocou,tem um exemplo para gravar float https://www.arduino.cc/en/Reference/EEPROMPut

 

-----//-----
float f = 123.456f;  //Variable to store in EEPROM.
int eeAddress = 0;   //Location we want the data to be put.
//One simple call, with the address first and the object second.
EEPROM.put(eeAddress, f);
-----//----

e para ler ter um exemplo https://www.arduino.cc/en/Reference/EEPROMGet

 

----//----
EEPROM.get( eeAddress, f );
----//----

 Eu demorei menos de um minuto para achar isto,digitei no google apenas "float arduino eeprom",a maioria das vezes não sabemos das coisas,mas temos que aprender pesquisar.

 

Se você quer programa em c,deve saber struct,union,isso é o básico. Talvez ta na hora de você pegar um livro de C genérico,e estudar um pouco.O jeito que @Isadora Ferraz  disse,é o mais eficiente mesmo,mais obviamente você usar a função pronta do Arduíno não terá problema para maioria dos casos,pois se você um projeto que tivesse alguns requisitos critico,você não estaria fazendo no Arduíno..

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Ofioneu  

 

Não é hostilidade.... é que até eu que todos aqui sabem que sou um completo ignorante em C, digitei no Google e o segundo link que apareceu foi o que eu te indiquei, e eu lí e entendí e ví que era a resposta que voce procura.

 

Se você reparar na minha assinatura embaixo, vai ver que eu falo que temos de saber presquisar no Google, assim evitamos de fazer perguntas que são muito básicas e que uma simples leitura de um artigo já resolveria.

 

O que todos aqui estão te "indicando" é que voce precisa se dedicar mais ao estudo básico da linguagem !

 

@Isadora Ferraz ,

 

Você vai me xingar .... :

 

Basta declarar o tipo dessa variável, por exemplo para float de precisão dupla ficaria assim :

 

Dim Teste as Eram Double

 

Pronto, Eram significa que será armazenada na Eeprom, e Double determina que é uma float de dupla precisão.

 

Se quiser armazenar ela em um endereço fixo na Eeprom, é só adicionar isto no final :

 

At 0x02h

 

Pronto, será armazenada a partir do segundo endereço na Eeprom.

 

Complicado ?  Kkkkkkkk 

 

Paulo

 

Editado por aphawk
  • Curtir 3

Compartilhar este post


Link para o post
Compartilhar em outros sites

Senhores (as) , eu agradeço de verdade.  Também li  sobre  eeprom.put e eeprom.get, e também li coisas mirabolantes de códigos que em tese fazem a mesma coisa,  e pra ser bem sincero antes da vossas respostas eu consegui executar o que queria (quase,  pois ainda estou tendo um problema na lógica a partir de uma eq que está atualizando a partir do endereço da eeprom),  e sim,  nunca tinha lido sobre struck e union e etc,  nem sei se é assim que se escreve  kkkk,  mas mesmo com todas as críticas e com a suposição de vocês que por eu estar fazendo uma pergunta básica vocês tem o direito de me mostrar de forma enfatizada e cotundente que eu não sei sobre a minha pergunta (que é óbvio,  pois se soubesse não estaria perguntando) , tenho a dizer que tenho a consciência que preciso mais deste fórum que apesar de as vezes nos tratarem com uma certa arrogância por julgarem que são melhores por ter certo domínio em alguma área específica, que de fato sejam mesmo, à me preocupar com tais desapontamentos de minhas perguntas e carências de informações  para vocês. 

Novamente agradeço a todos.  E não fico chateado por me apontarem os meus defts, mas fico um pouco chateado pela forma que se expressam ao compartilha vossos conhecimentos. 

Obrigado novamente. 

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Ofioneu ,

 

Não confunda as coisas, meu amigo. Não é arrogância !

 

Você não é novato, e já viu muitos de nós respondermos. Em dois anos, já deve ter visto até umas "pauladas" direto na cabeça de alguns engraçadinhos espertinhos, mas viu também muita ajuda !

 

Eu, por exemplo, não respondí a sua pergunta logo no início por realmente não saber nada a respeito de C , muito menos isso de Strucs ...

 

Outros não responderam por considerarem uma pergunta muito básica, a qual é facilmente respondida usando o Google. 

 

O que você chama de arrogância eu chamo de " poxa esse cara nem pesquisou no Google, veio direto aqui nos fazer perder nosso tempo com uma coisa tão básica " , entendeu ?

 

É uma crítica, mas é sempre no sentido construtivo ! A ideia é que você procure, ANTES de vir perguntar !

 

Muitos aqui possuem conheçimento avançado em muitos assuntos, conheçimentos que poucos professores possuem, e com certeza podem divulgar esse conhecimento sempre que alguém tenha procurado sem achar ou tenha tentado fazer por si só de várias maneiras e não tenha conseguido.

 

Ainda assim, nos reservamos alguns direitos, como não ajudar quando notamos que existe interesse comercial, ou que quem está solicitando a ajuda não fêz o seu "dever de casa" .

 

Todos nós aqui fazemos isto de explicar, ensinar, esclarecer, simplesmente por que gostamos. Não recebemos nada por isto, nem temos nenhuma obrigação em responder ou em ensinar.

 

Mas precisamos que também haja interesse real em aprender por parte de quem faz as perguntas, não apenas de resolver um problema imediato.

 

Pode continuar perguntando quando você pesquisar e não encontrar a resposta !

 

Nós podemos latir bastante, mas mordemos pouco kkkkk !

 

Contamos com o seu entendimento, ok ?

 

Paulo

Editado por aphawk
  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
6 horas atrás, Ofioneu disse:

nos tratarem com uma certa arrogância por julgarem que são melhores por ter certo domínio em alguma área específica,

Comentário extremamente infeliz amigo.  A ideia, como não poderia ser diferente em foruns, é apenas compartilhar algum conhecimento seja de que maneira for. Doamos tempo, recursos, gastamos teclado, clique de mouse, e até arriscamos nossos empregos pra vos iluminar um pouco (mesmo que com lamparina, no meu caso)..enfim, sua alma sua palma

 

7 horas atrás, aphawk disse:

At 0x02h

 

Pronto, será armazenada a partir do segundo endereço na Eeprom.

Não seria 3º? 

Até aí tudo bem. Dou o braço a torcer que é bem mais simples do que o c. Mas (sempre tem um) vamos complicar? se eu fizer

teste=3.141592

Como será o assembly que o compilador gera? quanto de flash ele gasta? Quantos ciclos de máquina? Ou isso está sendo profundo demais? (doeu? kk) . Penso que gravar na eeprom não é algo direto. Há uma rotina que envolve um pouco de hw interno do mc. E, claro, depende do mc.  De fato isso não deve agregar nenhum valor à nossa (sadia) discussão. É só curiosidade mesmo...

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

E mais uma coisa,  Amo vocês kkkk 

São sempre os mesmos que me respondem!!  

Obrigado. 

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
5 horas atrás, Isadora Ferraz disse:

Não seria 3º? 

Até aí tudo bem. Dou o braço a torcer que é bem mais simples do que o c. Mas (sempre tem um) vamos complicar? se eu fizer

teste=3.141592

Como será o assembly que o compilador gera? quanto de flash ele gasta? Quantos ciclos de máquina? Ou isso está sendo profundo demais? (doeu? kk) . Penso que gravar na eeprom não é algo direto. Há uma rotina que envolve um pouco de hw interno do mc. E, claro, depende do mc.  De fato isso não deve agregar nenhum valor à nossa (sadia) discussão. É só curiosidade mesmo...

 

 

Opa, tem razão, esse é o terceiro endereço, esquecí do 00.....

 

Quanto a doer, garanto que doeu menos em mim do que vai doer em você kkkkk !

 

Curiosidade a gente mata :

 

8:        Dim Isadora As Eram Single At &H02
9:        
10:       Isadora = 3.14151692
000000A4: E2E2     LDI       R30, $22            Load Immediate
000000A6: E0F1     LDI       R31, $01            Load Immediate
000000A8: 940E     CALL      $0108               Long Call to a Subroutine
000000AC: E0E2     LDI       R30, $02            Load Immediate
000000AE: E0F0     LDI       R31, $00            Load Immediate
000000B0: E0AD     LDI       R26, $0D            Load Immediate
000000B2: 27BB     EOR       R27, R27            Exclusive OR
000000B4: E094     LDI       R25, $04            Load Immediate
000000B6: E77B     LDI       R23, $7B            Load Immediate
000000B8: 940E     CALL      $00EC               Long Call to a Subroutine
11:       
12:       End
000000BC: 94F8     BCLR      7                   Bit Clear in SREG
000000BE: CFFF     RJMP      $-0000 (00BE)       Relative Jump
13:       
000000C0: 9731     SBIW      R31:R30, 1          Subtract Immediate from Word
000000C2: F7F1     BRNE      $00C0               Branch if Minus
000000C4: 9508     RET                           Return from Subroutine
000000C6: 9468     SET                           Set T Flag
000000C8: F862     BLD       R6, 2               Bit Load from the T Flag in SREG to a Bit in Register
000000CA: 9508     RET                           Return from Subroutine
000000CC: 94E8     BCLR      6                   Bit Clear in SREG
000000CE: F862     BLD       R6, 2               Bit Load from the T Flag in SREG to a Bit in Register
000000D0: 9508     RET                           Return from Subroutine
000000D2: 95C8     LPM                           Load Program Memory
000000D4: 9631     ADIW      R31:R30, 1          Add Immediate to Word
000000D6: 2000     AND       R0, R0              Logical AND
000000D8: 9508     RET                           Return from Subroutine
000000DA: 99F9     SBIC      $1F, 1              Skip if Bit in I/O Register is Cleared
000000DC: CFFE     RJMP      $-0002 (00DA)       Relative Jump
000000DE: BDE1     OUT       $21, R30            Store Register to I/O Location
000000E0: BDF2     OUT       $22, R31            Store Register to I/O Location
000000E2: 9631     ADIW      R31:R30, 1          Add Immediate to Word
000000E4: 9508     RET                           Return from Subroutine
000000E6: E091     LDI       R25, $01            Load Immediate
000000E8: C001     RJMP      $+0004 (00EC)       Relative Jump
000000EA: E092     LDI       R25, $02            Load Immediate
000000EC: 377B     CPI       R23, $7B            Compare with Immediate
000000EE: F451     BRNE      $0104               Branch if Minus
000000F0: B77F     IN        R23, $3F            Load an I/O Location to Register
000000F2: 94F8     BCLR      7                   Bit Clear in SREG
000000F4: DFF2     RCALL     $-001A (00DA)       Relative Call to Subroutine
000000F6: 918D     LD        R24, X+             Load Indirect from Data Space to Register using Index X
000000F8: BD80     OUT       $20, R24            Store Register to I/O Location
000000FA: 9AFA     SBI       $1F, 2              Set Bit in I/O Register
000000FC: 9AF9     SBI       $1F, 1              Set Bit in I/O Register
000000FE: 959A     DEC       R25                 Decrement
00000100: F7C9     BRNE      $00F4               Branch if Minus
00000102: BF7F     OUT       $3F, R23            Store Register to I/O Location
00000104: 2777     EOR       R23, R23            Exclusive OR
00000106: 9508     RET                           Return from Subroutine
00000108: 940E     CALL      $00D2               Long Call to a Subroutine
0000010C: 2CD0     MOV       R13, R0             Copy Register
0000010E: 940E     CALL      $00D2               Long Call to a Subroutine
00000112: 2CE0     MOV       R14, R0             Copy Register
00000114: 940E     CALL      $00D2               Long Call to a Subroutine
00000118: 2CF0     MOV       R15, R0             Copy Register
0000011A: 940E     CALL      $00D2               Long Call to a Subroutine
0000011E: 2D00     MOV       R16, R0             Copy Register
00000120: 9508     RET                           Return from Subroutine
00000122: 0E9D     ADD       R9, R29             Add without Carry
00000124: 4049     SBCI      R20, $09            Subtract Immediate with Carry

 

O programa completo para gravar teria 294 bytes, incluindo toda a inicialização do hardware e do Stack, e o numero foi armazenado no formato IEEE ocupando 4 bytes. Quanto aos ciclos de máquina, se prepare ....  118.130 ciclos kkkkk  gravar 4 bytes na EEPROM demora mesmo !

 

Mas confesso que só coloquei o código ASM aqui para te provocar .... não entendí nada de nada  de como foi feita a conversão do numero para o formato Single e como foi armazenado na EEprom....

 

Não sei se a minha resposta conseguiu satisfazer essa sua ânsia por ter seu imenso vazio profundamente preenchido, talvez precise da resposta de um outro membro ( uiiii   kkk  1 a 1 )  :atirador:, mas faço o melhor possível, mesmo sabendo que a idade provoca uma certa "flacidez" em minhas convicções .....

 

Paulo

 

 

Editado por aphawk
  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

kk a do outro  membro foi boa kk. Mas dispenso.. é sério!

Suspeitei desde o princípio que duas linhas em bascom provocariam tudo isso! É o preço da "moleza" soft. você só no "mole" hein. (kk 2x1... esquece piadinha com hard). Mas senti muita dor sim. Os 110.130 ciclos doeram d+ em mim! E olha que nem vi a função de gravar na eeprom. Penso que de gravar é á tal Call 00ec e a de ler a tal Call D2 que também devem ocupar uns 'baita bytes'. Ok não nos importemos com isso por hora.

 

Me fale qual mc que é este. Vou cogitar mostrar o que saí do c dele. LINGUAGEM C!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz ,

 

Hehehe ok, deixemos as piadinhas hard de fora ... é um Atmega328P.

 

De acordo com o datasheet, cada byte escrito demora em média 3.4 milissegundos, variando com o endereço físico utilizado... 4 bytes seriam 13.6 milissegundos na média

 

É bem demorado, mesmo assim lembro de que o ciclo de máquina nos AVRs é muito mais eficiente do que nos Pic's, pois a grande maioria das instruções é realizada em um único ciclo de máquina.

 

No clock de 12.288 Mhz, demorou 118.130 ciclos, convertendo em tempo foi 9.6 milissegundos todo o processo. Mas isto foi medido com o Proteus, provavelmente ele usa o menor tempo de escrita, e não o tempo médio. Ou seja, é uma daquelas situações que o Proteus difere da realidade.

 

Mas repare que o problema não é o código gerado pelo Basic ou pelo C, e sim o hardware do microcontrolador AVR que demora esse tempo todo para apagar o valor ( gravar FF )  e depois gravar o dado.

 

Paulo

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, aphawk disse:

problema não é o código gerado pelo Basic ou pelo C

é sim o problema meu amigo.

1 hora atrás, aphawk disse:

hardware do microcontrolador AVR que demora esse tempo todo para apagar o valor ( gravar FF )  e depois gravar o dado.

Vou verificar. Apagar não precisa. Penso que ele grava por hw, portanto o asm pode ser bem otimizado pelo compilador

A qualquer momento dou uma verificada...

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, Isadora Ferraz disse:

é sim o problema meu amigo.

Vou verificar. Apagar não precisa. Penso que ele grava por hw, portanto o asm pode ser bem otimizado pelo compilador

A qualquer momento dou uma verificada...

 

Bom, se você ache que é ... segue o app note da Atmel sobre operações com a EEPROM; o código de gravação é muito simples, o problema é esperar um flag que informa que a eeprom foi escrita .....

 

http://www.atmel.com/Images/doc0932.pdf

 

Boa diversão !

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

ok amigo. Sim minimalismo é minha filosofia

 

De cara só por esta descrição...
 

The subroutine waits until the EEPROM is ready to be accessed by polling the EEWE bit in the EEPROM Control Register – EECR. When EEWE is zero, the subroutine and transfers the contents of EEardh:EEard to the EEPROM Address Register –EEARH:EEARL. It then sets the EEPROM Read Strobe – EERE. In the next instruction the content of the EEDR Register is tranferred to the register variable EEdrd.

...já dá pra perceber que, de novo, há um excesso de flatulência pra pouca..."  "  no assembly gerado pelo seu precioso. Parece que ele faz muito mais coisa além disso. Provavelmente o que grava-lê efetivamente são aqueles 2 call's que mencionei.  Manipular tais registros diretamente é muito mais eficiente né?  Este é um dos pontos que onde queremos chegar. De fato, o compilador já deve ter tal função - manipula diretamente os registros. O IAR c tem pro atmega, o hitech-c tem pro pic e etc

O outro ponto é a manipulação da ram, mais especificamente os 4 bytes do float. Isto tem pra todos compiladores e mc pois é nativo do c. Portanto, o pulo do gato é juntar os dois...

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz ,

 

Sim, existe maneira mais objetiva de se fazer isso. Posso fazer tudo em Asm direto e pronto, ignoro todas as estruturas dos compiladores e terei o melhor tempo possível.

 

Mas .... adianta economizar 50 ou 100 ciclos de clock em um total de mais de 118.000 ciclos ? 

 

Teria de debugar e perder uma hora ou mais, tudo para se ganhar míseros 50 ou 100 ciclos de clock ?

 

Resolví o problema com apenas duas linhas. Duas únicas e simples linhas. Sem Strucs. Sem Unions. Creio que a objetividade dessas duas linhas é algo impossível de ser batida.

 

Para mim isso é o que importa. Uso o Bascom para ganhar tempo, e quando encontro coisas críticas, coloco o Asm no meio dele e resolvo.

 

Repare que eu declarei a variável e dei um valor para ela. E quando usei o valor 3.1415... o programa teve de fazer a conversão para float durante a execução do programa, pois eu não indiquei esse numero como CONSTANT . ( nada como guardar os truques na manga.... ) Na minha opinião o Bascom deveria fazer isso sem eu ter de deixar explícito como constant, mas o autor achou melhor deixar isso manual, vai entender.... Mas tenho certeza de que os bons compiladores C fazem isso automaticamente.

 

Se tivesse utilizado assim com constant, o compilador do Bascom  iria converter isso na compilação e já teríamos os bytes correspondentes calculados e prontinhos para uso. O código ficaria bem menor. Converter para float consome alguns bons ciclos de programa e de código. Mas de nada adianta otimizar bits, bytes e ciclos de máquina, se tiver de esperar uma eternidade ( do ponto de vista do AVR... ) para um flag dizer que a memória EEPROM está gravada.....

 

Não sou de ficar comparando a eficiência do compilador, o tamanho do programa, nada disso. Minha mercadoria mais valiosa é o tempo envolvido até obter o resultado.

 

Esse foi o motivo quando eu citei acima que o problema não era o código do C ou do Bascom... e sim o hardware interno de gravação da EEPROM. Eu já tinha lido esse app note da Atmel.

 

Como costumo dizer , não importa a cor do gato, desde que coma os ratos !

 

Paulo

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
10 horas atrás, aphawk disse:

Não sou de ficar comparando a eficiência do compilador, o tamanho do programa

Pois eu vivo disso kk. Se couber num mc de menor capacidade custando algumas dezenas de centavos a menos... já sabe... Com relação ao tempo, basta seguir o cronograma que você mesmo cria.

 

Em tempo... certa feita fiz um programinha pra um mc de 1K que ocupou... 1022 bytes. Sério. Isso meio que responde minha "paranóia" kk. Algo como um rato que ruge espantou um gato.

 

Enfim, seus (válidos) argumentos no aspecto "é mole pro gato" esfriaram minhas intenções de publicar algum resultado vindo do c. (LINGUAGEM C!). Talvez eu o faça (já o fiz no passado - preguiça de procurar) pra alguma satisfação pessoal e se me der vontade, publico pra que os amigos leitores que não programam em bascom possam ver a alternativa.

abç

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz ,

 

Se for para um projeto onde vão ser vendidos milhares de produtos, então claro que temos de procurar o melhor preço - benefício. Aí sim estamos de acordo ! Se tiver de escovar bits, escovaremos bits kkkkk !

 

Mas longe de mim esfriar alguma coisa !

 

Aqui temos a possibilidade de ensinar , de passa adiante o nosso conhecimento !

 

 E pouca gente terá na vida uma oportunidade melhor de aprender do que interagir conosco e com outros usuários experientes. Vide aquele tópico que você acompanhou do projetinho de robótica, o tal "Veículo Explorador de Marte" , o qual refletiu bem o nível das nossas escolas e dos professores ! Estamos a anos-luz disso ...

 

Estas discussões que temos aqui, sempre no sentido mais coloquial, passa muitos insights diferentes, e que vão ajudar essas pessoas que estão iniciando.

 

Acho que voce pode sim publicar seus resultados, seus projetos, e o Fórum só tem a ganhar com isto !

 

Vela o tópico que eu comecei do Bascom, eu sempre que posso publico alguma coisa lá, justamente para servir de referência para quem estiver procurando algo. Não me importo se poucos comentam, ou se poucos se interessam, mas existe uma monte de experiência acumulada, algumas técnicas avançadas para casos de velocidade extrema, e um dia isso vai ajudar alguém. Levar para o caixão comigo não serve para nada !

 

voce poderia se animar também e fazer algo semelhante, divulgar as suas experiências  com a LINGUAGEM C! e os microcontroladores !

 

Paulo

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

ok me convenceu kk.  Seguinte ... o exemplo que dei dos ponteiros de ponteiros está 'sob judice'. não está respondendo a contento. Se você, caro leitor, for um expert em c e sentir vontade, fique a vontade em analisar e propor algo.

 

Vejamos o da struct/union. Esse sim está dominado! Usei um atmega48 e attiny
o fonte:
 

Spoiler



#include <ioavr.h>
//*************************************************************
void eepw(unsigned char ucAddress, unsigned char ucData)
{
/* Wait for completion of previous write */
while(EECR_Bit1);
/* Set Programming mode */
EECR_Bit5=EECR_Bit4=0; //Erase and Write in one operation (Atomic Operation)
/* Set up address and data registers */
EEAR = ucAddress;
EEDR = ucData;
/* Write logical one to EEMWE */
EECR_Bit2=1;  //o mesmo que EEMPE bit2
/* Start eeprom write by setting EEWE */
EECR_Bit1=1;  //o mesmo que EEPE bit1
}

//*************************************************************

unsigned char eepr(unsigned char ucAddress)
{
/* Wait for completion of previous write */
while(EECR_Bit1); //bit1
/* Set up address register */
EEAR = ucAddress;
/* Start eeprom read by writing EERE */
EECR_Bit0=1; //bit0
/* Return data from data register */
return EEDR;
}

float pi;

struct float_struct        //estrutura de 4 bytes do float 32 bits
{
unsigned char _byte0;
unsigned char _byte1;
unsigned char _byte2;
unsigned char _byte3;
};
union  
{
struct float_struct float_byte;  //4 bytes contidos em...
float _float;      //32 bits
} float_union; //união dos 4 bytes

#define float0 float_union._float  //float todo dividido em 
#define byte0 float_union.float_byte._byte0    //4 bytes
#define byte1 float_union.float_byte._byte1
#define byte2 float_union.float_byte._byte2
#define byte3 float_union.float_byte._byte3

int main( void )
{
float0=3.141592;

eepw(0,byte0);
eepw(1,byte1);
eepw(2,byte2);
eepw(3,byte3);

float0=0; //destroi

//reconstroi float0 a partir dos pedaços
byte0=eepr(0);
byte1=eepr(1);
byte2=eepr(2);
byte3=eepr(3);
  
pi=float0; //taí

for(;;);
}

 

 


 

Se comparar com Dim Teste as Eram Double realmente é um baita susto kk.  O assembly fica quase a lesma lerda [***]. Ocupou 162 bytes . bem gulosinho mesmo. kk

Spoiler



      1          #include <ioavr.h>

   \                                 In  segment ABSOLUTE, at 0x41
   \   union <unnamed> volatile __io _A_EEARL
   \                     _A_EEARL:
   \   00000000                      DS8 1

   \                                 In  segment ABSOLUTE, at 0x40
   \   union <unnamed> volatile __io _A_EEDR
   \                     _A_EEDR:
   \   00000000                      DS8 1

   \                                 In  segment ABSOLUTE, at 0x3f
   \   union <unnamed> volatile __io _A_EECR
   \                     _A_EECR:
   \   00000000                      DS8 1
      2          //*************************************************************

   \                                 In  segment CODE, align 2, keep-with-next
      3          void eepw(unsigned char ucAddress, unsigned char ucData)
   \                     eepw:
   \                     ??eepw_0:
      4          {
      5          /* Wait for completion of previous write */
      6          while(EECR_Bit1);
   \   00000000   99F9               SBIC    0x1F, 0x01
   \   00000002   CFFE               RJMP    ??eepw_0
      7          /* Set Programming mode */
      8          EECR_Bit5=EECR_Bit4=0; //Erase and Write in one operation (Atomic Operation)
   \   00000004   98FC               CBI     0x1F, 0x04
   \   00000006   98FD               CBI     0x1F, 0x05
      9          /* Set up address and data registers */
     10          EEAR = ucAddress;
   \   00000008   BD01               OUT     0x21, R16
     11          EEDR = ucData;
   \   0000000A   BD10               OUT     0x20, R17
     12          /* Write logical one to EEMWE */
     13          EECR_Bit2=1;  //o mesmo que EEMPE bit2
   \   0000000C   9AFA               SBI     0x1F, 0x02
     14          /* Start eeprom write by setting EEWE */
     15          EECR_Bit1=1;  //o mesmo que EEPE bit1
   \   0000000E   9AF9               SBI     0x1F, 0x01
     16          }
   \   00000010   9508               RET
   \   00000012                      REQUIRE _A_EECR
   \   00000012                      REQUIRE _A_EEARL
   \   00000012                      REQUIRE _A_EEDR
     17          
     18          //*************************************************************
     19          

   \                                 In  segment CODE, align 2, keep-with-next
     20          unsigned char eepr(unsigned char ucAddress)
   \                     eepr:
     21          {
   \   00000000   2F10               MOV     R17, R16
     22          /* Wait for completion of previous write */
     23          while(EECR_Bit1); //bit1
   \                     ??eepr_0:
   \   00000002   99F9               SBIC    0x1F, 0x01
   \   00000004   CFFE               RJMP    ??eepr_0
     24          /* Set up address register */
     25          EEAR = ucAddress;
   \   00000006   BD11               OUT     0x21, R17
     26          /* Start eeprom read by writing EERE */
     27          EECR_Bit0=1; //bit0
   \   00000008   9AF8               SBI     0x1F, 0x00
     28          /* Return data from data register */
     29          return EEDR;
   \   0000000A   B500               IN      R16, 0x20
   \   0000000C   9508               RET
   \   0000000E                      REQUIRE _A_EECR
   \   0000000E                      REQUIRE _A_EEARL
   \   0000000E                      REQUIRE _A_EEDR
     30          }
     31          

   \                                 In  segment NEAR_Z, align 1, keep-with-next
   \   00000000                      REQUIRE `?<Segment init: NEAR_Z>`
     32          float pi;
   \                     pi:
   \   00000000                      DS8 4
     33          
     34          struct float_struct        //estrutura de 4 bytes do float 32 bits
     35          {
     36          unsigned char _byte0;
     37          unsigned char _byte1;
     38          unsigned char _byte2;
     39          unsigned char _byte3;
     40          };
     41          union  
     42          {
     43          struct float_struct float_byte;  //4 bytes contidos em...
     44          float _float;      //32 bits

   \                                 In  segment NEAR_Z, align 1, keep-with-next
   \   00000000                      REQUIRE `?<Segment init: NEAR_Z>`
     45          } float_union; //união dos 4 bytes
   \                     float_union:
   \   00000000                      DS8 4
     46          
     47          #define float0 float_union._float  //float todo dividido em 
     48          #define byte0 float_union.float_byte._byte0    //4 bytes
     49          #define byte1 float_union.float_byte._byte1
     50          #define byte2 float_union.float_byte._byte2
     51          #define byte3 float_union.float_byte._byte3
     52          

   \                                 In  segment CODE, align 2, keep-with-next
     53          int main( void )
   \                     main:
     54          {
     55          float0=3.141592;
   \   00000000   ED08               LDI     R16, 216
   \   00000002   E01F               LDI     R17, 15
   \   00000004   E429               LDI     R18, 73
   \   00000006   E430               LDI     R19, 64
   \   00000008   ....               LDI     R30, LOW(float_union)
   \   0000000A   ....               LDI     R31, (float_union) >> 8
   \   0000000C   8300               ST      Z, R16
   \   0000000E   8311               STD     Z+1, R17
   \   00000010   8322               STD     Z+2, R18
   \   00000012   8333               STD     Z+3, R19
     56          
     57          eepw(0,byte0);
   \   00000014   9110....           LDS     R17, float_union
   \   00000018   E000               LDI     R16, 0
   \   0000001A   ....               RCALL   eepw
     58          eepw(1,byte1);
   \   0000001C   9110....           LDS     R17, (float_union + 1)
   \   00000020   E001               LDI     R16, 1
   \   00000022   ....               RCALL   eepw
     59          eepw(2,byte2);
   \   00000024   9110....           LDS     R17, (float_union + 2)
   \   00000028   E002               LDI     R16, 2
   \   0000002A   ....               RCALL   eepw
     60          eepw(3,byte3);
   \   0000002C   9110....           LDS     R17, (float_union + 3)
   \   00000030   E003               LDI     R16, 3
   \   00000032   ....               RCALL   eepw
     61          
     62          float0=0; //destroi
   \   00000034   E000               LDI     R16, 0
   \   00000036   E010               LDI     R17, 0
   \   00000038   E020               LDI     R18, 0
   \   0000003A   E030               LDI     R19, 0
   \   0000003C   ....               LDI     R30, LOW(float_union)
   \   0000003E   ....               LDI     R31, (float_union) >> 8
   \   00000040   8300               ST      Z, R16
   \   00000042   8311               STD     Z+1, R17
   \   00000044   8322               STD     Z+2, R18
   \   00000046   8333               STD     Z+3, R19
     63          
     64          //reconstroi float0 a partir dos pedaços
     65          byte0=eepr(0);
   \   00000048   E000               LDI     R16, 0
   \   0000004A   ....               RCALL   eepr
   \   0000004C   9300....           STS     float_union, R16
     66          byte1=eepr(1);
   \   00000050   E001               LDI     R16, 1
   \   00000052   ....               RCALL   eepr
   \   00000054   9300....           STS     (float_union + 1), R16
     67          byte2=eepr(2);
   \   00000058   E002               LDI     R16, 2
   \   0000005A   ....               RCALL   eepr
   \   0000005C   9300....           STS     (float_union + 2), R16
     68          byte3=eepr(3);
   \   00000060   E003               LDI     R16, 3
   \   00000062   ....               RCALL   eepr
   \   00000064   9300....           STS     (float_union + 3), R16
     69            
     70          pi=float0; //taí
   \   00000068   ....               LDI     R30, LOW(float_union)
   \   0000006A   ....               LDI     R31, (float_union) >> 8
   \   0000006C   8100               LD      R16, Z
   \   0000006E   8111               LDD     R17, Z+1
   \   00000070   8122               LDD     R18, Z+2
   \   00000072   8133               LDD     R19, Z+3
   \   00000074   ....               LDI     R30, LOW(pi)
   \   00000076   ....               LDI     R31, (pi) >> 8
   \   00000078   8300               ST      Z, R16
   \   0000007A   8311               STD     Z+1, R17
   \   0000007C   8322               STD     Z+2, R18
   \   0000007E   8333               STD     Z+3, R19
     71          
     72          for(;;);
   \                     ??main_0:
   \   00000080   CFFF               RJMP    ??main_0
     73          }

   Maximum stack usage in bytes:

     Function  CSTACK RSTACK
     --------  ------ ------
     eepr          0      2
     eepw          0      2
     main          0      2
       -> eepw     0      2
       -> eepw     0      2
       -> eepw     0      2
       -> eepw     0      2
       -> eepr     0      2
       -> eepr     0      2
       -> eepr     0      2
       -> eepr     0      2


   Segment part sizes:

     Function/Label Bytes
     -------------- -----
     _A_EEARL          1
     _A_EEDR           1
     _A_EECR           1
     eepw             18
     eepr             14
     pi                4
     float_union       4
     main            130
      Others           6

 
   3 bytes in segment ABSOLUTE
 162 bytes in segment CODE
   6 bytes in segment INITTAB
   8 bytes in segment NEAR_Z
 
 162 bytes of CODE memory (+ 6 bytes shared)
   8 bytes of DATA memory (+ 3 bytes shared)

Errors: none
Warnings: none

 


 

 

 

A proposta, como disse é bem simples. Gravar e ler pi da eeprom. ([***]não sei se o seu asm advindo do basic leu ou só gravou) O tempo de execução não vamos considerar pois com disse depende do hw do mc.

Pra concluir, permita de novo a visão prática: mc 8 bits e variáveis com ponto flutuante ... nada a ver.

 

Ah a propósito... uma compilação que estou fazendo precisa de 14k e o mc só tem 8. Penei por 1 ou 2 dias pra caber.. questão de princípios kk Apelei e fiz até algumas rotinas em asm do mc . Quebrei alguns princípios kk !! ... Desisti! kk O mc de 32K custa U$0,68 e o de 8 U$0.50. Evoluir é preciso kk.

Bom é isso.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 21/10/2016 às 11:37, Isadora Ferraz disse:

Pra concluir, permita de novo a visão prática: mc 8 bits e variáveis com ponto flutuante ... nada a ver.

 

Ah a propósito... uma compilação que estou fazendo precisa de 14k e o mc só tem 8. Penei por 1 ou 2 dias pra caber.. questão de princípios kk Apelei e fiz até algumas rotinas em asm do mc . Quebrei alguns princípios kk !! ... Desisti! kk O mc de 32K custa U$0,68 e o de 8 U$0.50. Evoluir é preciso kk.

Bom é isso.

 

Concordo totalmente com o que você disse sobre os mc de 8 bits.

 

Quanto ao resto, bom, admiro a sua insistência ... 14K caber em 8K eu nem tentaria encaixar o código para ver se dava !

Já partiria direto para um de 16K ou mesmo de 32K !

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

é isso aí paulão! Tentei um pouco só pra exercitar o intelecto e principalmente pela adrenalina kk. Mas como disse.. desisti.

Bom.. cá está a outra alternativa a quem interessar possa. Pode não ser totalmente inútil.

 

int main( void )
{
float float0;
float *ponteiro;
  
ponteiro = &float0; 
  
float0=3.141592;

//grava os pedaços na eeprom
eepw(0,*((unsigned char *)(ponteiro)+0)); 
eepw(1,*((unsigned char *)(ponteiro)+1)); 
eepw(2,*((unsigned char *)(ponteiro)+2)); 
eepw(3,*((unsigned char *)(ponteiro)+3)); 

float0=0; //destroi

//reconstroi float0 a partir dos pedaços da eeprom
*((unsigned char *)ponteiro + 0)=eepr(0);
*((unsigned char *)(ponteiro)+1)=eepr(1);
*((unsigned char *)(ponteiro)+2)=eepr(2);
*((unsigned char *)(ponteiro)+3)=eepr(3);
  
pi=float0; //taí

for(;;);
}

Ainda assusta, claro. Mas um pouco menos do que o struct/union. Ou assusta ainda mais?! A propósito, nunca, jamais me peça pra explicar isso ok? Não é de minha autoria. Só sei que funciona e fds. Se quiser te ponho em contato com o autor lá do asm51.com.br

Enfim...Foi uma cagadinha básica minha: estava definindo ponteiro como tipo diferente daquele pra quem ele ia apontar

você (ou você) pode não acreditar mas vi o problema quando vi um antigo fonte onde gravo um float na eeprom de um mc de .... de ... de.... 8 bits kk. Contrariando os meus princípios, na época foi mais rápido pois tinha algumas apenas horas pra concluir. Enfim .. é isso: temos que dançar conforme a música. Mas por hora.. nada de bascom.

 

abç´s

  • Curtir 1

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

×