collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: STM32 inicio  (Lida 10064 vezes)

0 Membros e 2 Visitantes estão a ver este tópico.

Offline KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.481
Re: STM32 inicio
« Responder #15 em: 12 de Abril de 2020, 17:16 »
Experimentei os exemplos que enviou no entanto o resultado em ambos é o mesmo:
Hex:0xff61   Binary:1111111101100001

Optimo, era isso que esperava que desse. Qual e' entao o problema ? :)

Offline jm_araujo

  • Mini Robot
  • *
  • Mensagens: 2.947
  • NERD!
Re: STM32 inicio
« Responder #16 em: 12 de Abril de 2020, 18:03 »
Andam lá perto mas não atinam ;)
Testa isto assim:
Código: [Seleccione]
   uint8_t READXYZ[2];
   int16_t final;

   READXYZ[0]=0x61;
   READXYZ[1]=0xff;
   final = READXYZ[0] | READXYZ[1] << 8;
   float x1=(final / 4096.0f );


Lógica: o que o arduino está a fazer é "esticar" o sinal de um número de 16 bits (0xff61) para 32 bits. Nesse caso queremos que variável para meter os 2 bytes seja um  "signed" de 16 bits, para garantir que ao fazer as promoções para as contas o C entenda corretamente o sinais. Removi os casts todos porque para operações matematicas não devem ser necessários se estiver bem escrito (senão nunca mais se saía do lugar a programar em C)

Offline dio123

  • Mini Robot
  • *
  • Mensagens: 1.032
Re: STM32 inicio
« Responder #17 em: 12 de Abril de 2020, 20:20 »
Boa tarde,
jm_araujo - é isso mesmo, assim já consegui fazer a leitura correcta e obter os valores de x,y,z certinhos.

Agradeço a todos pela ajuda


Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: STM32 inicio
« Responder #18 em: 12 de Abril de 2020, 21:45 »
Lógica: o que o arduino está a fazer é "esticar" o sinal de um número de 16 bits (0xff61) para 32 bits.

Chama-se "estender o sinal". Alguns CPUs, se não todos, têm uma instrução para isso.

Quando copiamos de uma variável para outra maior com sinal, os bits mais significativos têm que ser iguais ao mais significativo da variável pequena, senão o sinal do número não é mantido. Por exemplo, passar -1 em 8 bits para -1 em 16 bits; se apenas copiarmos os 8 para os 8 menos significativos dos 16 com sinal, ficamos com 0x00ff, que não é -1 mas sim 255. O correcto é passar para 0xffff, que é -1 em 16 bits. A regra que faz a conversão correcta é pegar no bit mais significativo da variável pequena e replicá-lo pelos bits mais significativos da variável maior (estender o sinal):

-1 (8bits) = 1111 1111b -> 0000 0000 1111 1111b
mas o bit mais significativo é 1 e portanto repete-se nos restantes bits à esquerda
1111 1111 1111 1111b (16bits) = -1

Já se o valor original fosse 1 (ou qualquer valor positivo, que tem o bit mais significativo = 0), repetia-se 0 e o resultado final continua a ser 1
1 (8bits) = 0000 0001b -> 0000 0000 0000 0001b (16bits)

Em variáveis sem sinal, não se estende o sinal, os bits "novos", mais significativos do sinal, ficam sempre a zero.
« Última modificação: 12 de Abril de 2020, 21:56 por Njay »

Offline KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.481
Re: STM32 inicio
« Responder #19 em: 12 de Abril de 2020, 22:49 »
Eu nao estou dentro do problema inicial (como deu para reparar ai em cima), mas em relacao a esses "esquemas da linguagem", eu faria de um modo que fosse explicito perceber o que se passa e o que se quer fazer.
Deve haver uma maneira de resolver esse problema que nao seja necessario conhecer o funcionamento binario das variaveis com sinal ou especificacoes da arquitectura.
Normalmente isso passa por usar os valores binario sem significado de sinal(usar sempre a informacao unsigned int ou fazer a conversao no inicio) e depois so no final fazer a conversao explicitamente (uma conta..).
Se nao, acontecem estas questoes "o que e' que ele esta a fazer por detras"?


