关于STM32的硬件SPI驱动加速度传感器LIS3DH

[复制链接]
11630|19
手机看帖
扫描二维码
随时随地手机跟帖
newsoule|  楼主 | 2013-9-17 10:28 | 显示全部楼层 |阅读模式
本帖最后由 newsoule 于 2013-9-17 10:31 编辑

       之前有位叫“xuqj4490”的朋友在论坛里面发过一贴“ STM32的SPI驱动加速度芯片LIS33DE”,连接如下“https://bbs.21ic.com/icview-219639-1-1.html”。

       最近我也在用STM32的硬件SPI驱动加速度传感器LIS3DH,也遇到很多问题,之后有试过用软件模拟SPI进行驱动,也是同样无法通信。
问题如下:
       1、经过观察CS和SCK的信号正常,而MOSI的信号好像不是很对,MISO没有信号。
             在u8 LIS3DH_SPI_RD(u8 addr)函数中,有SPI_ReadWriteByte((addr|0x80)&0xbf);和temp=SPI_ReadWriteByte(0xff);两句代码,当我在主程序中调用u8 LIS3DH_SPI_RD(u8 addr)函数时,MOSI输出的波形不是很正确;如我调用Dx_L=LIS3DH_SPI_RD(0x28);时,MOSI的波形应该是0xa8ff,而我实际观察到的波形是0xa800,哪位大侠知道这是为什么?
             而MISO一直没有信号,起初我以为是LIS3DH的初始化不正确,经过仔细阅读datasheet,和各自配置实验,MISO依旧没有信号。
       2、我的代码是参考“xuqj4490”这位朋友的。波形、代码、SPI通信协议如下:

波形:
QQ图片20130913164456.jpg
QQ图片20130913164539.jpg


代码:
/* 头文件-- ------------------------------------------------------------------*/
#include "stm32f10x.h"

/* 常量定义-- ----------------------------------------------------------------*/
#define SPI1_CS_High() GPIO_SetBits(GPIOA,GPIO_Pin_4);  
#define SPI1_CS_Low() GPIO_ResetBits(GPIOA,GPIO_Pin_4);

/* 函数声明-- ----------------------------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void USART_Config(USART_TypeDef* USARTx);

void Delay(uint32_t nCount);

void SPI1_STM32_Init(void);
void SPI_LIS3DH_Init(void);
u8 LIS3DH_SPI_RD(u8 addr);
void LIS3DH_SPI_WR(u8 addr,u8 wrdata);
u8 SPI_ReadWriteByte(u8 RxTxData);

/*******************************************************************************
* 函数名称           : 主函数
* 函数功能           :
* 输    入           : None
* 输    出           : None
* 返 回 值           :
* 备    注           :                       
*******************************************************************************/
int main(void)
{
#ifdef DEBUG
  debug();
#endif
  
  u8 Dx_L=0,Dy_L=0,Dz_L=0;
  u8 Dx_H=0,Dy_H=0,Dz_H=0;

  RCC_Configuration();
  NVIC_Configuration();
  GPIO_Configuration();
  USART_Config(USART1);

  SPI1_STM32_Init();
  SPI_LIS3DH_Init();

  while(1)
  {     
     Dx_L=LIS3DH_SPI_RD(0x28);
     Dy_L=LIS3DH_SPI_RD(0x2A);
     Dz_L=LIS3DH_SPI_RD(0x2C);

     Dx_H=LIS3DH_SPI_RD(0x20);
     Dy_H=LIS3DH_SPI_RD(0x23);
     Dz_H=LIS3DH_SPI_RD(0x24);

     //USART_OUT(USART1,"\r\nDx的值为:\r\n");
     USART_SendData(USART1,Dx_L);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
     
     //USART_OUT(USART1,"\r\nDy的值为:\r\n");
     USART_SendData(USART1,Dy_L);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
         
     //USART_OUT(USART1,"\r\nDz的值为:\r\n");
     USART_SendData(USART1,Dz_L);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);

     USART_OUT(USART1,"\r\n");     

     USART_SendData(USART1,Dx_H);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);

     USART_SendData(USART1,Dy_H);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);

     USART_SendData(USART1,Dz_H);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);   
  }
}

//SPI1配置函数
void SPI1_STM32_Init(void)
{
  //SPI1 Init
  GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef SPI_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1|RCC_APB2Periph_GPIOA, ENABLE);

  //SPI1_SCK,SPI1_MOSI
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//口线翻转速度为50MHz
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //SPI1_NSS
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//口线翻转速度为50MHz
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //SPI1_MISO
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  //GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;
  //GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  SPI_Cmd(SPI1,DISABLE);
  //SPI1_CS_High;
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_SSOutputCmd(SPI1,ENABLE);
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;

  //SPI1主机模式
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_Init(SPI1,&SPI_InitStructure);
      
  SPI_Cmd(SPI1,ENABLE);
}


//LIS3DH的初始化
void SPI_LIS3DH_Init()
{
   LIS3DH_SPI_WR(0x20,0x9f);//5kHz Low power mode,XYZ axis enabled
   //LIS3DH_SPI_WR(0x22,0x40);
   LIS3DH_SPI_WR(0x23,0xf1);//+/- 16g,4线spi
   LIS3DH_SPI_WR(0x24,0x0c);//
}

