kaze
Newbie level 5
Dear all, I have some problem. I want to interface ATMEGA8535 with cmps03 using I2C. I have interface the ATMEGA8535 with DS1624 before and it work well, but when I interface it with cmps03, the problem I have is the data that I passed to the port always changing when I reset my AVR, supposedly the data is static (don't change)cause I didn't change the compass direction pointing way.
Here is my source code (using ICC AVR):
#include <iom8535v.h>
#include <macros.h>
//function to initial AVR port
void init_port(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x00;
DDRC = 0xFF;
PORTD = 0xFF;
DDRD = 0xFF;
}
//function to initial TWI
void init_TWI(void)
{
TWCR = 0x00; //disable TWI
TWBR = 0x0C; //bit rate = 12 | to get the SCL clock rate
TWSR = 0x00; //prescaler = 1 | 100 KHz
TWAR = 0xAA; //assign AAh for AVR to become slave mode
TWCR = 0x04; //enable TWI
}
//function to initial AVR
void initial(void)
{
CLI(); //disable ext interupt
MCUCR = 0x00; //Sleep mode off & interupt mode disable
init_port(); //initiliaze AVR Ports
init_TWI(); //initialize TWI
SEI(); //enable ext interupt
}
//function to delay for a short time
void delay(int dly)
{
int str;
for(str=0;str<=dly;str++) ;
}
//function to wait for TWI_Int
void Wait_TWI_int(void)
{
while (!(TWCR & (1<<TWINT)))
;
}
//function to send start condition
void start(void)
{
delay(15);
TWCR = ((1<<TWSTA)+(1<<TWEN)+(1<<TWINT));
Wait_TWI_int();
}
//function to send data byte and receive ACK
void send(unsigned char data)
{
delay(5);
Wait_TWI_int();
TWDR = data;
TWCR = ((1<<TWEN)+(1<<TWINT));
Wait_TWI_int();
}
//function to get data byte and send ACK
unsigned char receive1(void)
{
unsigned char data;
delay(5);
Wait_TWI_int();
TWCR = ((1<<TWINT)+(1<<TWEA)+(1<<TWEN));
Wait_TWI_int();
return data = TWDR;
}
//function to get data byte and send NACK
unsigned char receive2(void)
{
unsigned char data;
delay(5);
Wait_TWI_int();
TWCR = ((1<<TWINT)+(1<<TWEN));
Wait_TWI_int();
return data = TWDR;
}
//function to send stop condition
void stop(void)
{
delay(5);
TWCR = ((1<<TWEN)+(1<<TWSTO)+(1<<TWINT));
}
//main function that run when program started
void main(void)
{
unsigned char read,write,data;
int flag;
read = 0xC1;
write = 0xC0;
flag = 1;
initial();
while(1)
{
delay(5000); //delay time to make compass ready
data = 0xFF; //initial data
//to get direction from the CMPS03
do
{
delay(1000); //delay before I2C start
start(); //send start
send(write); //send address+write
send(0x01); //send command get direction in 1 byte
start(); //repeated start
send(read); //send address+read
data = receive1(); //get the first byte + ack
PORTB = data; //send the data byte to PORTB
stop(); //send stop
if(data != 0xFF) flag = 0;
else
{
delay(5000);
flag = 1;
}
}while(flag == 1);
while(flag == 0) ; //looping forever to make idle
}
}
Did I made some mistake in my source code or does another mistake I didn't know on the hardware?Is there any simulation program for debugging my code?
Thanks for your help
Best regards
Kaze
Here is my source code (using ICC AVR):
#include <iom8535v.h>
#include <macros.h>
//function to initial AVR port
void init_port(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x00;
DDRC = 0xFF;
PORTD = 0xFF;
DDRD = 0xFF;
}
//function to initial TWI
void init_TWI(void)
{
TWCR = 0x00; //disable TWI
TWBR = 0x0C; //bit rate = 12 | to get the SCL clock rate
TWSR = 0x00; //prescaler = 1 | 100 KHz
TWAR = 0xAA; //assign AAh for AVR to become slave mode
TWCR = 0x04; //enable TWI
}
//function to initial AVR
void initial(void)
{
CLI(); //disable ext interupt
MCUCR = 0x00; //Sleep mode off & interupt mode disable
init_port(); //initiliaze AVR Ports
init_TWI(); //initialize TWI
SEI(); //enable ext interupt
}
//function to delay for a short time
void delay(int dly)
{
int str;
for(str=0;str<=dly;str++) ;
}
//function to wait for TWI_Int
void Wait_TWI_int(void)
{
while (!(TWCR & (1<<TWINT)))
;
}
//function to send start condition
void start(void)
{
delay(15);
TWCR = ((1<<TWSTA)+(1<<TWEN)+(1<<TWINT));
Wait_TWI_int();
}
//function to send data byte and receive ACK
void send(unsigned char data)
{
delay(5);
Wait_TWI_int();
TWDR = data;
TWCR = ((1<<TWEN)+(1<<TWINT));
Wait_TWI_int();
}
//function to get data byte and send ACK
unsigned char receive1(void)
{
unsigned char data;
delay(5);
Wait_TWI_int();
TWCR = ((1<<TWINT)+(1<<TWEA)+(1<<TWEN));
Wait_TWI_int();
return data = TWDR;
}
//function to get data byte and send NACK
unsigned char receive2(void)
{
unsigned char data;
delay(5);
Wait_TWI_int();
TWCR = ((1<<TWINT)+(1<<TWEN));
Wait_TWI_int();
return data = TWDR;
}
//function to send stop condition
void stop(void)
{
delay(5);
TWCR = ((1<<TWEN)+(1<<TWSTO)+(1<<TWINT));
}
//main function that run when program started
void main(void)
{
unsigned char read,write,data;
int flag;
read = 0xC1;
write = 0xC0;
flag = 1;
initial();
while(1)
{
delay(5000); //delay time to make compass ready
data = 0xFF; //initial data
//to get direction from the CMPS03
do
{
delay(1000); //delay before I2C start
start(); //send start
send(write); //send address+write
send(0x01); //send command get direction in 1 byte
start(); //repeated start
send(read); //send address+read
data = receive1(); //get the first byte + ack
PORTB = data; //send the data byte to PORTB
stop(); //send stop
if(data != 0xFF) flag = 0;
else
{
delay(5000);
flag = 1;
}
}while(flag == 1);
while(flag == 0) ; //looping forever to make idle
}
}
Did I made some mistake in my source code or does another mistake I didn't know on the hardware?Is there any simulation program for debugging my code?
Thanks for your help
Best regards
Kaze