Ir ao conteúdo

Duvida I2C


Francisco. F

Posts recomendados

Postado

Boa tarde,

estou com alguns problemas em conseguir escrever 2 bytes seguidos no barramento I2C.

O que pretendo fazer é ler o valor de tensão e corrente de um fio.

Utilizo um pic16f690 e o sensor é o INA209.

O compilador é o CCS e uso o MPlab.

Sou iniciante na electronica e tenho dificuldade em perceber o funcionamento deste sensor.

a minha ideia era ler o valor de tensão mas acho que algo está mal.

O programa que estou a fazer é este:

#if defined(__PCM__)

#include <16F690.h>

#device ADC=8

#fuses INTRC_IO,NOPROTECT,NOBROWNOUT,NOMCLR,NOCPD,NOWDT,NOPUT,NOIESO,NOFCMEN,BROWNOUT_NOSL

#use delay(clock=4000000)

#endif

#define I2C_SDA PIN_B4 //Define pinos i2c microcontrolador

#define I2C_SCL PIN_B6

#define Ina209 0b10000000 //Define endereço Ina209

#use i2c(master, sda=I2C_SDA, scl=I2C_SCL,slow) // Configure Device as Master

char volt[2];

void inicio_i2c (void) //Inicio comunicaçao i2c

{

output_float(I2C_SDA);

output_float(I2C_SCL);

}

void config_ina209(void) //Configuration Register

{

i2c_start();

i2c_write(Ina209);

i2c_write(0x00);

i2c_write(0b00110000);

i2c_write(0b01000111);

i2c_stop();

}

void read_bus_volt(void) // Read Bus Voltage Register

{

i2c_start();

i2c_write(0x04);

i2c_write(Ina209);

i2c_start();

i2c_write(0b10000001);

volt[0] = i2c_read();

volt[1]= i2c_read(0);

i2c_stop();

if (volt[1]==128)

volt[1]==5;

else

volt[1]==0;

}

inicio_i2c();

config_ina209();

void main()

{

setup_oscillator(OSC_4MHZ);

delay_ms(255);

setup_adc(ADC_OFF);

setup_adc_ports(NO_ANALOGS);

setup_comparator(0x00);

{

while (true)

read_bus_volt();

if(volt[0]<3);

output_bit(PIN_C3, 1);

delay_ms(1000);

delay_ms(1000);

}

}

Se alguem me puder ajudar agradeço.

Abraço

Postado

Acho que sei onde está o problema, veja a função:


void read_bus_volt(void) // Read Bus Voltage Register
{
i2c_start();
i2c_write(0x04);
i2c_write(Ina209);
[B][I]i2c_start();[/I][/B] //você esta dando dois starts seguidos isso nao é necessario
i2c_write(0b10000001);
volt[0] = i2c_read();
volt[1]= i2c_read(0);
i2c_stop();
if (volt[1]==128)
volt[1]==5;
else
volt[1]==0;
}


ficaria melhor assim:

void_read_bus_volt ((int*) pointer)
{
i2c_start();
i2c_write(0x04);
i2c_write(Ina209);
i2c_write(0b10000001);
*pointer = i2c_read(); // le primeiro valor
*pointer ++;
*pointer = i2c_read(); //le proximo valor
i2c_stop();
} //as duas leituras estarao em volt <0:1>


dúvidas pergunte, Abs.

Postado

Boas Filipe,

Obrigado pela sua ajuda.

Mesmo assim com a substituiçao o compilador dá-me 19 erros, desculpa a minha ignorância mas não percebo muito disto.

Se puderes dar uma explicaçao do teu codigo era bacano.

Abraço

Postado

Francisco, é muito simples, talvez tenha retornado erro pois você não chamou a função da maneira correta, veja que esse minha função você deve passar um valor como ponteiro, faço isso para economia de pilha e processamento, além de evitar o uso de "return"

veja só, como essa função deve ser chamada no seu codigo:


#include <16F690.h>

#device ADC=8
#fuses INTRC_IO,NOPROTECT,NOBROWNOUT,NOMCLR,NOCPD,NOWDT,N OPUT,NOIESO,NOFCMEN,BROWNOUT_NOSL
#use delay(clock=4000000)



#define I2C_SDA PIN_B4 //Define pinos i2c microcontrolador
#define I2C_SCL PIN_B6
#define Ina209 0b10000000 //Define endereço Ina209


#use i2c(master, sda=I2C_SDA, scl=I2C_SCL,slow) // Configure Device as Master
char volt[2];

void inicio_i2c (void) //Inicio comunicaçao i2c
{
output_float(I2C_SDA);
output_float(I2C_SCL);
}

void config_ina209(void) //Configuration Register
{
i2c_start();
i2c_write(Ina209);
i2c_write(0x00);
i2c_write(0b00110000);
i2c_write(0b01000111);
i2c_stop();
}

