• Welcome to LusoRobótica - Robótica em Português.
 

Passar byte para bit em pic18f4550

Started by banji, 19 de October de 2012, 18:44

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

banji

Boas pessoal,

estou com um problema , estou lendo dois sinais que estao a alto=1 sempre que um vai a 0 um dos sinais quando vai a 0 envia um 1 e o outro sinal quando vai a 0 envia um 0. estou a ler bem o sinal o problema é o seguinte : depois envio por putcusart a varavel que m guarda os dados e ela aparece 000000001 00000000 000000001 0000001 00000001 0000000 00000001 00000000 00000001 00000001 00000001, quando eu queria que aparece-se 10111010111.

ja tentei ao mesmo tempo que uso os dados shiftar mas assim aparece-me 00000010 0000000 00000010 ....

Alguem sabe o que poderei fazer? estou a usar o compilador c18.

ivitro

Assim por alto tu tas a ler isso para uma variável char [8bits ou 1 byte] mete isso numa variável booleana ( 0 ou 1)

ou então quando fazes um nova leitura fazes um shift para a esquerda

banji

o que eu leio tem 27 bits logo preciso de uma variavel com 32 bits , estou a usar uma variavel do tipo double .

Sinceramente ja fiz de tudo quando shifto << shifta um bit em cada byte, ou seja não entendo pk é que esta a passar o byte em ves de bit a bit :s

ivitro

mas tu tas a ler directamente para essa variável não é??

banji

o meu codigo de leitura é este :

void leitura()

{  i=0;
 
    while(i<27) //para ler 26 bits
{

    if(PORTBbits.RB2==0 && PORTBbits.RB1==1)
      {
       data=!PORTBbits.RB2;
       while (PORTBbits.RB2==0 && PORTBbits.RB1==1);
       data=data<<1;
      }
   if(PORTBbits.RB2==1 && PORTBbits.RB1==0)
      {
       data=PORTBbits.RB1;
       data=data<<1;
        while(PORTBbits.RB2==1 && PORTBbits.RB1==0);
       
      }
i++;
}   


putcUSART(data);
     while(BusyUSART());

   

     INTCON3bits.INT2IF=0;
     INTCON3bits.INT1IF=0;
     INTCONbits.GIE=1;
     
   
}

a variavel data está como int ... estou a ler numa interrupçao no flanco descendente do INT1 e INT2


banji

estou a reparar numa coisa , no ciclo while(i<27)  se eu puser while(i<8) para ler so um byte ele continua a ter 26 bytes e a escrever um bit em cada um desses bytes alias se retirar o ciclo while ele lê na mesma :s estou a ficar maluco .....

dropes

#6
funcionaria melhor com um contador até 26

Variável=0
For Bit=0 to 26
  Aquisição do valor para "Data"
  if Data=1 then Variável = Variável or (2 ^ Bit)
Next

ps: a linguagem é outra mas trata-se de um exemplo, usar while e wend também funciona


banji

não estou a entender esta ultima parte ??? porquê o "or(2^BIT)

dropes

#8
2 elevado a um número vai dar o valor do bit inserido no byte como 1
assim coloca-se o operador OR que vai adicionar esse valor à variável final

exe:
2^5 = 10 0000 em binário (bit 5)
se o valor da variável já for 00 0101 o resultado será 10 0101 (ao colocar o operador OR)

10 0000 OR 00 0101 = 10 0101

last edit: OR é um operador lógico e não uma condição (enganei-me)

banji

com a alteração do (2^bit) é o mesmo que fazer variavel=variavel<<1 esta a deslocar um bit em cada byte.

a saida pela usart esta a ser a seguinte:00000010 00000010 00000010 00000000 00000010 00000010 00000000 00000000
00000000 00000010 00000010 00000000 00000010 00000010 00000000 00000010
00000010 00000010 00000010 00000000 00000010 00000000 00000010 00000000
00000010 00000010        e eu queria: 11101100 01101101 11101010 11    ou sja cada byte deveria ser um bit :s

em anexo envio o meu codigo, não sei o que pode estar a acontecer :s. já ando à quase uma semana com isto....

dropes

Sim, 2^bit vai dar o mesmo que shift left de 1, de qualquer forma tem de ser acrescentado o bit recebido pela uart.
Vou ver do código...

dropes

#11

variavel=0;
for (i=0;i<26;i++)
{
    if(PORTBbits.RB2==0 && PORTBbits.RB1==1) //RB2 ?! não seria "if PORTBbits.RB2==1", tem de detectar apenas o bit 0 do byte
      {
       data=!PORTBbits.RB2; //apagar, data não é usada em nenhum lado
       variavel=variavel|(2^i);
       while (PORTBbits.RB2==0 && PORTBbits.RB1==1); //RB2 ?!     
      }
   if(PORTBbits.RB2==1 && PORTBbits.RB1==0) //apagar esta condição completa
      {
       data=PORTBbits.RB1;       
        while(PORTBbits.RB2==1 && PORTBbits.RB1==0);
      } 
}   
      putcUSART(variavel); //OK


infelizmente não entendo de C, alguém poderia confirmar este código sff  :-\

ivitro

#12
tu tas a ler o bit directamente para o teu data e depois alteras o data isto 27 vezes...

lê para um buffer 0 ou 1

fazes o shit de data e depois um e adicionas o teu buffer.

ou então tens que fazer

data=data<<1 e depois
data= data| PORTBbits.RB2



data=0;

for (i=0;i<26;i++)
{
    if(PORTBbits.RB2==0 && PORTBbits.RB1==1)
    {
    data|=0;  //Alteras o primeiro bit de data para 0
    while (PORTBbits.RB2==0 && PORTBbits.RB1==1); //RB2 ?!     
    }
    if(PORTBbits.RB2==1 && PORTBbits.RB1==0) //apagar esta condição completa
    {
    data|=1;      //Alteras o primeiro Bit de data para 1
    while(PORTBbits.RB2==1 && PORTBbits.RB1==0);
    } 
    data<<=1; // shift de data para a proxima ronda alterar o primeiro bit again!
}   
      putcUSART(data); //OK


Se as tuas condições estiverem correctas vais ter na saida o que queres.

dropes

Obrigado Ivitro, é isso mesmo embora com algumas modificações:

no inicio da leitura dos 27 bits data tem de ser 0

aqui troquei as instruções (shift só depois da operação lógica)
data= data| PORTBbits.RB2
data=data<<1

no final da leitura dos 27 bits tem de haver um shift right

ivitro

Editei o meu post anterior e já meti o código...

em termos de eficiência não sei o que é melhor de fazer adição ou um OR ou até mesmo fazer um incremento

tipo:

se....
data++;
se
não faz nada

e depois o data<<=1;

tas a ver? era interessante discutirmos isto XD