通訊介面是用I2C
由於89s5x沒有提供硬體I2C介面
所以就用軟體模擬
程式只是試驗用的
所以沒有寫的很嚴謹
如果G_SENSOR有問題的話
整個程式會當在ACK
有需要的人可自已在改寫
INT腳未拉出
/*
BMA020 G_SENSOR 3.3V
需注意io 可使用在16 or 32 bit mcu
USER I2C INTERFACE
By Brian @Taiwan
*/
#include "AT89X52.H"
#define GS_SDI 0x80 //P2.7 low
#define GS_SCK 0x40 //P2.6 low
#define GS_Read 0x71
#define GS_Write 0x70
void sys_init(void);
void msDelay(unsigned int MaxDelay);
void Init_GS(void);
void Send_Comm(unsigned char tx_data);
void Receive_ACK(void);
unsigned char read_Data(unsigned char send_reg);
unsigned char read_Comm(void);
void I2C_Stop(void);
void I2C_Start(void);
void Send_ACK(void);
unsigned int DelayCNT;
unsigned int TimeCNT;
void main(void)
{
unsigned char x_axis_lsb=0,x_axis_msb=0;
sys_init();
Init_GS();
while(1)
{
x_axis_lsb=read_Data(0x02);
x_axis_msb=read_Data(0x03);
//you code
}
}
void sys_init(void)
{
//ALL SYSTEM REG SET
IE = 0x82; //USER INTERRUPT TIME0
TMOD = 0x02; //SET TIME 0 MODE
TH0 = 256-200; //SET RELOAD VALUE
TL0 = 256-200; // FAST VALUE
TimeCNT=0;
TR0=1; //time enabled
P2 = 0x00; //gs port default
}
void Time0_int(void)interrupt 1
{
TimeCNT++;
if(TimeCNT>=10)
{
DelayCNT++;
TimeCNT=0;
}
}
void msDelay(unsigned int MaxDelay)
{
DelayCNT = 0x0000;
while(DelayCNT < MaxDelay) {}
}
void Init_GS(void)
{
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(0x0A); //regedit
Receive_ACK();
Send_Comm(0x02); //soft reset
Receive_ACK();
I2C_Stop();
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(0x14);
Receive_ACK();
Send_Comm(0x16); //+/-4g 1500hz
Receive_ACK();
I2C_Stop();
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(0x15);
Receive_ACK();
Send_Comm(0x40);//enable adv_int
Receive_ACK();
I2C_Stop();
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(0x11);
Receive_ACK();
Send_Comm(0x00);//any_motion_dur hg lg set
Receive_ACK();
I2C_Stop();
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(0x0F);
Receive_ACK();
Send_Comm(0x0A); //hg_dur
Receive_ACK();
I2C_Stop();
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(0x0E);
Receive_ACK();
Send_Comm(0xE0); //hg_thres
Receive_ACK();
I2C_Stop();
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(0x0C);
Receive_ACK();
Send_Comm(0x10); //lg_thres
Receive_ACK();
I2C_Stop();
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(0x0B);
Receive_ACK();
Send_Comm(0x57); //any & hg & lg_enable hg & lg_counter
Receive_ACK();
I2C_Stop();
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(0x0A);
Receive_ACK();
Send_Comm(0x00);
Receive_ACK();
I2C_Stop();
}
void Send_Comm(unsigned char tx_data)
{
unsigned char Port_status;
unsigned char temp;
int i;
for(i=0;i<8;i++)
{
temp = tx_data & GS_SDI;
Port_status = P2;
if(temp)
Port_status |= GS_SDI;
else
Port_status &= ~GS_SDI;
P2 = Port_status;
tx_data<<=1;
// msDelay(1);
P2 |= GS_SCK;
// msDelay(1);
P2 &= ~GS_SCK;
// msDelay(1);
}
}
void Receive_ACK(void)
{
unsigned int i,temp;
P2 |= GS_SDI;
// msDelay(1);
P2 |= GS_SCK;
i=1;
while(i)
{
temp = P2;
temp &=GS_SDI;
if(temp==0)
i=0;
// msDelay(1);
}
P2 &= ~GS_SCK;
// msDelay(1);
}
void I2C_Start(void)
{
P2 |= GS_SCK;
P2 |= GS_SDI;
//msDelay(2);
P2 &= ~GS_SDI;
// msDelay(2);
P2 &= ~GS_SCK;
//msDelay(2);
}
void I2C_Stop(void)
{
P2 |= GS_SCK;
// msDelay(2);
P2 |= GS_SDI;
}
unsigned char read_Data(unsigned char send_reg)
{
unsigned char Rx_data;
I2C_Start();
Send_Comm(GS_Write);
Receive_ACK();
Send_Comm(send_reg);
Receive_ACK();
I2C_Stop();
//msDelay(1);
I2C_Start();
Send_Comm(GS_Read);
Receive_ACK();
// msDelay(1);
Rx_data = read_Comm();
Send_ACK();
I2C_Stop();
return Rx_data;
}
unsigned char read_Comm(void)
{
unsigned char Port_status;
unsigned char temp=0x00;
int i;
for(i=0;i<8;i++)
{
Port_status=P2 & GS_SDI;
Port_status>>=i;
temp|= Port_status;
// msDelay(1);
P2 |= GS_SCK;
// msDelay(1);
P2 &= ~GS_SCK;
// msDelay(1);
}
return temp;
}
void Send_ACK(void)
{
P2 &= ~GS_SDI;
// msDelay(1);
P2 |= GS_SDI;
// msDelay(1);
}
沒有留言:
張貼留言