引用: 快乐程序员 发表于 2018-10-29 08:23
who am i 正常的,其他需要配置的寄存器我也是先写再读,保证配置正确

再不行试下这个代码
lis2dh12_STdC.rar (14.97 KB)
(下载次数: 168, 2018-10-29 11:12 上传)

虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2018-10-29 11:12
引用: littleshrimp 发表于 2018-10-29 11:12
再不行试下这个代码

这个代码测试了下,读出的XYZ数据都是一样的 3F80 FE80  FE00
Acceleration [mg]:1016.00        -24.00        -32.00

我看了下状态寄存器0x27,读完数据后会自动清0;

点赞  2018-10-29 11:44
引用: littleshrimp 发表于 2018-10-29 11:12
再不行试下这个代码

吃过饭 重新上了个电  OK了
应该是之前哪个寄存器被我配置掉了
两套代码跑其实都没问题,问题是我的IIC读
读1个字节OK,读6个字节失败,所以之前数据没获取到,0x27状态也一直清除不掉
点赞  2018-10-29 13:10
引用: littleshrimp 发表于 2018-10-29 11:12
再不行试下这个代码

多谢支持
点赞  2018-10-29 13:10
我也是使用NRF的单片机,使用VER2.3的驱动程序。寄存器写完后,一起读出来,确定是没有配置错的,也重新上电试过,但是发现寄存器LIS2DH12_STATUS_REG总是为0xff,而且3个轴的值装换完后始终是-2040.楼主有遇到过这种情况吗?
点赞  2018-11-17 17:36
是我自己智障了,没理解上一个哥们的回复。NRF的IIC历程要注意读取的函数,不是在一个寄存器读6个数据,而是应该在6个寄存器分别读1个数据。当修改模块额配置时,最好让模块重新上电,恢复默认值在进行配置,防止之前的配置有错误。
点赞  2018-11-17 17:58
感谢楼主分享!以后慢慢学。
点赞  2018-12-10 18:28

正好需要。作为参考,谢谢!

点赞  2019-10-18 17:00

I2C_MEMS.H和HW配置H文件没有,在哪里找呀,谢谢,文件中没有

点赞  2020-3-21 16:54

请问各位,IIC的速度使用的是多少,我发送设备地址后没有应答,怀疑是IIC速度的问题

点赞  2020-3-31 23:25
引用: littleshrimp 发表于 2018-5-16 18:34 你的意思是说platform_write要使用0x30,platform_read要使用0x31这样区分吗? 这个例程是使用stm32操作 ...

您好,请问 在使用I/O模拟I2C的时候具体如何在对应的读函数里将设备地址&0x01?

点赞  2020-4-3 23:29
引用: hongboyunquan 发表于 2020-4-3 23:29
您好,请问 在使用I/O模拟I2C的时候具体如何在对应的读函数里将设备地址&0x01?

发送地址前直接设置地址变量不行吗?
点赞  2020-4-4 05:14
引用: ppsp59 发表于 2020-3-31 23:25
请问各位,IIC的速度使用的是多少,我发送设备地址后没有应答,怀疑是IIC速度的问题

可以看数据手册
  • Screenshot_20200404_052905_com.adobe.reader.jpg
点赞  2020-4-4 05:29
项目准备用,谢谢分享。
点赞  2020-6-5 23:37
引用: ppsp59 发表于 2020-3-31 23:25 请问各位,IIC的速度使用的是多少,我发送设备地址后没有应答,怀疑是IIC速度的问题

配的多少输出哇

点赞  2024-4-15 18:32

我读WHO AM I寄存器也是0xff

点赞  2024-4-16 09:24
引用: anning865 发表于 2018-5-17 20:54 这个驱动倒是可以用的,使用STM32F4很容易就移植了。但是STM32F1系列的就不行,后来查了一圈,发现是STM32F ...

有使用模拟IIC的例程吗,我使用模拟IIC获取器件ID一直都是0xff,代码如下:

/* STMicroelectronics evaluation boards definition

 *

 * Please uncomment ONLY the evaluation boards in use.

 * If a different hardware is used please comment all

 * following target board and redefine yours.

 */

 

//#define STEVAL_MKI109V3  /* little endian */

//#define NUCLEO_F411RE    /* little endian */

//#define SPC584B_DIS      /* big endian */

 

/* ATTENTION: By default the driver is little endian. If you need switch

 *            to big endian please see "Endianness definitions" in the

 *            header file of the driver (_reg.h).

 */

/* Includes ------------------------------------------------------------------*/

#include "stm32f10x.h"    // Device header

