|
各位大神,最近小弟正在调硬件IIC总线,一直都很头疼,现在求救于各位大大,先贴出程序!
/*The slave address of the MPU-60X0 is b110100X which is 7 bits lengths.the address of the devices should be b1101000(0xD0)(pin AD0 is logic low),by then,the writing address is 0xD0 and the reading address is 0xD1 */
/*the interface is as follows,SCLJ7 SDAJ6 */
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#define SlaveAddress 0xD0
//****************************************
// ¶¨òåMPU6050Äú2¿μØÖ·
//****************************************
#define SMPLRT_DIV 0x19 //íóÂYòÇ2éÑùÂ꣬μäDíÖμ£o0x07(125Hz)
#define CONFIG 0x1A //μíí¨ÂË2¨ÆμÂ꣬μäDíÖμ£o0x06(5Hz)
#define GYRO_CONFIG 0x1B //íóÂYòÇ×Լ켰2aá¿·¶Î§£¬μäDíÖμ£o0x18(2»×Լ죬2000deg/s)
#define ACCEL_CONFIG 0x1C //¼óËù¼Æ×Լ졢2aá¿·¶Î§¼°¸ßí¨ÂË2¨ÆμÂ꣬μäDíÖμ£o0x01(2»×Լ죬2G£¬5Hz)
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define PWR_MGMT_1 0x6B //μçÔ′1üàí£¬μäDíÖμ£o0x00(Õy3£ÆôóÃ)
#define WHO_AM_I 0x75 //IICμØÖ·¼Ä′æÆ÷(ĬèÏêyÖμ0x68£¬Ö»¶á)
struct Mpu_data{
sWord Accel_X;
sWord Accel_Y;
sWord Accel_Z;
sWord Temp;
sWord Gyro_X;
sWord Gyro_Y;
sWord Gyro_Z;
}mpu_data;
struct IMU{
float a_x;
float a_y;
float a_z;
float gyro_x;
float gyro_y;
float gyro_z;
}Imu_data;
void delay(word time)
{
word i=0,j=0;
while(time--)
{
for(i=0;i<25;i++)
for(j=0;j<1200;j++)
asm("nop");
}
}
/*************************************************************/
/* 3õê¼»ˉËøÏà»· */
/*************************************************************/
void PLL_init(void)
{
CLKSEL=0X00; //disengage PLL to system
PLLCTL_PLLON=1; //turn on PLL
SYNR =0xc0 | 0x07;
REFDV=0x80 | 0x01;
POSTDIV=0x00; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=128MHz;
_asm(nop); //BUS CLOCK=64M
_asm(nop);
while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it;
CLKSEL_PLLSEL =1; //engage PLL to system;
asm NOP;
asm NOP;
while(!(CRGFLG&0x08)); //PLLCLK is Locked already
CLKSEL |= 0x80; //set PLLCLK as sysclk
}
//-----I2C 3õê¼»ˉ3ìDò --------//
void I2C_Bus_init(void)
{
IIC0_IBFD=0x65; //this choose f(I2C)=100K,sda hold=1.53125us,scl hold start=4.9375us,scl hold stop=5.13125us
IIC0_IBAD=0xF4; //choose slave address of the chip,ensure that this is not the address of MPU6050
IIC0_IBCR|=0x80;//enable I2C system
IIC0_IBCR|=0x30;//disable I2C interrupt,choose Slave mode,Tx mode,then it generates a P signal
IIC0_IBSR_IBAL=1;//set the bus to be idle
}
void I2C_Single_Write(uchar REG_Address,uchar REG_data){
IIC0_IBCR=0xB0;//master mode ,Tx mode ,then it generates a S signal
//while(!IIC0_IBSR_IBB);
IIC0_IBDR=SlaveAddress;// send AD+W
while(IIC0_IBSR_RXAK);//wait ACK
IIC0_IBDR=REG_Address; //send RA
while(IIC0_IBSR_RXAK);//wait ACK
IIC0_IBDR=REG_data; //send DATA
while(IIC0_IBSR_RXAK);//wait ACK
IIC0_IBCR=0x80;
}
//**************************************
//′óI2Cé豸¶áè¡ò»¸ö×Ö½úêy¾Y
//**************************************
byte I2C_Single_Read(byte REG_Address)
{
byte REG_data;
IIC0_IBCR=0xB0;//master mode ,Tx mode ,then it generates a S signal
IIC0_IBDR=SlaveAddress;// send AD+W
//while(IIC0_IBSR_RXAK);//wait ACK
IIC0_IBDR=REG_Address; //send RA
while(IIC0_IBSR_RXAK);//wait ACK
IIC0_IBCR_RSTA=1;//send Repeat_S signal
IIC0_IBDR=SlaveAddress+1;// send AD+R
IIC0_IBCR_TX_RX=0;// turn to receive
// IIC0_IBCR_TXAK=1;
while(IIC0_IBSR_RXAK);//wait ACK
//IIC0_IBCR_RSTA=0;//close Repeat_S signal
REG_data=IIC0_IBDR;
while(!IIC0_IBSR_IBIF);
IIC0_IBSR_IBIF=1;
IIC0_IBCR=0x80; //send P
while(IIC0_IBSR_IBB);
REG_data=IIC0_IBDR; //when the data is read,then the bus turn to busy,the IBSR is 0x36,so the NACK has not been sent
return REG_data;
}
//**************************************
//′óI2Cé豸¶áè¡N¸ö×Ö½úêy¾Y
//**************************************
/*void Burst_ReadI2C(byte REG_Address)
{
byte i;
byte* add;
add=(byte*)&(mpu_data.Accel_X);
I2C_Start(); //Æeê¼DÅoÅ,S
I2C_Send(0xD0); //·¢Ëíé豸μØÖ·+D′DÅoÅ,AD+W
I2C_Wait_Ack(); //μè′yé豸ó|′eDÅoÅ,ACK
I2C_Send(REG_Address); //·¢Ëí′æ′¢μ¥ÔaμØÖ·£¬′ó0¿aê¼,RA
I2C_Wait_Ack();//ACK
I2C_Start();//S
I2C_Send(0xD1); //·¢Ëíé豸μØÖ·+¶áDÅoÅ,AD+R
I2C_Wait_Ack();//ACK
*add=I2C_Receive(); //¶á3ö¼Ä′æÆ÷êy¾Y,DATA
for(i=0;i<13;i++)
{
I2C_Send_Ack();
*(add+i+1)=I2C_Receive(); //¶á3ö¼Ä′æÆ÷êy¾Y,DATA
}
I2C_Send_Nack(); //·¢Ëí·Çó|′eDÅoÅ,NACK
I2C_Stop(); //í£Ö1DÅoÅ,P
}
*/
void InitMPU6050(void)
{
I2C_Single_Write(PWR_MGMT_1, 0x00); //½a3yDYÃß×′ì¬
I2C_Single_Write(SMPLRT_DIV, 0x07);
I2C_Single_Write(CONFIG, 0x06);
// I2C_Single_Write(GYRO_CONFIG, 0x18);
// I2C_Single_Write(ACCEL_CONFIG, 0x01);
}
byte a;
void main(void) {
/* put your own code here */
DisableInterrupts;
PLL_init();
DDRB=0xFF;
PORTB=0xff;
I2C_Bus_init();
InitMPU6050();
PORTB=0x00;
EnableInterrupts;
for(;;) {
I2C_Single_Write(GYRO_CONFIG, 0x18);
I2C_Single_Write(ACCEL_CONFIG, 0x01);
// a=I2C_Single_Read(ACCEL_XOUT_L);
PORTB=~PORTB;
delay(20);
_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
部分内容已更改,现在说下情况:
数据线、时钟线没反应,示波器上也没波形,遇到很奇怪的现象,就是我把SCL和SDA换过后程序依然可以运行,我现在有点确定我的I2C时钟没发出去,不知道肿么办了,希望大神来帮帮小弟,小弟万分感激!
小弟用的芯片是自己焊的,用的是龙丘4.1版本的MC9S12XS128MAL的板子,焊的芯片是MC9S12XET256MAL,内带I2C模块,今天下午试了下,PWM没问题!用软件模拟也没问题,关键就是这个硬件I2C模块问题,真心纠结! |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|