关于ADXL加速度传感器SPI驱动问题

疯疯先生 2016-06-02 10:53:54
最近在用MSP430用4线SPI读取ADXL,时序写完了,用示波器看发送时ADXL的SDA时序也对,但是SDO始终保持低电平,无输出,导致读取的值一直为0。在网上查资料说4线SPI是ADXL默认的方式,不需要配置,也就是说开机上来就直接读一个寄存器,就会有结果,是这样吗。我把代码发上来看一下。
//下面是我的读取函数,因为不需要配置,试验的时候直接调用了这一个函数,写函数就不发了。
unsigned char ReadSpiAdxl(unsigned char Reg)
{
//unsigned char buffer = 0xC0|Reg;
unsigned char buffer = BIT7 | Reg;
ADXL_CS_1;
ADXL_SCL_1;
delay(30);
ADXL_CS_0;

delay(30);


for(unsigned char i=0;i<8;i++)
{
ADXL_SCL_0;
if(buffer & 0x80)
ADXL_SDO_1;
else
ADXL_SDO_0;
delay(300);
ADXL_SCL_1;
delay(300);
buffer <<= 1;
}

for(unsigned char j=0;j<8;j++)
{
buffer <<= 1;
ADXL_SCL_0;
delay(300);
ADXL_SCL_1;
if( ADXL_SDA )
buffer ++;
delay(300);
}

ADXL_CS_1;
return buffer;
}


//下面是主函数
main()
{
初始化IO引脚:SLK SCL CS 配置为输出,SDA配置为输入
其中,SCL =1,CS = 0
while(1)
ReadSpiAdxl(0x00);
}
...全文
808 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
limao_4 2016-10-07
  • 打赏
  • 举报
回复
直接用硬件的SPI驱动,很方便的。 深圳市巨兆数码股份有限公司,专业生产供应平衡车,滑板车等动力电池组,国产5C,三星,LG大量现货,UN38.3、CE、MSDS、等认证齐全,我们以高质量、低价格、灵活的账期以及优质的保障为您服务!欢迎来电咨询,138 7558 3520 李生
疯疯先生 2016-10-07
  • 打赏
  • 举报
回复
引用 4 楼 g62r83t27 的回复:
我这个代码测试过,ADXL345 你可以试试 头文件


#ifndef ADXL345_H_
#define ADXL345_H_

#define	 MOSI2_H	  (P3OUT |= BIT4)
#define	 MOSI2_L	  (P3OUT &= ~BIT4)
#define  SCK2_H	  	  (P4OUT |= BIT7)
#define  SCK2_L	  	  (P4OUT &= ~BIT7)
#define  CSN2_H	      (P3OUT |= BIT6)
#define  CSN2_L	      (P3OUT &= ~BIT6)
#define  MISO2_IN     P3IN
#define  MISO2        BIT5


#define	WRITE_BURST2  0x40	//连续写入
#define	READ_SINGLE2  0x80	//读
#define	READ_BURST2	  0xC0	//连续读

#define DEVICE_ID	  0xE5

#define ADDR_DEVID       			0x00    //固定器件ID代码
#define ADDR_THRESH_TAP  			0x1D    //敲击中断阈值
#define ADDR_OFSX			        0x1E    //X轴偏移调整
#define ADDR_OFSY        			0x1F    //Y轴偏移调整
#define ADDR_OFSZ        			0x20    //Z轴偏移调整
#define ADDR_DUR         			0x21    //敲击超过阀值的持续时间
#define ADDR_LATENT  			    0x22    //单击持续时间
#define ADDR_WINDOW      			0x23    //双击间隔最小时间
#define ADDR_THRESH_ACT  			0x24    //运动检测阈值
#define ADDR_THRESH_INACT			0x25    //静止检测阈值
#define ADDR_TIME_INACT  			0x26    //静止时间
#define ADDR_ACT_INACT_CTL 			0x27  	//轴使能活动和静止检测
#define ADDR_THRESH_FF			   	0x28    //自由落体阈值
#define ADDR_TIME_FF			    0x29    //自由落体时间
#define ADDR_TAP_AXES			    0x2A    //单击或双击轴控制
#define ADDR_ACT_TAP_STATUS			0x2B 	//单击或双击源
#define ADDR_BW_RATE			    0x2C    //数据速率与功率模式控制
#define ADDR_POWER_CTL				0x2D    //省电特性控制
#define ADDR_INT_ENABLE				0x2E    //中断使能控制
#define ADDR_INT_MAP			    0x2F    //中断映射控制
#define ADDR_INT_SOURCE				0x30    //中断源
#define ADDR_DATA_FORMAT			0x31    //数据格式控制
#define ADDR_DATAX0				    0x32    //X轴数据0
#define ADDR_DATAX1				    0x33    //X轴数据1
#define ADDR_DATAY0				    0x34    //Y轴数据0
#define ADDR_DATAY1				    0x35    //Y轴数据1
#define ADDR_DATAZ0				    0x36    //Z轴数据0
#define ADDR_DATAZ1				    0x37    //Z轴数据1
#define ADDR_FIFO_CTL			    0x38    //FIFO控制
#define ADDR_FIFO_STATUS			0x39    //FIFO状态


