引用: 快乐程序员 发表于 2018-10-29 08:23
who am i 正常的,其他需要配置的寄存器我也是先写再读,保证配置正确
引用: littleshrimp 发表于 2018-10-29 11:12
再不行试下这个代码
引用: littleshrimp 发表于 2018-10-29 11:12
再不行试下这个代码
引用: littleshrimp 发表于 2018-10-29 11:12
再不行试下这个代码
引用: littleshrimp 发表于 2018-5-16 18:34 你的意思是说platform_write要使用0x30,platform_read要使用0x31这样区分吗? 这个例程是使用stm32操作 ...
您好,请问 在使用I/O模拟I2C的时候具体如何在对应的读函数里将设备地址&0x01?
引用: hongboyunquan 发表于 2020-4-3 23:29
您好,请问 在使用I/O模拟I2C的时候具体如何在对应的读函数里将设备地址&0x01?
引用: ppsp59 发表于 2020-3-31 23:25 请问各位,IIC的速度使用的是多少,我发送设备地址后没有应答,怀疑是IIC速度的问题
配的多少输出哇
引用: 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];
}