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]; }
ppsp59 发表于 2020-3-31 23:25 请问各位,IIC的速度使用的是多少,我发送设备地址后没有应答,怀疑是IIC速度的问题配的多少输出哇
已有--人来访过
现在还没有留言