Ir ao conteúdo
  • Cadastre-se
Thiago Felipe Soares Gonçalves

Outro Manipulação de bit - inverter e deslocar bits

Recommended Posts

Boa noite,

 

estou com a seguinte questão tenho um conjunto de bits e preciso inverte-los da seguinte maneira.

Original   - 0b01001111

Invertido -  0b11110010

 

A segunda questão é preciso deslocar esses bits depois de invertidos da seguinte maneira.

Invertido -    0b11110010

Deslocado - 0b11001000

 

No deslocamento eu posso perder os bits deslocados não a problema. Se alguém saber aonde posso achar algo que me ajude a fazer isso eu ficaria muito agradecido.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Thiago Felipe Soares Gonçalves      se você quiser fazer na linguagem c e  se esses bits puderem ser colocados em um vetor então seria fácil, você colocaria os bits assim :

int vetor [8]={0,1,0,0,1,1,1,1};
int vetor2[8];


e para inverter use um loop pegando os bits em cada posição do vetor e coloca em outro vetor de mesmo tamanho na ordem inversa assim :

for(i=0;i<8;i++)
    vetor2[7-i] = vetor[i];


e para deslocar os bits, como no seu exemplo você deslocou de dois em dois, use outro loop assim :
 

for(i=0;i<8;i++)
    vetor2[i] = vetor2[i+2];
vetor2[6]=0;/* colocando zero no final dos bits */
vetor2[7]=0;

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Infelizmente assim não vai dar, pois eu já tenho uma lista de vetores aonde cada célula do meu vetor é um byte, assim:

 

const char A_seq[5] =  {0x7e,0x09,0x09,0x09,0x7e};

 

Eu leio no meu código um byte por vez, assim

 

PORTB = 0x7e;

 

Assim consigo acender leds numa sequencia especifica, porém preciso inverter esse byte para acender a sequencia corretamente.

 

A ideia é inverter ele em seguida deslocá-lo assim consigo por parte dele em um PORT e parte em OUTRO. Exemplo:

 

Original - 0b01001110

Inverto -  0b01110010

 

data = 0b01110010;

PORTB = data>>3; //0b00001110

PORTD = data<<5; //0b01000000

 

A ideia é essa.

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
12 minutos atrás, Thiago Felipe Soares Gonçalves disse:

parte dele em um PORT e parte em OUTRO

Acionando o minimalismo em 3...2...aff que bobeira...

Amigo isto é mais simples do que imaginas. Faça bit a bit

unsigned char a=0x55;

RB0=a; //>>0

RC2=a>>1;

RE6=a>>2;

RA7=a>>3;

RD5=a>>4;

e por aí vai...

Ou se preferir algo mais sinistro e desafiador e portável, faça uma perturbadora estrutura com campos  de bits

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Infelizmente o minimalismo se faz necessário, pois a velocidade com que ele vai processar isso influencia na projeção da minha imagem.

 

Vou continuar procurando uma solução que inverta o byte como já mencionado. Se encontrar posto aqui para futuras consultas.

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
8 horas atrás, Thiago Felipe Soares Gonçalves disse:

Infelizmente o minimalismo se faz necessário

Mas a solução que te passei é o minimalismo puro. Enfim...

 

Obviamente não vai se importar com minhas observações abaixo...

 

Então teu projeto já nasceu errado. Não teve 'visão além do alcance' em prever a correta distribuição do bits no hw com este mc tão lento. Trocar o mc, aumentar velocidade, redistribuir corretamente, seria a solução mais eficiente. Fazer remendos tem seu preço.

Agora se estiver querendo reaproveitar um hw preexistente, sem problema mas vai ter que conviver/contornar/ajustar/remendar/etcterar.

 

Mas não sei que tipo de mc estás a usar. Deduzi pic. Se fosse da família 51, este tem instruções de manipulação de bit no assembly que são trilegais. Um bom compilador há de usá-las pra otimizar o código.

 

8 horas atrás, Thiago Felipe Soares Gonçalves disse:

Se encontrar posto aqui para futuras consultas.

Aí sim hein!... Esta é a ideia do forum!

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Consegui resolver o problema ontem de madrugada, aumentei o clock de 4Mhz para 16Mhz, alem disso fiz uma instrução parecida com o que a @Isadora Ferraz mostrou. Alias o microcontrolador que estou usando é um ATMEGA328P e o que estou fazendo é um pov com velocidade variável, fazendo a projeção manter sua forma mesmo alterando a velocidade de rotação.

 

data = 0b01001001;

 

if(data & 0b00000001) setb(PB4); else clrb(PB4);

if(data & 0b00000010) setb(PB3); else clrb(PB3);
if(data & 0b00000100) setb(PB2); else clrb(PB2);
if(data & 0b00001000) setb(PB1); else clrb(PB1);

if(data & 0b00010000) setb(PB0); else clrb(PB0);
if(data & 0b00100000) setd(PD7); else clrd(PD7);
if(data & 0b01000000) setd(PD6); else clrd(PD6);

 

Basicamente comparo o byte com uma mascara se o resultado for verdadeiro ele acendera o led que quero. Funcionou bem mas tive que fazer mudanças no hardware e no código para funcionar.

 

Lembre aos que quiserem fazer projetos assim, faça a sua tabela alfanumérica coincidir com a disposição dos led em seu hardware facilita muito a vida.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bacana. Algo me diz que seu compilador te da acesso direto aos ports algo como

...
PORTD.PD7=data>>5; //if(data & 0b00100000) setd(PD7); else clrd(PD7);
PORTD.PD6=data>>6; //if(data & 0b01000000) setd(PD6); else clrd(PD6);
...

Se bem que pra facilitar alguma eventual portabilidade, eu (eu) faria algo como

#define led7 PORTD.PD5
//#define led7 RD5
//#define led7 GPIO2
//#define led7 PORTD.F5
//#define led7 PORTB.7
//e por aí vai.
...
led7=data>>6;

Serve pra qualquer mc e qualquer compilador

Se achar que deve, faça dos 2 jeitos e compare o assembly de ambos.

 

Dica prática: faça com que a distribuição dos bits fique de tal forma que facilite o layout pcb principalmente se for face simples. Depois é só montar a tabela e afins de acordo com tal distribuição. É soft... Ou quer mais?

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Só pra constar... mais uma de minhas historietas de casos reais...

Certa feita fiz uma comparação (necessária) entre if e switch case

algo como (só ex.)

if (a==0) b=3;
if (a==1) b=5;
if (a==2) b=17;
... //vários

comparado com:

switch (a) {
case 0: b=3;break
case 1: b=5;break
case 2: b=17;break
//..
}

Ambos com mesmíssima missão mas como se vê o switch case ficou LÍN-DÔ ... no fonte. Só que tinha só 1023 bytes de flash e não tava dando. conclusão ...  O feio if ocupou muito menos espaço. O programinha ocupou 1022 no total. 

Portanto, seu método horroroso pode ser mais eficiente do que o meu maravilhoso kk

Beleza não se põe a mesa.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não lembro qual manual de compilador que eu li,mostrava que switch usava uma tabela onde se pegava os valores,e sem o usos dele era feita comparações linha a linha.

  • 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

×