#include "lis2dh12_reg.h"

#include "stdint.h"

#include "math.h"

#include "stdio.h"

#include "stm32f10x_gpio.h"        

#include <stm32f10x_rcc.h>

#include <system_stm32f10x.h>

#include <core_cm3.h>

#include <misc.h>


 

#define LIS2DH12_FROM_FS_2g_HR_TO_mg(lsb)  (float)((int16_t)lsb>>4) * 1.0f

#define LIS2DH12_FROM_FS_4g_HR_TO_mg(lsb)  (float)((int16_t)lsb>>4) * 2.0f

#define LIS2DH12_FROM_FS_8g_HR_TO_mg(lsb)  (float)((int16_t)lsb>>4) * 4.0f

#define LIS2DH12_FROM_FS_16g_HR_TO_mg(lsb) (float)((int16_t)lsb>>4) * 12.0f

#define LIS2DH12_FROM_LSB_TO_degC_HR(lsb)  (float)((int16_t)lsb>>6) / 4.0f+25.0f

 

#define DEGREE_CAL 180.0/3.1416

 

#define IIC_SDA_PING    GPIO_Pin_9

#define IIC_SCL_PING    GPIO_Pin_8

#define IIC_PORT        GPIOB

 

#define SDA_H           GPIO_SetBits(IIC_PORT,IIC_SDA_PING)

#define SDA_L           GPIO_ResetBits(IIC_PORT,IIC_SDA_PING)

#define SCL_H           GPIO_SetBits(IIC_PORT,IIC_SCL_PING)

#define SCL_L           GPIO_ResetBits(IIC_PORT,IIC_SCL_PING)

#define SDA_IN          0

#define SDA_OUT         1

#define SDA             GPIO_ReadInputDataBit(IIC_PORT,IIC_SDA_PING)


 

typedef struct {

  short x;

  short y;

  short z;

  short new_angle_x;

  short new_angle_y;

  short new_angle_z;

}axis_info_t;

 

axis_info_t sample;

/* Private macro -------------------------------------------------------------*/

#define    DELAYX_TIME             6  //5us

 

static int32_t lis2dh12_iic_write_byte( uint8_t reg, uint8_t bufp);

static int32_t lis2dh12_iic_read_byte(uint8_t reg, uint8_t *bufp);

 

uint32_t fac_us = 0;

uint32_t fac_ms = 0;

uint32_t fac_s = 0;

 

void delay_init(void)

{

  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);   //选择外部时钟  HCLK/8

  fac_us=SystemCoreClock/8000000;                         //选择的经过8分频的外部时钟

  fac_ms=(u16)fac_us*1000;                                //非OS下,代表每个ms需要的systick时钟数  

  fac_s = fac_ms * 1000;                                  //非OS下,代表每个s需要的systick时钟数

 

}

 

void delay_us(uint32_t  nus)

{      

  u32 temp;

  SysTick->LOAD= nus * fac_us - 1;             //时间加载  

  SysTick->CTRL &= ~(0x01<<1);                 //禁止中断      

  SysTick->VAL= 0x00;                          //清空计数器

  SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;   //开始倒数  

  //这里通过循环判断定时器的状态位值来确认定时器是否已归零

  do{

    temp = SysTick -> CTRL;                    //获取定时器的状态值

  }while(temp & 0x01 && !(temp & (1 << 16)));  //等待时间到达  

  SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;   //关闭计数器

  SysTick->VAL = 0X00;                         //清空计数器  

}

 

void delay_ms(uint16_t nms)

{      

  u32 temp;

  SysTick -> LOAD = nms * fac_ms - 1;           //设置重装载值

  SysTick->CTRL &=~(0x01<<1);                   //禁止中断

  SysTick -> VAL |= 0x00;                       //将定时器归零

  SysTick -> CTRL |= SysTick_CTRL_ENABLE_Msk;   //开启定时器

  //这里通过循环判断定时器的状态位值来确认定时器是否已归零

  do{

    temp = SysTick -> CTRL;                     //获取定时器的状态值

  }while(temp & 0x01 && !(temp & (1 << 16)));   //等待时间到达  

  SysTick -> CTRL &= ~SysTick_CTRL_ENABLE_Msk;  //关闭定时器

  SysTick -> VAL |= 0x00;                       //将定时器归零      

}



 

void IIC_SDA_MODE(uint8_t SDA_Mode)

{

    GPIO_InitTypeDef  GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = IIC_SDA_PING;  

  if(SDA_Mode){

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;              

    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;      

  }

  else

  {

    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;

  }

  GPIO_Init(IIC_PORT, &GPIO_InitStructure);

}

 

