1.初始化L3GD20端口配置。将端口配置为SPI通信接口。
单片机端口初始化包括I/O端口,I/O端口spi系统时钟。
以STM32F303为例配置端口如下:
static void L3GD20_LowLevel_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef
SPI_InitStructure;
RCC_APB2PeriphClockCmd(L3GD20_SPI_CLK,
ENABLE);
RCC_AHBPeriphClockCmd(L3GD20_SPI_SCK_GPIO_CLK |
L3GD20_SPI_MISO_GPIO_CLK | L3GD20_SPI_MOSI_GPIO_CLK, ENABLE);
RCC_AHBPeriphClockCmd(L3GD20_SPI_CS_GPIO_CLK, ENABLE);
RCC_AHBPeriphClockCmd(L3GD20_SPI_INT1_GPIO_CLK, ENABLE);
RCC_AHBPeriphClockCmd(L3GD20_SPI_INT2_GPIO_CLK, ENABLE);
GPIO_PinAFConfig(L3GD20_SPI_SCK_GPIO_PORT,
L3GD20_SPI_SCK_SOURCE, L3GD20_SPI_SCK_AF);
GPIO_PinAFConfig(L3GD20_SPI_MISO_GPIO_PORT,
L3GD20_SPI_MISO_SOURCE, L3GD20_SPI_MISO_AF);
GPIO_PinAFConfig(L3GD20_SPI_MOSI_GPIO_PORT,
L3GD20_SPI_MOSI_SOURCE, L3GD20_SPI_MOSI_AF);
GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType =
GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd
= GPIO_PuPd_NOPULL;//GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin =
L3GD20_SPI_SCK_PIN;
GPIO_Init(L3GD20_SPI_SCK_GPIO_PORT,
&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =
L3GD20_SPI_MOSI_PIN;
GPIO_Init(L3GD20_SPI_MOSI_GPIO_PORT,
&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =
L3GD20_SPI_MISO_PIN;
GPIO_Init(L3GD20_SPI_MISO_GPIO_PORT,
&GPIO_InitStructure);
SPI_I2S_DeInit(L3GD20_SPI);
SPI_InitStructure.SPI_Direction =
SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize =
SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL =
SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA =
SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS =
SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler =
SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit =
SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial =
7;
SPI_InitStructure.SPI_Mode =
SPI_Mode_Master;
SPI_Init(L3GD20_SPI,
&SPI_InitStructure);
SPI_RxFIFOThresholdConfig(L3GD20_SPI,
SPI_RxFIFOThreshold_QF);
SPI_Cmd(L3GD20_SPI, ENABLE);
GPIO_InitStructure.GPIO_Pin =
L3GD20_SPI_CS_PIN;
GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType =
GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_50MHz;
GPIO_Init(L3GD20_SPI_CS_GPIO_PORT,
&GPIO_InitStructure);
GPIO_SetBits(L3GD20_SPI_CS_GPIO_PORT,
L3GD20_SPI_CS_PIN);
GPIO_InitStructure.GPIO_Pin =
L3GD20_SPI_INT1_PIN;
GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType =
GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd
= GPIO_PuPd_NOPULL;
GPIO_Init(L3GD20_SPI_INT1_GPIO_PORT,
&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =
L3GD20_SPI_INT2_PIN;
GPIO_Init(L3GD20_SPI_INT2_GPIO_PORT,
&GPIO_InitStructure);
}
2.陀螺仪初始化配置
配置陀螺仪芯片功能和芯片初始化设置
对应寄存器配置及功能参考LG3D20数据手册
代码示例如下:
void L3GD20_Init(L3GD20_InitTypeDef
*L3GD20_InitStruct)
{
uint8_t ctrl1 = 0x00, ctrl4 = 0x00;
L3GD20_LowLevel_Init();
L3GD20_InitStructure.Power_Mode =
L3GD20_MODE_ACTIVE; //配置值0x08
L3GD20_InitStructure.Output_DataRate =
L3GD20_OUTPUT_DATARATE_1; //配置值0x00
L3GD20_InitStructure.Axes_Enable =
L3GD20_AXES_ENABLE; //配置值0x07
L3GD20_InitStructure.Band_Width =
L3GD20_BANDWIDTH_4; //配置值0x30
L3GD20_InitStructure.BlockData_Update =
L3GD20_BlockDataUpdate_Continous; //配置值0x00
L3GD20_InitStructure.Endianness =
L3GD20_BLE_LSB; //配置值0x00
L3GD20_InitStructure.Full_Scale =
L3GD20_FULLSCALE_500; //配置值0x10
ctrl1 |= (uint8_t)
(L3GD20_InitStruct->Power_Mode |
L3GD20_InitStruct->Output_DataRate | \
L3GD20_InitStruct->Axes_Enable |
L3GD20_InitStruct->Band_Width);
ctrl4 |= (uint8_t)
(L3GD20_InitStruct->BlockData_Update |
L3GD20_InitStruct->Endianness | \
L3GD20_InitStruct->Full_Scale);
L3GD20_Write(&ctrl1,
L3GD20_CTRL_REG1_ADDR, 1);
L3GD20_Write(&ctrl4,
L3GD20_CTRL_REG4_ADDR, 1);
}
void
L3GD20_FilterConfig(L3GD20_FilterConfigTypeDef
*L3GD20_FilterStruct)
{
uint8_t tmpreg;
L3GD20_Read(&tmpreg,
L3GD20_CTRL_REG2_ADDR, 1);
tmpreg &= 0xC0;
L3GD20_FilterStructure.HighPassFilter_Mode_Selection
=L3GD20_HPM_NORMAL_MODE_RES; //配置值0x00
L3GD20_FilterStructure.HighPassFilter_CutOff_Frequency =
L3GD20_HPFCF_0; //配置值0x00
tmpreg |= (uint8_t)
(L3GD20_FilterStruct->HighPassFilter_Mode_Selection |\
L3GD20_FilterStruct->HighPassFilter_CutOff_Frequency);
L3GD20_Write(&tmpreg,
L3GD20_CTRL_REG2_ADDR, 1);
}
void L3GD20_FilterCmd(uint8_t HighPassFilterState)
{
uint8_t tmpreg;
L3GD20_Read(&tmpreg,
L3GD20_CTRL_REG5_ADDR, 1);
tmpreg &= 0xEF;
tmpreg |= HighPassFilterState;
//配置值0x10
L3GD20_Write(&tmpreg,
L3GD20_CTRL_REG5_ADDR, 1);
}
3.L3GD20配置SPI数据读、写寄存器函数
读取函数L3GD20_Read(uint8_t*
pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
void L3GD20_Read(uint8_t* pBuffer, uint8_t
ReadAddr, uint16_t NumByteToRead)
{
if(NumByteToRead > 0x01)
{
ReadAddr |=
(uint8_t)(READWRITE_CMD | MULTIPLEBYTE_CMD);
}
else
{
ReadAddr |=
(uint8_t)READWRITE_CMD;
}
L3GD20_CS_LOW();
L3GD20_SendByte(ReadAddr);
while(NumByteToRead > 0x00)
{
*pBuffer =
L3GD20_SendByte(DUMMY_BYTE);
NumByteToRead--;
pBuffer++;
}
L3GD20_CS_HIGH();
}
写L3GD20寄存器函数L3GD20_Write(uint8_t* pBuffer,
uint8_t WriteAddr, uint16_t NumByteToWrite)
void
L3GD20_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t
NumByteToWrite)
{
if(NumByteToWrite > 0x01)
{
WriteAddr |=
(uint8_t)MULTIPLEBYTE_CMD;
}
L3GD20_CS_LOW();
L3GD20_SendByte(WriteAddr);
while(NumByteToWrite >= 0x01)
{
L3GD20_SendByte(*pBuffer);
NumByteToWrite--;
pBuffer++;
}
L3GD20_CS_HIGH();
}
4.封装读取陀螺仪3轴数据函数
将读取出来的数据进行处理计算
Demo_GyroReadAngRate (float* pfData)
void Demo_GyroReadAngRate (float* pfData)
{
uint8_t tmpbuffer[6] ={0};
int16_t RawData[3] = {0};
uint8_t tmpreg = 0;
float sensitivity = 0;
int i =0;
L3GD20_Read(&tmpreg,L3GD20_CTRL_REG4_ADDR,1);
L3GD20_Read(tmpbuffer,L3GD20_OUT_X_L_ADDR,6);
if(!(tmpreg & 0x40))
{
for(i=0; i<3;
i++)
{
RawData[i]=(int16_t)(((uint16_t)tmpbuffer[2*i+1] << 8) +
tmpbuffer[2*i]);
}
}
else
{
for(i=0; i<3;
i++)
{
RawData[i]=(int16_t)(((uint16_t)tmpbuffer[2*i] << 8) +
tmpbuffer[2*i+1]);
}
}
switch(tmpreg & 0x30)
{
case 0x00:
sensitivity=L3G_Sensitivity_250dps;//L3G_Sensitivity_500dps=360/pi
break;
case 0x10:
sensitivity=L3G_Sensitivity_500dps;
//L3G_Sensitivity_500dps=180/pi=57.1429
break;
case 0x20:
sensitivity=L3G_Sensitivity_2000dps;//L3G_Sensitivity_500dps=1/4*180/pi
break;
}
for(i=0; i<3; i++)
{
pfData[i]=(float)RawData[i]/sensitivity; //读出数据除以量程
}
}
后续就是自己的算法处理机判断。