uint8 ADXL345_Init(void);
uint8 ADXL345_AMInit(void);
uint8 ADXL345_ReadChar(uint8 bAddr);
void ADXL345_WriteChar(uint8 bAddr, uint8 bValue);
void ADXL345_ReadString(uint8 bAddr, uint8 bp[], uint8 bCounter);
#endif /* ADXL345_H_ */
C文件


#include "../header/adxl345.h"
uint8 ADXL345_TxRxChar(uint8 bData)
{
    uint8 i,btn;
    btn = 0;
    for(i = 0; i < 8; i++)
    {
        if(bData & 0x80)
        {
            MOSI2_H;
        }
        else
        {
        	MOSI2_L;
        }
        SCK2_L;
        bData <<= 1;
        SCK2_H;
        btn <<= 1;
        if((MISO2_IN & MISO2)!= 0)
        {
        	btn |= 0x01;
        }
    }
    return btn;
}

uint8 ADXL345_TxRxChar2(uint8 bData)
{
    uint8 i,btn;

    btn = 0;
    SCK2_L;
    for(i = 0; i < 8; i++)
    {
        if(bData & 0x80)
        {
            MOSI2_H;
        }
        else
        {
        	MOSI2_L;
        }
        bData <<= 1;

        SCK2_H;

        __no_operation();
        __no_operation();

        btn <<= 1;
        if((MISO2_IN&MISO2)!=0)
        {
        	btn |= 0x01;
        }

        SCK2_L;
        __no_operation();
        __no_operation();
    }
    return btn;
}

uint8 ADXL345_ReadChar1(void)
{
	SCK2_L;

}

void ADXL345_WriteChar(uint8 bAddr, uint8 bValue)
{
	uint8 temp = 0;
	temp = bAddr & (~READ_SINGLE2);
    CSN2_L;
    ADXL345_TxRxChar(temp);		//写地址
    ADXL345_TxRxChar(bValue);		//写入配置
    CSN2_H;
}

uint8 ADXL345_ReadChar(uint8 bAddr)
{
	volatile uint8 temp = 0;
	volatile uint8 value = 0;
	temp = bAddr|READ_SINGLE2;//读寄存器命令
	CSN2_L;
	ADXL345_TxRxChar(temp);
	value = ADXL345_TxRxChar(0);
	CSN2_H;
	return value;
}

void ADXL345_ReadString(uint8 bAddr, uint8 bp[], uint8 bCounter)
{
    uint8 i, temp;
    temp = bAddr | READ_BURST2;
    CSN2_L;
    ADXL345_TxRxChar(temp);
    for (i = 0; i < bCounter; i++)
    {
    	bp[i] = ADXL345_TxRxChar(0);
    }
    CSN2_H;
}

//ADXL345初始化,返回1成功,返回0失败
uint8 ADXL345_Init(void)
{
    uint8 i = 0;
    i = ADXL345_ReadChar(ADDR_DEVID);
    if(DEVICE_ID == i)
    {
    	ADXL345_WriteChar(ADDR_DATA_FORMAT, 0x1B);//D6 = 0 4线SPI, D5 = 1,高电平中断,D3 = 1 13位精度,D2 = 0 LSB, D1= D0 = 1 +-16g
    	ADXL345_WriteChar(ADDR_BW_RATE, 0x07);    // D4 = 1低功耗模式,D3-D0 = 0x07,速率最小12.5Hz
    	//ADXL345_WriteChar(ADDR_OFSX, 0x00);
    	//ADXL345_WriteChar(ADDR_OFSY, 0x00);
    	//ADXL345_WriteChar(ADDR_OFSZ, 0x00);

    	ADXL345_WriteChar(ADDR_THRESH_ACT, 0x0f);    //活动阈值设定
    	ADXL345_WriteChar(ADDR_ACT_INACT_CTL, 0xC0);     //交流耦合检测,D7 =1 活动检测,D3 = 0 静止检测
    													 //D6 = 1 X轴活动使能, D5 = 1 Y轴活动使能,D4 = 0 Z轴活动使能
    													 //D2 = 0 X轴静止使能, D1 = 0 Y轴静止使能,D0 = 0 Z轴静止使能

    	ADXL345_WriteChar(ADDR_INT_MAP, 0x0);          //INT1捕获数据、活动、静止、自由落体中断
    	ADXL345_WriteChar(ADDR_INT_ENABLE, 0x10);      //加速度中断使能 , INT1引脚, 上升沿有效


    	ADXL345_WriteChar(ADDR_POWER_CTL,0x08);		//D3 = 0,休眠模式,
    	ADXL345_ReadChar(ADDR_INT_SOURCE);  		//清空器件的中断标志
    	ADXL345_ReadChar(ADDR_FIFO_STATUS);//
    	return 1;
    }
    else
    {
    	return 0;
    }
}