void I2C_Start(void)

{

  SCL_H;

  delay_us(DELAYX_TIME);

  SDA_H;

  delay_us(DELAYX_TIME);

  SDA_L;

  delay_us(DELAYX_TIME);

  SCL_L;

  delay_us(DELAYX_TIME);

}

 

void I2C_Stop(void)

{

  SDA_L;

  delay_us(DELAYX_TIME);

  SCL_H;

  delay_us(DELAYX_TIME);

  SDA_H;

  delay_us(DELAYX_TIME);

}

 

void I2C_Ack(void)

{

 

  IIC_SDA_MODE(SDA_OUT);

  SCL_L;

  delay_us(DELAYX_TIME);

  SDA_L;

  delay_us(DELAYX_TIME);

  SCL_H;

  delay_us(DELAYX_TIME);

  SCL_L;

  delay_us(DELAYX_TIME);

 

}

 

void I2C_NoAck(void)

{

 

  IIC_SDA_MODE(SDA_OUT);

  SCL_L;

  delay_us(DELAYX_TIME);

  SDA_H;

  delay_us(DELAYX_TIME);

  SCL_H;

  delay_us(DELAYX_TIME);

  SCL_L;

  delay_us(DELAYX_TIME);

 

}


 

uint8_t I2C_WaitAck(uint16_t waitime)

{

  SCL_L;

  delay_us(DELAYX_TIME);

  SDA_H;

  IIC_SDA_MODE(SDA_IN);

//  delay_us(DELAYX_TIME);

  SCL_H;

  while(waitime){

    if(SDA == 0)break;

    delay_us(2);

    waitime--;

  }

  IIC_SDA_MODE(SDA_OUT);

  return waitime;

}

 

void I2C_SendByte(uint8_t data)

{

  uint8_t i;

  SCL_L;

  delay_us(DELAYX_TIME);

  for(i = 0;i < 8;i++)

  {

    if(data & (0x01 << (7 - i))) SDA_H;

     else SDA_L;

    delay_us(DELAYX_TIME);

    SCL_H;

    delay_us(DELAYX_TIME);

    SCL_L;

    delay_us(DELAYX_TIME);

  }

}

 

uint8_t I2C_ReadByte(void)

{

  uint8_t i,data = 0;

  SCL_L;

  SDA_H;

  IIC_SDA_MODE(SDA_IN);

  for(i=0;i<8;i++)

  {  

    SCL_H;  

    delay_us(DELAYX_TIME);

    data <<= 1;

    if(SDA)

    {

      data |= 0x01;

    }

//    SCL_H;

//    delay_us(DELAYX_TIME);

    SCL_L;

    delay_us(DELAYX_TIME);

  }

  IIC_SDA_MODE(SDA_OUT);

  printf("data = %#x\n", data);

  return data;

}

 

int8_t write_reg(uint8_t reg, uint8_t data,uint16_t len)

{

  uint16_t NoAck=0,stoplen=0;

  stoplen=len;

  I2C_Start();

  I2C_SendByte(LIS2DH12_I2C_ADD_H << 1);

  if(I2C_WaitAck(250) == 0)NoAck++;

  if(((reg>>8)&0xff)!=0){

    I2C_SendByte(reg>>8);

    // if(waitAck(impl,100)==0)NoAck++;

    I2C_Ack();

  }

  I2C_SendByte(reg&0xff);

  I2C_Ack();

  while(NoAck==0&&len){

    I2C_SendByte(data);

    I2C_WaitAck(100);

    data++;len--;

  }

  if(stoplen)

  I2C_Stop();

  return NoAck;

 

  // I2C_SendByte(reg);

  // I2C_WaitAck(250);

  // I2C_SendByte(data);

  // I2C_WaitAck(250);

  // I2C_Stop();

 

}

 

uint8_t IIC_read(uint8_t slave_addr, uint8_t registerAddr,uint8_t *bufp,uint16_t len)