Por exemplo, o seguinte codigo:

Código: [Seleccione]
#include <stdio.h>
#include <cstdint>

int main()
{
    uint8_t READXYZ[2];
    uint32_t u32value;
    int32_t s32value;
   
    READXYZ[0] = 0x61;
    READXYZ[1] = 0xff;
    u32value = ( READXYZ[0] | ( READXYZ[1] << 8 ) );
    s32value = -(0x10000 - u32value);
    printf("0x%08X    %d    0x%08X\n", u32value, s32value, s32value);
}

dá o seguinte resultado:

Código: [Seleccione]
0x0000FF61    -159    0xFFFFFF61

Neste caso quem desenvolve o codigo precisa de saber que o que vem no READXYZ e' um numero com sinal e a conversao se faz -(0x10000 - u32value);
Certo que é necessario saber alguma coisa.. e tambem pode nao ser o mais eficiente em termos de instrucoes.

Mas quem nao esta por dentro, pode nao entender porque e' que isto e' feito, mas pelo menos nao esta escondido pelo compilador, arquitectura ou magia obscura, as operacoes matematicas estao la e basta ler o codigo para conseguirmos chegar ao resultado final :)


Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: STM32 inicio
« Responder #20 em: 12 de Abril de 2020, 23:09 »
Por isso mesmo é que me limitei a dar informação genérica.

Offline jm_araujo

  • Mini Robot
  • *
  • Mensagens: 2.947
  • NERD!
Re: STM32 inicio
« Responder #21 em: 13 de Abril de 2020, 10:44 »
Lógica: o que o arduino está a fazer é "esticar" o sinal de um número de 16 bits (0xff61) para 32 bits.

Chama-se "estender o sinal". Alguns CPUs, se não todos, têm uma instrução para isso.

Quando copiamos de uma variável para outra maior com sinal, os bits mais significativos têm que ser iguais ao mais significativo da variável pequena, senão o sinal do número não é mantido. Por exemplo, passar -1 em 8 bits para -1 em 16 bits; se apenas copiarmos os 8 para os 8 menos significativos dos 16 com sinal, ficamos com 0x00ff, que não é -1 mas sim 255. O correcto é passar para 0xffff, que é -1 em 16 bits. A regra que faz a conversão correcta é pegar no bit mais significativo da variável pequena e replicá-lo pelos bits mais significativos da variável maior (estender o sinal):

-1 (8bits) = 1111 1111b -> 0000 0000 1111 1111b
mas o bit mais significativo é 1 e portanto repete-se nos restantes bits à esquerda
1111 1111 1111 1111b (16bits) = -1

Já se o valor original fosse 1 (ou qualquer valor positivo, que tem o bit mais significativo = 0), repetia-se 0 e o resultado final continua a ser 1
1 (8bits) = 0000 0001b -> 0000 0000 0000 0001b (16bits)

Em variáveis sem sinal, não se estende o sinal, os bits "novos", mais significativos do sinal, ficam sempre a zero.

Está tudo correto

Em C não tens de te preocupar com nada disso se definires as variáveis do tipo correto, as conversão são implícitas na linguagem.
Em C se fizeres
Código: [Seleccione]
    int8_t x;
    int16_t y;
    x=0xff;
    y=x;
    printf("%d  %d",x,y);
Tens como resultado "-1 -1", x e y ficam com o valor -1, não tens de extender o sinal explicitamente.

Com atribuições bitwise (&,|,<<,>>,~,^) é preciso mais algum cuidado, mas nada que uns testes não resolvam.
Eu nao estou dentro do problema inicial (como deu para reparar ai em cima), mas em relacao a esses "esquemas da linguagem", eu faria de um modo que fosse explicito perceber o que se passa e o que se quer fazer.
Deve haver uma maneira de resolver esse problema que nao seja necessario conhecer o funcionamento binario das variaveis com sinal ou especificacoes da arquitectura.
Normalmente isso passa por usar os valores binario sem significado de sinal(usar sempre a informacao unsigned int ou fazer a conversao no inicio) e depois so no final fazer a conversao explicitamente (uma conta..).
Se nao, acontecem estas questoes "o que e' que ele esta a fazer por detras"?