谢谢,才想起这个帖子,问题解决了,不是自己的代码问题,是买来的器件店家说有输出接了0欧姆的电阻,直接接地了,要去掉,太坑了。
侦探蜡笔小新 2016-06-07
  • 打赏
  • 举报
回复
我这个代码测试过,ADXL345 你可以试试 头文件


#ifndef ADXL345_H_
#define ADXL345_H_

#define	 MOSI2_H	  (P3OUT |= BIT4)
#define	 MOSI2_L	  (P3OUT &= ~BIT4)
#define  SCK2_H	  	  (P4OUT |= BIT7)
#define  SCK2_L	  	  (P4OUT &= ~BIT7)
#define  CSN2_H	      (P3OUT |= BIT6)
#define  CSN2_L	      (P3OUT &= ~BIT6)
#define  MISO2_IN     P3IN
#define  MISO2        BIT5


#define	WRITE_BURST2  0x40	//连续写入
#define	READ_SINGLE2  0x80	//读
#define	READ_BURST2	  0xC0	//连续读

#define DEVICE_ID	  0xE5

#define ADDR_DEVID       			0x00    //固定器件ID代码
#define ADDR_THRESH_TAP  			0x1D    //敲击中断阈值
#define ADDR_OFSX			        0x1E    //X轴偏移调整
#define ADDR_OFSY        			0x1F    //Y轴偏移调整
#define ADDR_OFSZ        			0x20    //Z轴偏移调整
#define ADDR_DUR         			0x21    //敲击超过阀值的持续时间
#define ADDR_LATENT  			    0x22    //单击持续时间
#define ADDR_WINDOW      			0x23    //双击间隔最小时间
#define ADDR_THRESH_ACT  			0x24    //运动检测阈值
#define ADDR_THRESH_INACT			0x25    //静止检测阈值
#define ADDR_TIME_INACT  			0x26    //静止时间
#define ADDR_ACT_INACT_CTL 			0x27  	//轴使能活动和静止检测
#define ADDR_THRESH_FF			   	0x28    //自由落体阈值
#define ADDR_TIME_FF			    0x29    //自由落体时间
#define ADDR_TAP_AXES			    0x2A    //单击或双击轴控制
#define ADDR_ACT_TAP_STATUS			0x2B 	//单击或双击源
#define ADDR_BW_RATE			    0x2C    //数据速率与功率模式控制
#define ADDR_POWER_CTL				0x2D    //省电特性控制
#define ADDR_INT_ENABLE				0x2E    //中断使能控制
#define ADDR_INT_MAP			    0x2F    //中断映射控制
#define ADDR_INT_SOURCE				0x30    //中断源
#define ADDR_DATA_FORMAT			0x31    //数据格式控制
#define ADDR_DATAX0				    0x32    //X轴数据0
#define ADDR_DATAX1				    0x33    //X轴数据1
#define ADDR_DATAY0				    0x34    //Y轴数据0
#define ADDR_DATAY1				    0x35    //Y轴数据1
#define ADDR_DATAZ0				    0x36    //Z轴数据0
#define ADDR_DATAZ1				    0x37    //Z轴数据1
#define ADDR_FIFO_CTL			    0x38    //FIFO控制
#define ADDR_FIFO_STATUS			0x39    //FIFO状态


uint8 ADXL345_Init(void);
uint8 ADXL345_AMInit(void);
uint8 ADXL345_ReadChar(uint8 bAddr);
void ADXL345_WriteChar(uint8 bAddr, uint8 bValue);
void ADXL345_ReadString(uint8 bAddr, uint8 bp[], uint8 bCounter);
#endif /* ADXL345_H_ */
C文件


#include "../header/adxl345.h"
uint8 ADXL345_TxRxChar(uint8 bData)
{
    uint8 i,btn;
    btn = 0;
    for(i = 0; i < 8; i++)
    {
        if(bData & 0x80)
        {
            MOSI2_H;
        }
        else
        {
        	MOSI2_L;
        }
        SCK2_L;
        bData <<= 1;
        SCK2_H;
        btn <<= 1;
        if((MISO2_IN & MISO2)!= 0)
        {
        	btn |= 0x01;
        }
    }
    return btn;
}

