你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

加速度传感器LIS3DH与STM32F103通讯问题

[复制链接]
西祠响马 提问时间:2019-3-28 13:23 /
定义了一个数据buffer[10],然后通过SPI总线从传感器读数据。
每10ms从传感器读数据,读的时候使用监视状态寄存器并等待的方式。
这里面有几个中断 ADC、TIM1
主要问题有:
1.             读入的数据总是错位,本来在buffer[1]的数据有时会到buffer[2],后来改在ADC中断中进行处理,数据倒是不会转移了。读取的数据如下
读取地址 27h,长度7
  
Buffer
  
正确数据
我读取的数据
buffer[0]
0F
FF
buffer[1]
00
0F
buffer[2]
00
00
buffer[3]
00
00
buffer[4]
00
00
buffer[5]
00
00
buffer[6]
00
00
好像是读取了一个无效的数据。
2.             使用DMA,但不在中断中执行的效果和(1)相同
3.             读出来的好像是位置数据,需要做什么处理吗?手册上说的是振动数据。
部分程序:
SPI 初始化
   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线双向全双工,还有半双工以及串行发和串行收方式
   SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // SPI  还有副 SPI
   SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI 发送接收8或者16位帧结构
   SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//串行同步时钟的空闲状态为高电平或者低电平
   SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//第一个或者第二个跳变沿数据被采样
SPI_InitStructure.SPI_NSS= SPI_NSS_Soft; //NSS 信号由软件控制
SPI_InitStructure.SPI_BaudRatePrescaler= SPI_BaudRatePrescaler_8; //预分频 256
SPI_InitStructure.SPI_FirstBit= SPI_FirstBit_MSB; //数据传输从 MSB 位开始
SPI_InitStructure.SPI_CRCPolynomial= 7; //CRC 值计算的多项式
SPI_Init(SPI3,&SPI_InitStructure); //根据指定的参数初始化外设 SPIx 寄存器
SPI_Cmd(SPI3,ENABLE);//使能SPI外设
voidInitLIS3DH(void)
{
  response = LIS3DH_WriteReg(LIS3DH_CTRL_REG1,0x57);         // 100Hz
response =  LIS3DH_WriteReg(LIS3DH_CTRL_REG2, 0); //高通滤波模式
response =  LIS3DH_WriteReg(LIS3DH_CTRL_REG3, 0);
response =  LIS3DH_WriteReg(LIS3DH_CTRL_REG4, 0); //正常模式,+-2g,低位在低字节
}
数据处理 ADC中断中执行
voidProcLis3dh(void)
{
response =LIS3DH_ReadReg(LIS3DH_STATUS_REG,&buffer[0]);
          if(buffer[1] & 0x08)
          {
                   View[6] = (((INT16S)buffer[3]<< 8) + buffer[2]) >> 6;
                   View[7] = (((INT16S)buffer[5]<< 8) + buffer[4]) >> 6;
                   View[8] = (((INT16S)buffer[7]<< 8) + buffer[6]) >> 6;
          }
}
u8_tLIS3DH_ReadReg(u8_t Reg, u8_t* Data)
{
INT8U i = 0,j = 0,k = 0;
    ZHD_CS_0;
SPI_FLASH_DMAMode(1);
    while ((SPI3->SR &SPI_I2S_FLAG_TXE)  == RESET);
    SPI3->DR = Reg | 0xc0;
for(i = 0; i <= 7;i++)
{
    while ((SPI3->SR & SPI_I2S_FLAG_TXE)== RESET)
{
          j++;
          if(j>20)
          {
                   return(0);
          }
}
          SPI3->DR = 0xFF;
    while( SPI_I2S_GetFlagStatus( SPI3,SPI_I2S_FLAG_RXNE ) == RESET )
{
          k++;
          if(k>20)
          {
                   return(0);
          }
}                 
    *Data++ = SPI3->DR;
}                 
SPI_FLASH_DMAMode(0);
ZHD_CS_1;
  return 1;
}
voidSPI_FLASH_DMAMode(u8 enable)
{
    if(0 == enable)
    {
        RCC->APB1RSTR |=RCC_APB1RSTR_SPI3RST;
        RCC->APB1RSTR &=~(RCC_APB1RSTR_SPI3RST);
        SPI3->CR1 =SPI_CR1_CPHA|SPI_CR1_CPOL|SPI_CR1_MSTR|SPI_CR1_SPE|
SPI_CR1_SSI|SPI_CR1_SSM|SPI_CR1_BR_1;
             SPI3->I2SCFGR &= ~(SPI_I2SCFGR_I2SMOD);
     }
    else
    {
        SPI3->CR2 |= SPI_CR2_RXDMAEN;
          }

}
希望有高手不吝赐教,感激不尽!

收藏 评论5 发布时间:2019-3-28 13:23

举报

5个回答
一代睡神的崛起 回答时间:2019-3-28 13:43:33
看来是数据错位了呀,怎么最高位还是F填充?没玩过这个MEMS等会儿去看看手册

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

衔胆栖冰 回答时间:2019-3-28 21:48:47
SPI同步通信,发送和接收是同时的,发送第一个字节(地址)的同时会返回一个无效数据,再发下一个时钟才能得到正确的数据。多看数据手册,这些东西一般没啥难度,根据手册操作就行。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

西祠响马 回答时间:2019-3-29 13:03:31
一代睡神的崛起 发表于 2019-3-28 13:43
看来是数据错位了呀,怎么最高位还是F填充?没玩过这个MEMS等会儿去看看手册 ...

好的,我也再去看看手册。有啥收获麻烦及时指教
西祠响马 回答时间:2019-3-29 13:04:07
衔胆栖冰 发表于 2019-3-28 21:48
SPI同步通信,发送和接收是同时的,发送第一个字节(地址)的同时会返回一个无效数据,再发下一个时钟才能 ...

嗯嗯,好的,这就去反复看手册
edmundlee 回答时间:2019-3-29 13:36:59
本帖最后由 edmundlee 于 2019-3-29 13:39 编辑

我之前也碰到过类似的问题, 不知道是否跟楼主的同一个问题
SPI有分4个不同的模式, 比如是上升沿读还是下降沿读, 比如空闲状态是高还是低, 看清楚传感器的规格书, 然后把SPI的配置跟上。
另外, 如果把传感器的CE在上电后先禁能几十个微秒后再使能, 可以防止上电时误触发时钟信号, 引至移位。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版