#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include "delay.h"
#include "iic.h"
#define iic_checkack iic_getbit
#define SDA PORTB_PB6
#define SCL PORTB_PB7
#define MMA8452 0b0011100
void iic_init(void){
DDRB_DDRB6=1;DDRB_DDRB7=1;
SCL=0;
SDA=1;
SCL=1;
iic_writevalue(MMA8452,0x2a,0);//进入standby模式
iic_writevalue(MMA8452,0x2a,0b00010100);//low noise模式 输出频率200HZ
iic_writevalue(MMA8452,0x0e,0);//关闭高通输出 量程2G
iic_writevalue(MMA8452,0x2b,0b00000010);//high resolution 在800HZ输出情况下无意义 100hz下可以提高精度
iic_writevalue(MMA8452,0x2a,0b00010101);//进入active模式 开始工作
}
void iic_ack(void){
DDRB_DDRB6=1;
SCL=0;
SDA=0;
delayus(1);
SCL=1;
delayus(1);
SCL=0;
}
void iic_nack(void){
DDRB_DDRB6=1;
SCL=0;
SDA=1;
delayus(1);
SCL=1;
delayus(1);
SCL=0;
}
void iic_start(void){
DDRB_DDRB6=1;
SCL=0;
SDA=1;
SCL=1;
delayus(1);
SDA=0;
delayus(1);
SCL=0;
}
void iic_stop(void){
DDRB_DDRB6=1;
SCL=0;
delayus(1);
SDA=0;
delayus(1);
SCL=1;
delayus(1);
SDA=1;
delayus(1);
}
void iic_writebit(unsigned char writebit){
DDRB_DDRB6=1;
SCL=0;
delayus(1);
SDA=writebit;
delayus(1);
SCL=1;
delayus(1);
SCL=0;
}
void iic_writebyte(unsigned char writebyte){
char temp;
for(temp=8;temp>0;temp--){
iic_writebit(writebyte>>7);
writebyte<<=1;
}
}
unsigned char iic_getbit(){
char returnchar;
DDRB_DDRB6=0;
SCL=0;
delayus(1);
SCL=1;
delayus(1);
returnchar=SDA;
SCL=0;
return returnchar;
}
unsigned char iic_getbyte(){
char temp,returnchar;
returnchar=0;
for(temp=8;temp>0;temp--)returnchar=(returnchar<<1)|iic_getbit();
return returnchar;
}
long iic_getvalue(unsigned char device_addr,unsigned char register_addr,unsigned char bytenumber){
long returnvalue=0;
char temp=bytenumber;
start:
bytenumber=temp;
iic_start();
iic_writebyte((device_addr<<1)|0);
if(iic_checkack()){
iic_stop();
goto start;
}
iic_writebyte(register_addr);
if(iic_checkack()){
iic_stop();
goto start;
}
iic_start();
iic_writebyte((device_addr<<1)|1);
if(iic_checkack()){
iic_stop();
goto start;
}
for(;bytenumber>0;bytenumber--){
returnvalue=(returnvalue<<8)|iic_getbyte();
if(bytenumber-1)iic_ack();
else iic_nack();
}
iic_stop();
return returnvalue;
}
void iic_writevalue(unsigned char device_addr,unsigned char register_addr,unsigned char writevalue){
start:
iic_start();
iic_writebyte((device_addr<<1)|0);
if(iic_checkack()){
iic_stop();
goto start;
}
iic_writebyte(register_addr);
if(iic_checkack()){
iic_stop();
goto start;
}
iic_writebyte(writevalue);
if(iic_checkack()){
iic_stop();
goto start;
}
iic_stop();
}