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; //读出数据除以量程
}
}
后续就是自己的算法处理机判