#include <stm32f10x.h>
#include <stdbool.h>
#include "IIC.h"
#include "math.h"
#include "usart1.h"
//STM32F103RCT6
/**
******************************************************************************
* @file bsp_i2c_ad.c
* @author STMicroelectronics
******************************************************************************
******************************************************************************
*/
//int16_t ADXL345_rxdata[3];
ADXL345_DATA new_adxl345_data;
Recent_Measure_Angle recent_adxl345_data;
/**
* @brief I2C1 I/O配置
* @param 无
* @retval 无
*/
void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能与 I2C1 有关的时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
///* PB6-I2C1_SCL、PB7-I2C1_SDA*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
uint8_t reset_no;
void reset_iic_init()
{
I2C_DeInit(I2C1);//RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,DISABLE);
__nop();
__nop();
__nop();
__nop();
I2C_GPIO_Config();
I2C_Mode_Configu();
__nop();
__nop();
__nop();
__nop();
reset_no++;
}
/**
* @brief I2C 工作模式配置
* @param 无
* @retval 无
*/
void I2C_Mode_Configu(void)
{
I2C_InitTypeDef I2C_InitStructure;
I2C_GPIO_Config();
/* 通信速率 */
I2C_InitStructure.I2C_ClockSpeed = 10000;
/* I2C 配置 */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
/* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 =0; //从模式下单片机IIC自己的地址
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
/* I2C的寻址模式 */
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
/* I2C1 初始化 */
I2C_Init(I2C1, &I2C_InitStructure);
/* 使能 I2C1 */
I2C_Cmd(I2C1, ENABLE);
}
#define SLAVE_ADXL345_ADDRESS (0x53<<1) //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改
uint8_t Write_ADXL345(uint8_t Slave_Addr,uint8_t REG_Address,uint8_t data)
{
//ADXL345_Start(); //起始信号
uint32_t i=0;
I2C_GenerateSTART(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)==0)//读取SR1
{
if(i++>10000)
{
return 0 ;
}
__nop();
__nop();
}
I2C_Send7bitAddress(I2C1, Slave_Addr , I2C_Direction_Transmitter);
i=0;
i=0;
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))//
{
if(i++>10000)
{
return 0 ;
}
__nop();
__nop();
}
//ADXL345_SendByte(REG_Address); //内部寄存器地址,请参考中文pdf22页
I2C_SendData(I2C1, REG_Address);
i=0;
while((I2C_GetFlagStatus(I2C1,I2C_FLAG_TXE)==0))
{
if(i++>10000)
return 0;
__nop();
__nop();
}
//ADXL345_SendByte(REG_data); //内部寄存器数据,请参考中文pdf22页
I2C_SendData(I2C1, data);
i=0;
while((I2C_GetFlagStatus(I2C1,I2C_FLAG_TXE)==0))
{
if(i++>10000)
return 0;
__nop();
__nop();
}
//ADXL345_Stop(); //发送停止信号
I2C_GenerateSTOP(I2C1, ENABLE);
return 1;
}
bool Single_Read_ADXL345(uint8_t REG_Address ,uint8_t *data)
{ //uint8_t REG_data;
uint32_t i=0;
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY))
{
if(i++>10000)
{
return 0;
}
__nop();
__nop();
}
//ADXL345_Start(); //起始信号
I2C_GenerateSTART(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)==0)//读取SR1
{
if(i++>10000)
{
return 0 ;
}
__nop();
__nop();
}
//ADXL345_SendByte(SlaveAddress); //发送设备地址+读信号
I2C_Send7bitAddress(I2C1, SLAVE_ADXL345_ADDRESS , I2C_Direction_Transmitter);
i=0;
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))//
{
if(i++>10000)
{
return 0;
}
__nop();
__nop();
}
//ADXL345_SendByte(REG_Address); //发送存储单元地址,从0开始
I2C_SendData(I2C1, REG_Address);
i=0;
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
if(i++>10000)
{
return 0;
}
__nop();
__nop();
}
//ADXL345_Start(); //重新设置起始信号
I2C_GenerateSTART(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)==0)//读取SR1
{
}
i=0;
//ADXL345_SendByte(SlaveAddress+1); //发送设备地址+读信号
I2C_Send7bitAddress(I2C1, SLAVE_ADXL345_ADDRESS , I2C_Direction_Receiver);
i=0;
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if(i++>10000)
{
return 0;
}
__nop();
__nop();
}
I2C_AcknowledgeConfig(I2C1,DISABLE);
//ADXL345_Stop(); //停止信号
I2C_GenerateSTOP(I2C1, ENABLE);
i=0;
while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)))
{
if(i++>10000)
{
return 0;
}
__nop();
__nop();
}
//REG_data=ADXL345_RecvByte(); //读出寄存器数据
*data=I2C_ReceiveData(I2C1);
return 1;
}
bool Multiple_read_ADXL345(int16_t *read_xyz)
{
int16_t outdata;
uint32_t i=0,j=0;
uint8_t xyzdata[6];
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY))
{
if(i++>10000)
{
return 0 ;
}
__nop();
__nop();
}
I2C_GenerateSTART(I2C1, ENABLE);
//
// while (I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)==0)//读取SR1
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))//
{
if(i++>10000)
{
return 0 ;
}
__nop();
__nop();
__nop();
__nop();
}
I2C_Send7bitAddress(I2C1, SLAVE_ADXL345_ADDRESS , I2C_Direction_Transmitter);
i=0;
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))//
{
if(i++>10000)
{
return 0 ;
}
__nop();
__nop();
__nop();
__nop();
}
I2C_SendData(I2C1, 0x32);
i=0;
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
if(i++>10000)
{
return 0 ;
}
__nop();
__nop();
__nop();
__nop();
}
I2C_GenerateSTART(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)==0)//读取SR1
{
}
I2C_Send7bitAddress(I2C1, SLAVE_ADXL345_ADDRESS , I2C_Direction_Receiver);
i=0;
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if(i++>10000)
{
return 0 ;
}
__nop();
__nop();
}
I2C_AcknowledgeConfig(I2C1, ENABLE);
for (j=0; j<6; j++) //连续读取6个地址数据,存储中BUF
{
i=0;
while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)))
{
if(i++>10000)
{
return 0 ;
}
__nop();
__nop();
}
xyzdata[j] = I2C_ReceiveData(I2C1); //BUF[0]存储0x32地址中的数据
//data++;
if (j == 4)
{
//ADXL345_SendACK(1); //最后一个数据需要回NOACK
I2C_AcknowledgeConfig(I2C1, DISABLE);
//ADXL345_Stop();
I2C_GenerateSTOP(I2C1, ENABLE);////停止信号在倒数第二个数据的时候申请
}
}
for(j=0;j<3;j++)
{
uint8_t i;
// uint16_t sysmbol;
uint16_t xyz_reg;
i=j*2;
outdata=0;
xyz_reg=xyzdata[i+1];
xyz_reg<<=8;
xyz_reg+=xyzdata[i];
//13位下高4位是符号位(12bit的有效数据D[11:0] 符号位D[15:12])
outdata=xyz_reg;
*read_xyz=outdata;//自测寄存器0x31 测量范围,正负16g 全分辨率13位模式32000mg/0x1fff=32000mg/8192=3.90625mg/Lsb 左对齐
//*read_xyz=(int32_t)outdata*39/10;//自测寄存器0x31 测量范围,正负16g 全分辨率13位模式32000mg/0x1fff=32000mg/8192=3.90625mg/Lsb 左对齐
read_xyz++;
}
return 1;
//Delay5ms();
}
int16_t Roll,Pitch,zz;
float Xmg ,Ymg ,Zmg;
int16_t X1angle,Y1angle,Z1angle;
//
uint32_t Gmg;
void calculate_angle(int16_t ADXL345_X_Reg,int16_t ADXL345_Y_Reg,int16_t ADXL345_Z_Reg)//(int16_t ADXL345_rxdata[],int16_t *Xangle,int16_t *Yangle,int16_t *Zangle)
{
//float Q,T,K;
float m;
uint32_t i;
//ADXL345_DATA p;
Xmg=(float)ADXL345_X_Reg*3.9;//分别是加速度X,Y,Z的原始数据 +_16g 全分辨率 13位 则32000/8192=3.90625
Ymg=Ymg=(float)ADXL345_Y_Reg*3.9;//*3.9;
Zmg=Zmg=(float)ADXL345_Z_Reg*3.9;//*3.9;
Gmg= Xmg * Xmg +
Ymg * Ymg +
Zmg * Zmg;
Gmg=(sqrt(Gmg));
if(Gmg>2000 || Gmg<500)
return;
//Roll=(float)(((atan2(K,Q)*180)/3.1416)-90); //X轴角度值
//Pitch=(float)(((atan2(K,T)*180)/3.1416)-90); //Y轴角度值
//zz=(float)((atan2(Q,K)*180)/3.1416); //Z轴角度值
m=sqrt(Ymg*Ymg+Zmg*Zmg);
X1angle=atan(Xmg/m)*180/3.1415926;
//X1angle=new_adxl345_data->Xangle;
//Xangle=atan2(Xmg,m)*180/3.1415926;
m=sqrt(Xmg*Xmg+Zmg*Zmg);
// Yangle=atan2(Ymg,m)*180/3.1415926;
Y1angle=atan(Ymg/m)*180/3.1415926;
//Y1angle=new_adxl345_data->Yangle;
m=sqrt(Xmg*Xmg+Ymg*Ymg);
// Zangle=atan2(Zmg,m)*180/3.1415926;
Z1angle=atan(m/Zmg)*180/3.1415926;
//Z1angle=new_adxl345_data->Zangle;
i=recent_adxl345_data.write;
recent_adxl345_data.struct_recent_adxl345[i].x_angle=X1angle;
recent_adxl345_data.struct_recent_adxl345[i].y_angle=Y1angle;
recent_adxl345_data.struct_recent_adxl345[i].z_angle=Z1angle;
recent_adxl345_data.write++;
if(recent_adxl345_data.write>=RECENT_ADXL345_BUFF_LEN)
recent_adxl345_data.write=0;
if(recent_adxl345_data.num<RECENT_ADXL345_BUFF_LEN)
recent_adxl345_data.num++;
//recent_adxl345_data.
}
void Init_ADXL345()
{
Write_ADXL345(SLAVE_ADXL345_ADDRESS,0x31,0x0B);//自测寄存器0x31 测量范围,正负16g 全分辨率13位模式32000mg/0x1fff=32000mg/8192=3.90625mg/Lsb 左对齐
Write_ADXL345(SLAVE_ADXL345_ADDRESS,0x2C,0x0A);//速率寄存器0x2C 速率设定为100HZ 参考pdf24页
Write_ADXL345(SLAVE_ADXL345_ADDRESS,0x2D,0x08);// PWR_CTL 寄存器 置于测量模式 参考pdf24页
Write_ADXL345(SLAVE_ADXL345_ADDRESS,0x2E,0x00);//中断使能 中断
Write_ADXL345(SLAVE_ADXL345_ADDRESS,0x1E,0x00);//X 偏移量 根据测试传感器的状态写入pdf29页
Write_ADXL345(SLAVE_ADXL345_ADDRESS,0x1F,0x00);//Y 偏移量 根据测试传感器的状态写入pdf29页
Write_ADXL345(SLAVE_ADXL345_ADDRESS,0x20,0x00);//Z 偏移量 根据测试传感器的状态写入pdf29页
Write_ADXL345(SLAVE_ADXL345_ADDRESS,0x21,0x00); //
}