Witam wszystkich,
mam duże trudności z nawiązaniem komunikacja z kompasem cyfrowym HMC5843 przez protokół I2C.
Wszystko ma działać na atmega8 (master) 3,3v @ 4MHz, bezpośrednio połączona z układem (slave).
Pull-up'y na liniach SDA i SCL przez rezystory 4k7 są obecne.
Komunikacja z prędkości 100kHz (sprawdzałem też dla 40 i 50kHz, efekt ten sam).
Po uruchomieniu modułu TWI (procedura i2cInit() ), obie linie przechodzą w stan wysoki.
Po uruchomieniu procedury wysyłającej instrukcje startowe dla kompasu (żeby dokonywał pomiaru ciągłego) obie linie przechodzą w stan niski - permanentnie.
Po każdorazowym wysłaniu danych lub adresu przez TWI/I2C w rejestrze TWSR powinien pojawiać się Status Code informujący o efekcie operacji.
Po wywołaniu init_hmc5843(); wartości status code to:
1) i2cSendStart();
Status Code: 0xA8
2) i2cSendByte(HMC5843_WRITE); //write to the HMC5843
Status Code: 0x80
3) i2cSendByte(0x02); //Write to Mode register
Status Code: 0x80
4) i2cSendByte(0x00); //Clear bit 1, the MD1 bit
Status Code: 0x80
Podstawowy problem, to fakt, że żadne z tych kodów nie należy do trybu Master Transmitter (tabela 66 na stronie 180 datasheet).
Występują w tabelach błędów dla SLAVE
0xA8 - slave transmitter, tabela 69
0x80 - slave receiver, tabela 68
Ma ktoś pomysł od czego zacząć ?
Nie mam możliwości sprawdzenia kompasu, dodam tylko tyle, że jest świeży ze sklepu, przyszedł polutowany do płytki.
=============================
=============================
11.10.10
Update.
Problem został rozwiązany, zamykam temat.
mam duże trudności z nawiązaniem komunikacja z kompasem cyfrowym HMC5843 przez protokół I2C.
Wszystko ma działać na atmega8 (master) 3,3v @ 4MHz, bezpośrednio połączona z układem (slave).
Pull-up'y na liniach SDA i SCL przez rezystory 4k7 są obecne.
Komunikacja z prędkości 100kHz (sprawdzałem też dla 40 i 50kHz, efekt ten sam).
Po uruchomieniu modułu TWI (procedura i2cInit() ), obie linie przechodzą w stan wysoki.
Po uruchomieniu procedury wysyłającej instrukcje startowe dla kompasu (żeby dokonywał pomiaru ciągłego) obie linie przechodzą w stan niski - permanentnie.
Po każdorazowym wysłaniu danych lub adresu przez TWI/I2C w rejestrze TWSR powinien pojawiać się Status Code informujący o efekcie operacji.
Po wywołaniu init_hmc5843(); wartości status code to:
1) i2cSendStart();
Status Code: 0xA8
2) i2cSendByte(HMC5843_WRITE); //write to the HMC5843
Status Code: 0x80
3) i2cSendByte(0x02); //Write to Mode register
Status Code: 0x80
4) i2cSendByte(0x00); //Clear bit 1, the MD1 bit
Status Code: 0x80
Podstawowy problem, to fakt, że żadne z tych kodów nie należy do trybu Master Transmitter (tabela 66 na stronie 180 datasheet).
Występują w tabelach błędów dla SLAVE
0xA8 - slave transmitter, tabela 69
0x80 - slave receiver, tabela 68
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define HMC5843_WRITE 0x3C
#define HMC5843_READ 0x3D
#define HMC5843_CON_MES 0x00
#define TRUE -1
#define FALSE 0
#define START 0x08
#define SLA_W_ACK 0x18
#define DATA_ACK 0x28
// Function declaration
// ************************************
void IOinit(void);
int16_t read_hmc5843(char reg_adr);
void init_hmc5843(void);
void i2cInit(void);
void i2cSetBitrate(uint8_t bitrateKHz);
void i2cSendStart(void);
void i2cSendStop(void);
void i2cWaitForComplete(char status);
void i2cSendByte(unsigned char data);
unsigned char i2cReceiveByte(void);
int main(void)
{
uint16_t znak = 0;
IOinit();
i2cInit();
_delay_ms(100);
init_hmc5843();
_delay_ms(100);
for(;;)
{
}
}
// ###########################################################
void IOinit(void)
{
//1 = output, 0 = input
DDRC = _BV(PC5) | _BV(PC4);
DDRB = 0b00000001;
PORTC = _BV(PC5) | _BV(PC4); //pullups on the I2C bus
}
//=================================
void i2cInit(void)
{
// set i2c bit rate to 100 [kHz]
i2cSetBitrate(100);
TWDR = 0xFF; // Default content = SDA released.
// enable TWI (two-wire interface)
TWCR = (1<<TWEN); // Enable TWI
}
//=================================
void init_hmc5843(void)
{
i2cSendStart();
i2cWaitForComplete(START);
i2cSendByte(HMC5843_WRITE); //write to the HMC5843
i2cWaitForComplete(SLA_W_ACK);
i2cSendByte(0x02); //Write to Mode register
i2cWaitForComplete(DATA_ACK);
i2cSendByte(0x00); //Clear bit 1, the MD1 bit
i2cWaitForComplete(DATA_ACK);
i2cSendStop();
}
//=================================
void i2cSetBitrate(uint8_t bitrateKHz)
{
uint8_t bitrate_div;
// i2c Prescaler Value = 1
TWSR = 0x00;
// wyliczenie wartości dla TWI Bit Rate Register
// SCL freq = F_CPU/(16+2*TWBR))
bitrate_div = (((FOSC/1000/bitrateKHz)-16)/2);
TWBR = bitrate_div;
}
//=================================
void i2cSendStart(void)
{
// send start condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
}
//=================================
void i2cSendStop(void)
{
// transmit stop condition
TWCR = (1<TWINT) | (1<<TWEN) | (1<<TWSTO);
}
//=================================
void i2cWaitForComplete(char status)
{
char i = 0;
// wait for i2c interface to complete operation
while ((!(TWCR & (1<<TWINT))) && (i < 90))
{
_delay_ms(1);
i++;
}
}
//=================================
void i2cSendByte(unsigned char data)
{
_delay_ms(1);
// save data to the TWDR
TWDR = data;
// begin send
TWCR = (1<<TWINT) | (1<<TWEN);
}
Ma ktoś pomysł od czego zacząć ?
Nie mam możliwości sprawdzenia kompasu, dodam tylko tyle, że jest świeży ze sklepu, przyszedł polutowany do płytki.
=============================
=============================
11.10.10
Update.
Problem został rozwiązany, zamykam temat.