void_read_bus_volt ((int *) pointer)
{
i2c_start();
i2c_write(0x04);
i2c_write(Ina209);
i2c_write(0b10000001);
*pointer = i2c_read(); // le primeiro valor
*pointer ++;
*pointer = i2c_read(); //le proximo valor
i2c_stop();
} //as duas leituras estarao em volt <0:1>

void main()
{

setup_oscillator(OSC_4MHZ);
delay_ms(255);

setup_adc(ADC_OFF);
setup_adc_ports(NO_ANALOGS);
setup_comparator(0x00);
inicio_i2c(); //inicializa I2C
config_ina209(); //configura sensor de corrente
{
while (true)

read_bus_volt(&volt); //passa ponteiro para a variavel

output_b (volt[0]); //mostra o primeiro valor lido do ina209
delay_ms(1000);//espera 1 seg
output_b(volt[1]); //mostra segundo byte lido do ina209
delay_ms(1000);
}

}

faça o teste e veja seo programa le o valor e coloca no portB.

Abs.

Postado

Esta é a parte de configuração de registos.

#if defined(__PCM__)

#include <16F690.h>

#device ADC=8

#fuses INTRC_IO,NOPROTECT,NOBROWNOUT,NOMCLR,NOCPD,NOWDT,NOPUT,NOIESO,NOFCMEN,BROWNOUT_NOSL

#use delay(clock=4000000)

#pragma use rs232(baud=19200, xmit=PIN_B7, rcv=PIN_B5)

#endif

#define I2C_SDA PIN_B4 //Define pinos i2c microcontrolador

#define I2C_SCL PIN_B6

#define Ina209 0b10000000 //Define endereço Ina209

#define Max5477 0b01010000 // define endereço Max5477

#use i2c(master, sda=I2C_SDA, scl=I2C_SCL,slow) // Configure Device as Master

unsigned char valores[8]={0,0,0,0,0,0,0,0};

unsigned char tensao_u,tensao_f, corrente_u, corrente_f,potencia_u,potencia_f;

int1 flag_corrente;

int1 flag_potencia;

float aux;

//unsigned int max5479;

//unsigned int print;

//****************************************INA209*************************************

void INA209_config()

{

i2c_start();

i2c_write(INA209); // control byte

i2c_write(0x00); // word address

i2c_write(0b00000111);

i2c_write(0b11111111);

i2c_stop();

delay_ms(100);

i2c_start();

i2c_write(INA209); // control byte

i2c_write(0x16); // word address

i2c_write(0x78); // data

i2c_write(0x31);

i2c_stop();

delay_ms(100);

}

void INA209_read()

{

i2c_start();

i2c_write(INA209);

i2c_write(0x06);

i2c_start();

i2c_write(INA209 | 0x01);

valores[2]=i2c_read();

valores[3]=i2c_read();

i2c_stop();

//corrente=(a*256)+b;

//corrente/=1000;

i2c_start();

i2c_write(INA209);

i2c_write(0x04);

i2c_start();

i2c_write(INA209 | 0x01);

valores[4]=i2c_read();

valores[5]=i2c_read();

i2c_stop();

// tensão=(a*256)+b;

// tensão/=2000;

i2c_start();

i2c_write(INA209);

i2c_write(0x05);

i2c_start();

i2c_write(INA209 | 0x01);

valores[6]=i2c_read();

valores[7]=i2c_read();

i2c_stop();

// potencia=((a*256)+B);

// potencia/=50;

}

Agora é a parte dos calculos

INA209_read();

//tensão

aux= (float)valores[4]*256;

aux+=valores[5];

aux/=2000;

tensao_u=(unsigned char)aux;

tensao_f=(unsigned char)((aux-tensao_u)*100);

/* if(aux<4.0){

max5479++;

max5479_write();

max5479--;

max5479_write();

}*/

//Corrente

aux=(float)valores[2]*256;

aux+=valores[3];

if(aux<20000){

aux/=20;

corrente_u=(unsigned char)aux;

corrente_f=(unsigned char)((aux-corrente_u)*100);

flag_corrente=1;

/* if(aux<10.0){

max5479++;

max5479_write();

}

else{*/

// max5479--;

// max5479_write();

// }

}

else{

aux/=20000;

corrente_u=(unsigned char)aux;

corrente_f=(unsigned char)((aux-corrente_u)*100);

flag_corrente=0;

}

//Potencia

aux=(float)valores[6]*256;

aux+=valores[7];

if(aux<1000){

potencia_u=(unsigned char)aux;

potencia_f=(unsigned char)((aux-potencia_u)*100);

flag_potencia=1;

}

else{

aux/=1000;

potencia_u=(unsigned char)aux;

potencia_f=(unsigned char)((aux-potencia_u)*100);

flag_potencia=0;

}

Para quem quiser usar esse sensor tem de calibrar conforme a resistencia que está a usar.

Mais uma vez obrigado Filipe, foi muito util a sua ajuda.

  • Coordenador
Postado

Caso o autor do tópico necessite, o mesmo será reaberto, para isso deverá entrar em contato com a moderação solicitando o desbloqueio.

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!