ADXL345调试心得

这几天测试了ADXL345,记录一下

1、关于初始化

         一般初始化0x31、0x2d、0x2c、0x2e、0x38就行了,它们分别是设置量程、工作模式、数据速率、中断及FIFO。

2、关于灵敏度。手册上写灵敏度a=256LSB/g,这是在2.5V时测的。在文档的某个角落里写了,3.3V供电时,灵敏度a=265LSB/g。

         另外,3.3V供电比2.5V时噪声要小。

3、注意SPI的时钟。输出数据1600或3200时,要大于等于2M;

         输出数据为800Hz时,要大于等于400kHz。

         SPI时钟最大5M。        

        SPI时钟配置不对会读不到数据或丢数。有次把SPI的时钟配的太快了,读的全是0XFFFF。

4、量程:本来想用正负2g的量程,这档量程在20mm/s时超过2g了。所以选择了正负16g。

而且实测下来这两个量程,在全分辨率模式下,没看出什么差别来。

5、带宽:带宽=数据输出速率/2。

         也就是说数据速率1600Hz时,带宽是800Hz

6、分辨率怎么算出来的?

         以正负16g,10分辨率为例,手册上写分辨率是32mg/LSB

         16*2/210=0.0312g/LSB

7、有次测试时,每秒读1000个数据,但是发现每10个连续的数据都是相同的,最后发现数据输出速率没有初始化,用的默认的100Hz

8、关于偏移值

         这个最坑了,搞了两天才反应过来。以前在网上找的例程初始化后,都要计算这个偏移值。但是我算完偏移值后,读到的数据老是有255或-250这样的数据。

         以为是数据合并的问题,或者是SPI时序不对,总线错误什么的。

         后来发现我的应用不需要计算偏移值。这个在计算倾角什么的,必须要先算一下偏移值。我可以不计算这个初始的偏移值,把它当成是一个直流量;我需要的是相对这个偏移值的变化量,用算法处理一下,就搞定了。

         最终把计算偏移值的代码去掉,读到的值就都恢复正常了。


下面是我的ADXL345初始化代码。用的SPI。

void SPI_init(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;
    SPI_InitTypeDef         SPI_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	
    GPIO_InitStructure.GPIO_Pin = ADXL345_SPI_CS_PIN ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = ADXL345_SPI_SCK_PIN | ADXL345_SPI_MISO_PIN | ADXL345_SPI_MOSI_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    ADXL345_CS_HIGH();	

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High ;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(ADXL345_SPI, &SPI_InitStructure); 
    SPI_Cmd(ADXL345_SPI,ENABLE);  
}

u8 ADXL345_read_byte(u8 add)
{
	u8 val;
	
    ADXL345_CS_LOW();
 
    while (SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_TXE) == RESET);	
	SPI_I2S_SendData(ADXL345_SPI, (add | 0x80) << 8);
   
    while (SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_RXNE) == RESET);  
    val = (SPI_I2S_ReceiveData(ADXL345_SPI) & 0xff); 
	
	ADXL345_CS_HIGH();
	
	return val;
}


void ADXL345_write_byte(u8 add,u8 val)
{
    ADXL345_CS_LOW();
 
    while (SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_TXE) == RESET);	
	SPI_I2S_SendData(ADXL345_SPI, add << 8 | val);
   
    while (SPI_I2S_GetFlagStatus(ADXL345_SPI, SPI_I2S_FLAG_RXNE)==RESET);    
    SPI_I2S_ReceiveData(ADXL345_SPI);
	
	ADXL345_CS_HIGH();
}
int main(void)
{
	if(ADXL345_read_byte(REG_DEVID) == DEVICEID)
	{
		ADXL345_write_byte(0x31,0X0b);	//16g
		ADXL345_write_byte(0x2D,0x08); //powerctrl 
		ADXL345_write_byte(0x2C,0x0e);	//1600
		ADXL345_write_byte(0x2E,0x00);  
		ADXL345_write_byte(0x38,0x00); 
		ADXL345_write_byte(0x2F,0x00);
		yanchi(1000);	
	}	
	//ADXL345_AUTO_Adjust();
	InitHardTimer();
	while (1)
	{}
}

你可能感兴趣的:(STM32,硬件相关)