//SPI1读函数
u8 LIS3DH_SPI_RD(u8 addr)
{
    u8  temp;
    SPI1_CS_Low();
    Delay(0x00001);
    SPI_ReadWriteByte((addr|0x80)&0xbf);      
    temp=SPI_ReadWriteByte(0xff);
    Delay(0x00001);
    SPI1_CS_High();
    return temp;
}

//SPI1写函数
void LIS3DH_SPI_WR(u8 addr,u8 wrdata)
{
    SPI1_CS_Low();
    Delay(0x00001);
    SPI_ReadWriteByte(addr&0x7f);
    SPI_ReadWriteByte(wrdata);
    Delay(0x00001);
    SPI1_CS_High();
}

//SPI读写子函数
u8 SPI_ReadWriteByte(u8 RxTxData)
{
    u8 Retry=0;
    while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET)
    {
        Retry++;
        if(Retry>200) return 0;
    }
    SPI_I2S_SendData(SPI1, RxTxData);
    while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET)
    {
        Retry++;
        if(Retry>200) return 0;
    }
    return SPI_I2S_ReceiveData(SPI1);
    SPI_I2S_ClearFlag(SPI1,SPI_I2S_FLAG_RXNE);
}

//延时函数
void Delay(uint32_t nCount)
{
   u16 i=0;
   while(nCount--)
   {
     i=10;
     while(i--);
   }
}

协议:

       QQ图片20130916173205.jpg
QQ图片20130916173139.jpg
QQ图片20130916173120.jpg




QQ图片20130913164600.jpg
ghost_like_li| | 2013-9-17 10:56 | 显示全部楼层
我艹好贴啊,顶楼主!

使用特权

评论回复
1849097455| | 2013-9-17 11:48 | 显示全部楼层
不是很懂这方面,顶一下

使用特权

评论回复
newsoule|  楼主 | 2013-9-17 14:03 | 显示全部楼层
1849097455 发表于 2013-9-17 11:48
不是很懂这方面,顶一下

谢谢                       

使用特权

评论回复
newsoule|  楼主 | 2013-9-17 14:04 | 显示全部楼层
ghost_like_li 发表于 2013-9-17 10:56
我艹好贴啊,顶楼主!

:D

使用特权

评论回复
jgphu| | 2013-9-17 17:19 | 显示全部楼层
我现在就是用STM32 的SPI,没有问题啊。

使用特权

评论回复
newsoule|  楼主 | 2013-9-17 18:05 | 显示全部楼层
jgphu 发表于 2013-9-17 17:19
我现在就是用STM32 的SPI,没有问题啊。

你是MISO,MOSI,SCK和CS是怎么样配置的

使用特权

评论回复
newsoule|  楼主 | 2013-9-17 18:05 | 显示全部楼层
jgphu 发表于 2013-9-17 17:19
我现在就是用STM32 的SPI,没有问题啊。

你MISO,MOSI,SCK和CS是怎么样配置的

使用特权

评论回复
newsoule|  楼主 | 2013-10-15 14:03 | 显示全部楼层
总算摸索好了,可以通信了!

使用特权

评论回复
jgphu| | 2013-11-5 14:25 | 显示全部楼层
  /* Configure SPI_SLAVE pins: SCK and MISO ---------------------------------*/
  /* Configure SCK and MOSI pins as Input Floating */
  GPIO_InitStructure.GPIO_Pin = SPI_SLAVE_PIN_SCK ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(SPI_SLAVE_GPIO, &GPIO_InitStructure);
  /* Configure MISO pin as Alternate Function Push Pull */
  GPIO_InitStructure.GPIO_Pin = SPI_SLAVE_PIN_MISO;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(SPI_SLAVE_GPIO, &GPIO_InitStructure);

使用特权

评论回复
huangbaohong| | 2014-1-2 10:23 | 显示全部楼层
newsoule 发表于 2013-10-15 14:03
总算摸索好了,可以通信了!

请问一下,你最后是怎么调好的呢,是哪儿出了问题?我现在遇到了同样的问题,希望你能帮忙解答一下!

使用特权

评论回复
rdbuy| | 2014-3-26 15:06 | 显示全部楼层
学习一下

使用特权

评论回复
huayuguo| | 2014-5-22 13:16 | 显示全部楼层
不结贴 是一个不好的习惯

使用特权

评论回复
tramp5529| | 2014-10-24 11:18 | 显示全部楼层
你好,现在你调通了吗?能否把程序给我参考一下?谢谢你

使用特权

评论回复
tramp5529| | 2014-10-24 11:20 | 显示全部楼层
jgphu 发表于 2013-9-17 17:19
我现在就是用STM32 的SPI,没有问题啊。

能否把程序发给我看看,我正在调试,谢谢你,37306194@qq.com

使用特权

评论回复
黑白之间| | 2014-12-16 10:18 | 显示全部楼层
是因为CS拉低拉高搞反了么

使用特权

评论回复
yyym| | 2015-12-27 19:56 | 显示全部楼层
是怎么调通的??我遇到的问题跟你一样

使用特权

评论回复
wgy851808815| | 2016-9-7 12:31 | 显示全部楼层
newsoule 发表于 2013-10-15 14:03
总算摸索好了,可以通信了!

读取到的数据总是0xff怎么办?

使用特权

评论回复
xixi2017| | 2017-4-22 22:28 | 显示全部楼层
有没有I2C的版本

使用特权

评论回复
pmp| | 2017-4-22 23:50 | 显示全部楼层
怎么不使用mpu6050?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

70

帖子

0

粉丝