Ir ao conteúdo
  • Cadastre-se

Mario Henrique Luchiari

Membro Júnior
  • Posts

    5
  • Cadastrado em

  • Última visita

Tópicos solucionados

  1. O post de Mario Henrique Luchiari em PIC 18F4550 com Bússola Eletrônica HMC5883L foi marcado como solução   
    Boa tarde, .if e pessoal do clube!
    Desculpem a minha demora em continuar postando. Estou com uma carga grande de trabalho. A carga ainda está grande mas, reservei um tempinho para dizer que resolvi o problema. Eram os registradores que estavam errados, inclusive o endereço I2C. Isso eu desconfiava desde o começo...
     
    Em primeiro lugar o módulo que comprei é uma enganação. Tomem cuidado! Vem apresentado como HMC5883 mas na verdade é QMC5883. A diferença? É brutal! Até o datasheet do QMC é chato de achar. Quando comparar os dois, verá que está tudo diferente. Acertei o endereço e os registradores e pufff! O trem funcionou!
     
    Em segundo lugar descobri o endereço na marra. Como? Fiz um programa que testa endereço por endereço até o módulo, que é escravo, responder. Deu certo! Aí que eu fui me tocar que o chip podia ser outro. Pesquisei e descobri que quando o chip tem a inscrição DA5883 é QMC5883 e quando tem L883 é HMC5883L. Vejam nas fotos.
      
     
    Em terceiro, acabei aprendendo muito sobre I2C, a ponto de colocar num osciloscópio para analisar o protocolo! Cheguei à conclusão que, quando o endereço está errado e o chip não responde, a linha do clock que é a amarela só completa a primeira parte (observe que esta possui (quase) três partes sutilmente separadas). Esta primeira parte é o envio do endereço do mestre para o escravo. Quando não obtém resposta do escravo, a sequência termina. A linha azul é a linha de dados, que é o SDA.
    A sequência desta foto está completa. Ela é de uma comunicação bem sucedida entre mestre e escravo com endereço 0x1A.

     
    Quem tiver interesse no código vou postar aqui e considerar esse tópico encerrado!
     
    Muito obrigado, .if! você ajudou bastante! 
     
    Atenção! Este código é para o QMC5883 e não para o HMC5883.
    /*Apesar de ter requisitado o HMC5883 e na placa do módulo estar escrito isso, o módulo possui o CI QMC5883 cujos endereços de registradores diferem do HMC. Após muita luta e pesquisa, consegui descobrir isso. Este código faz o QMC funcionar de maneira básica, apenas indicando os valores dos eixos X, Y e Z no display LCD 16 x 2 selecionados por um botão no PORTB.F2. A sequência apresenta X, Y, Z e por último a situação de todos os registradores, de 0x00 a 0x0D. Reconheço que consegui com a ajuda, a graça e pela glória de Deus! Versão: e São Carlos, 26 de novembro de 2020. ------------------------------------------------------------------------------*/ //Habilitar as bibliotecas: // I2C, Conversions, C_String e C_Math // RB0 -> SDA e RB1 -> SDL #define QMC5883_ADDRESS 0x1A #define DATA_OUTPUT_REG 0x00 // São de 0x00 a 0x05 #define STATUS_REG 0x06 #define TEMPL_OUTPUT_REG 0x07 #define TEMPH_OUTPUT_REG 0x08 #define CONTROL1_REG 0x09 #define CONTROL2_REG 0x0A #define SETRESET_REG 0x0B #define IDENTIFICATION_REG 0x0D #define botao PORTB.F2 // LCD module connections sbit LCD_RS at RE0_bit; sbit LCD_EN at RE1_bit; sbit LCD_D4 at RD0_bit; sbit LCD_D5 at RD1_bit; sbit LCD_D6 at RD2_bit; sbit LCD_D7 at RD3_bit; sbit LCD_RS_Direction at TRISE0_bit; sbit LCD_EN_Direction at TRISE1_bit; sbit LCD_D4_Direction at TRISD0_bit; sbit LCD_D5_Direction at TRISD1_bit; sbit LCD_D6_Direction at TRISD2_bit; sbit LCD_D7_Direction at TRISD3_bit; // End LCD module connections signed int tmp, tmpx, tmpy, tmpz, tmpr; char tmp1, tmp2, valor, trava, eixo, trava2, hexa; char txt[7], *hexindic = "0x00"; void QMC5883L_Inicio(void){ PORTB.F4 = 1; //Indica entrada no modo inicialização I2C1_Start(); I2C1_Wr( QMC5883_ADDRESS ); I2C1_Wr( CONTROL1_REG ); //I2C1_Wr( 0x1D ); //OSR 512, Scale Range 8 Gauss, ODR 200Hz, Continuous mode I2C1_Wr( 0x0D ); //OSR 512, Scale Range 2 Gauss, ODR 200Hz, Continuous mode I2C1_Stop(); I2C1_Start(); I2C1_Wr( QMC5883_ADDRESS ); I2C1_Wr( CONTROL2_REG ); I2C1_Wr( 0x41 ); I2C1_Stop(); PORTB.F4 = 0; //Indica entrada no modo inicialização } signed int QMC5883_Leitura(void){ PORTB.F5 = 1; //Indica entrada no modo leitura I2C1_Start(); I2C1_Wr( QMC5883_ADDRESS ); if(eixo == 3) I2C1_Wr( valor ); //Ler o valor dos registradores else I2C1_Wr( DATA_OUTPUT_REG ); I2C1_Repeated_Start(); I2C1_Wr( QMC5883_ADDRESS | 1 ); if(eixo == 3) tmpr = I2C1_Rd(0); //Ler o valor dos registradores else{ tmpx = I2C1_Rd(1); tmpx |= I2C1_Rd(1) << 8; tmpy = I2C1_Rd(1); tmpy |= I2C1_Rd(1) << 8; tmpz = I2C1_Rd(1); tmpz |= I2C1_Rd(0) << 8; } I2C1_Stop(); PORTB.F5 = 0; //Indica saída do modo leitura } char hexadec(char hexanum){ if((hexanum >> 4) < 10) hexindic[2] = (hexanum >> 4) +48; else hexindic[2] = (hexanum >> 4) +55; if((hexanum & 0x0F) < 10) hexindic[3] = (hexanum & 0x0F) +48; else hexindic[3] = (hexanum & 0x0F) +55; Lcd_Out_CP(hexindic); //Escreve hexindic depois do texto } void main() { ADCON1 = 0x0F; //desativa o canal analogico CMCON = 7; //desativa os comparadores analogicos TRISB = 0x0F; PORTB = 0x00; valor = 0; trava = 0; eixo = 0; trava2 = 0; //RBPU_bit = 0; Lcd_Init(); //inicia o display Lcd_Cmd(_LCD_CLEAR); //Limpa a tela do LCD Lcd_Cmd(_LCD_CURSOR_OFF); //Desliga o cursor piscante Delay_ms(100); Lcd_Out(1,1,"QMC5883e-Simples"); Delay_ms(500); I2C1_Init(100000); //Inicializa comunicação I2C Delay_ms(50); QMC5883L_Inicio(); //Inicializa o módulo QMC5883. Engraçado que sem... Delay_ms(50); //... inicializar pela segunda vez, às vezes falha! QMC5883L_Inicio(); //Inicializa o módulo QMC5883 novamente !!! while(1) { QMC5883_Leitura(); //Lê o módulo if(!eixo){ if(trava2){ Lcd_Out(1,1,"QMC5883e-Simples"); Lcd_Out(2,1," "); } Lcd_Out(2,5,"X:"); IntToStr(tmpx, txt); Lcd_Out_CP(txt); valor = 0; trava2 = 0; } if(eixo == 1){ Lcd_Out(2,5,"Y:"); IntToStr(tmpy, txt); Lcd_Out_CP(txt); } if(eixo == 2){ Lcd_Out(2,5,"Z:"); IntToStr(tmpz, txt); Lcd_Out_CP(txt); } if(eixo == 3){ if(!trava2) Lcd_Cmd(_LCD_CLEAR); trava2 = 1; Lcd_Out(1,3,"Reg: "); hexadec(valor); Lcd_Out(2,3,"Valor: "); hexadec(tmpr); valor++; if(valor > 0x0D) valor = 0; Delay_ms(1000); } Delay_ms(500); if(!botao && !trava){ trava = 1; eixo++; if(eixo > 3) eixo = 0; } if(botao) trava = 0; } }  

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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!