Por exemplo, o seguinte codigo:

Código: [Seleccione]
#include <stdio.h>
#include <cstdint>

int main()
{
    uint8_t READXYZ[2];
    uint32_t u32value;
    int32_t s32value;
   
    READXYZ[0] = 0x61;
    READXYZ[1] = 0xff;
    u32value = ( READXYZ[0] | ( READXYZ[1] << 8 ) );
    s32value = -(0x10000 - u32value);
    printf("0x%08X    %d    0x%08X\n", u32value, s32value, s32value);
}

dá o seguinte resultado:

Código: [Seleccione]
0x0000FF61    -159    0xFFFFFF61

Neste caso quem desenvolve o codigo precisa de saber que o que vem no READXYZ e' um numero com sinal e a conversao se faz -(0x10000 - u32value);
Certo que é necessario saber alguma coisa.. e tambem pode nao ser o mais eficiente em termos de instrucoes.

Mas quem nao esta por dentro, pode nao entender porque e' que isto e' feito, mas pelo menos nao esta escondido pelo compilador, arquitectura ou magia obscura, as operacoes matematicas estao la e basta ler o codigo para conseguirmos chegar ao resultado final :)



Esse código não é muito legível, nem amigável para micros: tens uma constante de 64 bits ("0x10000"), nem todos os compiladores vão comer sem calar, e vais ter uma penalização na execução pelas instruções extra (negação de uma subtração).
As explicações do código dão-se nos comentários, devemos deixar os compiladores fazer o seu trabalho. Se o C sabe converter entre tipos, devemos deixá-lo fazer.



Offline KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.481
Re: STM32 inicio
« Responder #22 em: 13 de Abril de 2020, 13:48 »
Esse código não é muito legível, nem amigável para micros: tens uma constante de 64 bits ("0x10000"), nem todos os compiladores vão comer sem calar, e vais ter uma penalização na execução pelas instruções extra (negação de uma subtração).

> Esse código não é muito legível

Pode nao ser compreensivel e nao se entender o proposito, mas legivel... é só a negacao da subtracao de um valor com uma variavel :)

> 64 bits, e vais ter uma penalização na execução pelas instruções extra (negação de uma subtração).

Sim, tinha dito que nao ia ser o mais eficiente.
Usei o u32/s32 para testes, ai nesse caso em concreto, servia usar so 16bits/32bits que ja ficava mais amigavel.


As explicações do código dão-se nos comentários, devemos deixar os compiladores fazer o seu trabalho. Se o C sabe converter entre tipos, devemos deixá-lo fazer.

Este caso e neste tipo de coisas que estamos a analisar entra muito na politica pessoal (ou o que estiver definido numa eventual politica de desenvolvimento de codigo interno numa empresa, por exemplo)
Eu pessoalmente, em relacao a isto de linguagens programacao, como tenho limitacoes cognitivas, nao consigo decorar todas as regras da linguagem.
Por exemplo, a questao do uso de ( ) para clarificar a precedencia de operacoes.. eu sei que existe uma tabela que define a ordem para todos os operadores da linguagem... mas nao vou estar a decora-la :) logo abuso do uso de ( ) mesmo nao sendo necessario a maior parte das vezes.

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: STM32 inicio
« Responder #23 em: 13 de Abril de 2020, 15:21 »
Eu pessoalmente, em relacao a isto de linguagens programacao, como tenho limitacoes cognitivas, nao consigo decorar todas as regras da linguagem.
Por exemplo, a questao do uso de ( ) para clarificar a precedencia de operacoes.. eu sei que existe uma tabela que define a ordem para todos os operadores da linguagem... mas nao vou estar a decora-la :) logo abuso do uso de ( ) mesmo nao sendo necessario a maior parte das vezes.

Eu idem. Meto parenteses em tudo. É muito mais fácil e legível do que decorar as regras da precedência. E uso as partes mais básicas das linguagens. Não sou purista em linguagem nenhuma. Adoro C com classes. Tenho uma regra que é "quanto mais explicito, melhor" - quanto menos "background" de informação for necessário para entender um pedaço de código, melhor. Quanto mais linguagens se conhece maior o potencial de se ficar baralhado :D