Ir ao conteúdo

Posts recomendados

Postado

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
Postado

@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;

 

Postado

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
  • Membro VIP
Postado
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
  • Membro VIP
Postado
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
Postado

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
  • Membro VIP
Postado

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
  • 2 semanas depois...
  • Membro VIP
Postado

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.

Postado

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

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 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...