cxieyunsky
xieyunsky_
采纳率100%
2019-08-06 18:32 阅读 1.4k

关于lis3dh使用的问题

最近用lis3dh开发东西,和NRF24LE1之间进行SPI通信。用的是SPI三线模式。需要配置为LIS3DH产生INT1中断给NRF24LE1来激活NRF24LE1进入工作模式。但是无论怎么样都把LIS3DH的寄存器配置不好,用示波器能看到MOSI和SCK有电平输出,但是永远都不能从LIS3DH的寄存器中读到数据。现在都不知道数据到底有没有能够通过SPI写入到LIS3DH的寄存器里面。求大佬给点提示,要怎么弄。
CS片选信号已由硬件一直拉低。SPI是三线模拟SPI。
图片说明

图片中黄线是时钟线,绿线是数据线。前8位是要写入的寄存器地址0x0f(第一位置高表示要从该寄存器中读值),后8位是该寄存器中的数据(读不出来,一直为0)。

这是配置寄存器部分

```void lis3dh_init(void){

spi_init();

LIS3DH_WriteReg(LIS3DH_CTRL_REG4, 0x09);  //设置量程为2g,三线接口
delay1us(100);

LIS3DH_WriteReg(LIS3DH_CTRL_REG1, 0x57);  //100Hz 正常模式 使能ZYX
delay1us(100);

LIS3DH_WriteReg(LIS3DH_CTRL_REG2, 0x39); //启用INT1高通滤波
delay1us(100);

LIS3DH_WriteReg(LIS3DH_CTRL_REG3, 0x40);  // INT1引脚上的中断发生器 1
delay1us(100);

LIS3DH_WriteReg(LIS3DH_CTRL_REG5, 0x08);  //锁存中断请求
delay1us(100);

LIS3DH_WriteReg(LIS3DH_INT1_CFG, 0xaa);  //中断源  zyx低
delay1us(100);

LIS3DH_WriteReg(LIS3DH_INT1_THS, 0x02);  //设置中断1阈值
delay1us(100);

LIS3DH_WriteReg(LIS3DH_INT1_DURATION, 0);  //中断持续时间
delay1us(100);

LIS3DH_ReadReference();

}

这是读取和写入SPI

void SPISendByte(u8 ch)
{
  u8 i;

    P1DIR  &= 0xEF;                //p1.4为输出
    delay1us(5);
  SCK = 1 ;                      //时钟置高
  for(i = 0; i < 8; i++)
  {
        SCK = 0 ;                    //时钟置低
    if(ch & 0x80){               //判断最高位,总是发送最高位
            MOSI = 1;                  //MOSI输出1,数据总线准备数据1
        }
    else{
            MOSI = 0;                  //MOSI输出0,数据总线准备数据0
        }
        delay1us(5);
        SCK = 1;                     //上升沿来了(SCK从0-->1),数据总线上的数据写入到器件       
        delay1us(5);
    ch <<= 1;                    //左移抛弃已经输出的最高位
  }
}
/******************************************************************
**name      : SPIreceiveByte
**fun       : 接收一字节数据
**arguments : void
**return    : 接收的数据
**date      : 2019/7/23
**by        : @曼珠沙华
*******************************************************************/
u8 SPI_Read_OneByte(void)
{
  u8 i;
  u8 temp = 0;

    MOSI = 0;
    delay1us(5);
    P1DIR |= 0x10;               //p1.4设为输入
    delay1us(5);
  SCK = 1;                     //时钟置高
  for(i = 0; i < 8; i++){
        temp <<= 1;                //读取MISO 8次输入的值,存入temp。之所以不放在“SCK = 0”语句之后的位置是因为:
                                                 //读取最后1byte的最后一位(即LSB)之后,不能再左移了  
        SCK = 0;                   //时钟为低
        if(MOSI){                  //读取最高位,保存至最末尾,通过左移位完成读整个字节
            temp |= 0x01;
        }
        else{
            temp &= ~0x01;
        }
        delay1us(5);
        SCK = 1;                   //上升沿来了(SCK从0-->1),MOSI上的数据将发生改变,稳定后读取存入temp
        delay1us(5);
  }

  return temp;
}

主函数部分:

void main(void){

    u8 i,m1 = 0xCC;
    int lisid=0;
  u8 lisidtemp=0;

    GPIO_Init();             //初始化GPIO
    RF_init();               //初始化RF
    uart0_init(38400);       //初始化串口 设置波特率为38400
    delay1ms(2000);          //等待稳定
    lis3dh_init();           //初始化运动传感器

    EA = 1;                  //允许中断

    /*上电闪灯5次*/
    for(i = 0; i < 5; i++){
        LED = 1;
        delay1ms(500);
        LED = 0;
        delay1ms(500);
    }

    while(1){
        LIS3DH_ReadReg(LIS3DH_WHO_AM_I, &int1_src);
        delay1ms(3000);
    }               
}
求大佬解答一下。
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    cxieyunsky xieyunsky_ 2019-08-14 11:32

    已找到出现问题的原因。已解决问题,且实现INT1中断及读取加速度数值。

    点赞 评论 复制链接分享
  • baidu_33879812 雲烟 2019-08-07 13:51

    你在lis3dh_init()之后延时1s,然后读一下who im i 寄存器,我记得读出来是0x33,你先确定你的spi是好的,你这个是模拟的SPI,可能是这个也有问题,如果有硬件SPI,试试读who im i ,你同样设置了中断阈值寄存器,写完之后一定要虚读reference寄存器一次,具体原理我不太清楚,当时我也是这么做才用起来的。

    点赞 评论 复制链接分享

相关推荐