uint8 ADXL345_TxRxChar2(uint8 bData)
{
    uint8 i,btn;

    btn = 0;
    SCK2_L;
    for(i = 0; i < 8; i++)
    {
        if(bData & 0x80)
        {
            MOSI2_H;
        }
        else
        {
        	MOSI2_L;
        }
        bData <<= 1;

        SCK2_H;

        __no_operation();
        __no_operation();

        btn <<= 1;
        if((MISO2_IN&MISO2)!=0)
        {
        	btn |= 0x01;
        }

        SCK2_L;
        __no_operation();
        __no_operation();
    }
    return btn;
}

uint8 ADXL345_ReadChar1(void)
{
	SCK2_L;

}

void ADXL345_WriteChar(uint8 bAddr, uint8 bValue)
{
	uint8 temp = 0;
	temp = bAddr & (~READ_SINGLE2);
    CSN2_L;
    ADXL345_TxRxChar(temp);		//写地址
    ADXL345_TxRxChar(bValue);		//写入配置
    CSN2_H;
}

uint8 ADXL345_ReadChar(uint8 bAddr)
{
	volatile uint8 temp = 0;
	volatile uint8 value = 0;
	temp = bAddr|READ_SINGLE2;//读寄存器命令
	CSN2_L;
	ADXL345_TxRxChar(temp);
	value = ADXL345_TxRxChar(0);
	CSN2_H;
	return value;
}

void ADXL345_ReadString(uint8 bAddr, uint8 bp[], uint8 bCounter)
{
    uint8 i, temp;
    temp = bAddr | READ_BURST2;
    CSN2_L;
    ADXL345_TxRxChar(temp);
    for (i = 0; i < bCounter; i++)
    {
    	bp[i] = ADXL345_TxRxChar(0);
    }
    CSN2_H;
}

//ADXL345初始化,返回1成功,返回0失败
uint8 ADXL345_Init(void)
{
    uint8 i = 0;
    i = ADXL345_ReadChar(ADDR_DEVID);
    if(DEVICE_ID == i)
    {
    	ADXL345_WriteChar(ADDR_DATA_FORMAT, 0x1B);//D6 = 0 4线SPI, D5 = 1,高电平中断,D3 = 1 13位精度,D2 = 0 LSB, D1= D0 = 1 +-16g
    	ADXL345_WriteChar(ADDR_BW_RATE, 0x07);    // D4 = 1低功耗模式,D3-D0 = 0x07,速率最小12.5Hz
    	//ADXL345_WriteChar(ADDR_OFSX, 0x00);
    	//ADXL345_WriteChar(ADDR_OFSY, 0x00);
    	//ADXL345_WriteChar(ADDR_OFSZ, 0x00);

    	ADXL345_WriteChar(ADDR_THRESH_ACT, 0x0f);    //活动阈值设定
    	ADXL345_WriteChar(ADDR_ACT_INACT_CTL, 0xC0);     //交流耦合检测,D7 =1 活动检测,D3 = 0 静止检测
    													 //D6 = 1 X轴活动使能, D5 = 1 Y轴活动使能,D4 = 0 Z轴活动使能
    													 //D2 = 0 X轴静止使能, D1 = 0 Y轴静止使能,D0 = 0 Z轴静止使能

    	ADXL345_WriteChar(ADDR_INT_MAP, 0x0);          //INT1捕获数据、活动、静止、自由落体中断
    	ADXL345_WriteChar(ADDR_INT_ENABLE, 0x10);      //加速度中断使能 , INT1引脚, 上升沿有效


    	ADXL345_WriteChar(ADDR_POWER_CTL,0x08);		//D3 = 0,休眠模式,
    	ADXL345_ReadChar(ADDR_INT_SOURCE);  		//清空器件的中断标志
    	ADXL345_ReadChar(ADDR_FIFO_STATUS);//
    	return 1;
    }
    else
    {
    	return 0;
    }
}

worldy 2016-06-02
  • 打赏
  • 举报
回复
SPI DO脚是输出,由器件寄存器内容决定,DI输入脚,由控制器决定 在时钟SCK驱动下,器件内容从DO输出,同时,传人的内容由DI读入,DO和DI没有直接的联系
疯疯先生 2016-06-02
  • 打赏
  • 举报
回复
引用 1 楼 shinerise 的回复:
好像ADXL345的硬件需要接成SPI模式,芯片才按SPI方式工作。好久了,不太记得了。
它有SPI接口啊,而且我买的是ADXL的模块,专门有SPI接口,目前有 CS SCL SDO SDA VCC GND 我只接了这几个口,另外还有IN1 IN2 两个中断口我没接 VS 什么数字电源我也没接,不知道这样对吗。
shinerise 2016-06-02
  • 打赏
  • 举报
回复
好像ADXL345的硬件需要接成SPI模式,芯片才按SPI方式工作。好久了,不太记得了。

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