{

  unsigned char NoAck=0;

  I2C_Start();

  I2C_SendByte(slave_addr<<1);

  if(I2C_WaitAck(250)==0)NoAck++;

  printf("NoAck1 = %d\n", NoAck);

// I2C_WaitAck(250);

//  if (len !=1)

//  {

//    I2C_SendByte(registerAddr + 0x80);

//    I2C_WaitAck(250);

 // }

 // else  

    I2C_SendByte(registerAddr);

    if(I2C_WaitAck(250)==0)NoAck++;

    printf("NoAck2 = %d\n", NoAck);

    // I2C_WaitAck(250);

    I2C_Start();

    I2C_SendByte((slave_addr<<1)+1);

    if(I2C_WaitAck(250)==0)NoAck++;

    printf("NoAck3 = %d\n", NoAck);

  while(len&&NoAck==0){

    *bufp=I2C_ReadByte();

    if(len-1!=0)I2C_Ack();

    else I2C_NoAck();

    bufp++;len--;

  }

    printf("bufp = %#x\n", *bufp);

  //   I2C_WaitAck(2);

  // for(int i=0;i<len;i++){

  //   *bufp = I2C_ReadByte();

  //   printf("bufp = %d\n", *bufp);

  //   if(i==len-1){

  //     I2C_NoAck();

  //   }else{

  //     I2C_Ack();

  //   }

  // }

  // I2C_Stop();

  // return bufp[0];

  I2C_Stop();

  return bufp[0];

}

 

void GPIO_I2C_init(void){

 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

 

  GPIO_InitTypeDef  GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = IIC_SCL_PING | IIC_SDA_PING;

  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

 

  GPIO_Init(IIC_PORT,&GPIO_InitStructure);

  GPIO_SetBits(IIC_PORT,IIC_SCL_PING);

  GPIO_SetBits(IIC_PORT,IIC_SDA_PING);

}




 

void lis2dh12_init(void){

  /* Initialization of sensor */

    delay_ms(6); // 6ms

   

    /* Start sensor */

   lis2dh12_iic_write_byte(0x20, 0x57);  

    /* CTRL_REG1(20h): Start sensor at ODR 100Hz high-resolution */

 

   lis2dh12_iic_write_byte(0x23, 0x88);    

     /* CTRL_REG4(23h): 使能快,数据更新,全量程+/-2G,非常精度模式 */

 

   delay_ms(7);// 7ms

   

}

 

 uint8_t i = 0;

/* Main Example --------------------------------------------------------------*/

void lis2dh12_read_data_polling(void)

{

   delay_ms(10); // 10ms

  /* Initialize mems driver interface */

    uint8_t i = 0;

    uint8_t data[6];

    uint8_t ID;

    while (1) {

//       for (i=0; i<6; i++){

//         lis2dh12_iic_read_byte(0x28 +i, data + i);   //获取X、y、z轴的数据

//      }

//      sample.x = LIS2DH12_FROM_FS_2g_HR_TO_mg(*(int16_t*)data);

//      sample.y = LIS2DH12_FROM_FS_2g_HR_TO_mg(*(int16_t*)(data+2));

//      sample.z = LIS2DH12_FROM_FS_2g_HR_TO_mg(*(int16_t*)(data+4));

 

//      sample.new_angle_x = atan((short)sample.x/(short)sqrt(pow(sample.y, 2)+pow(sample.z, 2))) * DEGREE_CAL; // 计算X轴的倾角

//      sample.new_angle_y = atan((short)sample.y/(short)sqrt(pow(sample.x, 2)+pow(sample.z, 2))) * DEGREE_CAL; // 计算Y轴的倾角

//      sample.new_angle_z = atan((short)sample.z/(short)sqrt(pow(sample.x, 2)+pow(sample.y, 2))) * DEGREE_CAL; // 计算Z轴的倾角

 

//      if (sample.new_angle_z < 0)

//      {

//      sample.new_angle_x = 180-sample.new_angle_x;

//      sample.new_angle_y = 180-sample.new_angle_y;

//      }

//       printf("X轴倾角: %hd 度\n", sample.new_angle_x);

//       printf("Y轴倾角: %hd 度\n", sample.new_angle_y);

//       printf("Z轴倾角: %hd 度\n", sample.new_angle_z);

 

        for (i=0; i<1; i++){

         ID = lis2dh12_iic_read_byte(0x0F, data);   //获取ID

    }

       printf("id = %#x\n", ID);

        delay_ms(60);   //6ms  

 

   }

 }

   

static int32_t lis2dh12_iic_write_byte( uint8_t reg,uint8_t data)//写一个字节

{

      write_reg( reg, data,1);  

      return 1;

}

 

static int32_t lis2dh12_iic_read_byte(uint8_t reg, uint8_t *data)//读一个字节

{

      IIC_read(LIS2DH12_I2C_ADD_H, reg, data,1);

      return data[0];

}

 

点赞  2024-5-7 11:29

这个代码感觉十分复杂啊,怎么样看懂,注释也没有啊

点赞  2024-6-2 21:57
12
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复