STM8模拟IIC的问题,和加速度计模块MMA8452Q通信异常

2019-07-19 20:50发布

最近想用STM8S103F3驱动MMA8452Q这个加速度计,可是我模拟的IIC读到的一直是FF,下面是我写的程序,希望可以收到大家的指点,小弟谢谢了!





[mw_shl_code=c,true].C文件


#include "soft_i2c.h"
#include "math.h"
#include "gpio.h"
u8     BUF[8];
int    dis_data;
float  x,y,z;
//===============================================================================
//功能:初始化IIC
//输入:无
//输出:无
//返回:无
//===============================================================================
void Soft_I2C_Int(void)
{
  Set_I2C_SCL_Out1;
  Set_I2C_SDA_Out1;  
//  Set_I2C_SCL_HIGHT;
//  Set_I2C_SDA_HIGHT;
}
//===============================================================================
//功能:模拟I2C的起始条件
//名称: Soft_I2C_Start
//输入:无
//返回:无
//说明: 标准的I2C协议I2C起始条件:SCL为高时,SDA由高变低
//===============================================================================
void Soft_I2C_Start(void)
{
  Set_I2C_SDA_Out1;
  Set_I2C_SCL_HIGHT;
  delay_us(5);
  Set_I2C_SDA_LOW;
  //标准的I2C协议I2C起始条件:SCL为高时,SDA由高变低
  delay_us(5);
  Set_I2C_SCL_LOW;//钳住I2C总线,准备发送或接收数据
}
//===============================================================================
//名称: Soft_I2C_Stop
//功能: 模拟I2C的停止条件
//返回: 无
//说明: 标准的I2C协议I2C停止条件:SCL为高时,SDA由低变高      
//===============================================================================
void Soft_I2C_Stop(void)
{
  Set_I2C_SDA_Out0;
  Set_I2C_SCL_HIGHT;
  delay_us(5);
  Set_I2C_SDA_HIGHT;
  //标准的I2C协议I2C停止条件:SCL为高时,SDA由低变高
  delay_us(5);
}
//===============================================================================
//名称: Soft_I2C_Ack
//功能: 模拟I2C的应答  
//返回:无
//===============================================================================
void Soft_I2C_Ack(void)
{
  Set_I2C_SDA_Out0;
  Set_I2C_SCL_HIGHT;
  delay_us(5);
  Set_I2C_SCL_LOW;
  delay_us(5);
}
//===============================================================================
//名称: Soft_I2C_NAck
//功能: 模拟I2C的不应答
//===============================================================================
void Soft_I2C_NAck(void)
{
  Set_I2C_SDA_Out1;  
  Set_I2C_SCL_HIGHT;
  delay_us(5);
  Set_I2C_SCL_LOW;
  delay_us(5);
}
//===============================================================================
//名称: Soft_I2C_recvACK
//功能: 接收应答信号
//===============================================================================
BitAction Soft_I2C_RecvAck(void)
{
  BitAction CY;
  Set_I2C_SDA_In;
  Set_I2C_SCL_HIGHT;
  delay_us(5);
  CY =(BitAction) Get_I2C_SDA;
  Set_I2C_SCL_LOW;
  delay_us(5);
  
  return CY;
}
//===============================================================================
//名称: Soft_I2C_Send_Byte
//功能: 模拟I2C主器件向从器件发送一个字节
//形参: Byte     
//返回: 无
//===============================================================================
void Soft_I2C_Send_Byte(u8 Byte)
{
  u8 bit,temp;
  for(bit=0;bit<8;bit++)
  {
    temp = Byte & 0x80;
    if(temp == 0)
    {
      Set_I2C_SDA_Out0;
    }
    else if(temp > 0)
    {
       Set_I2C_SDA_Out1;
    }
    Set_I2C_SCL_HIGHT;
    delay_us(5);      
    Set_I2C_SCL_LOW;
    delay_us(5);
    Byte<<= 1;
  }
  Soft_I2C_RecvAck();
}
//===============================================================================
//名称: Soft_I2C_Read_Byte
//功能: 模拟I2C主器件向从器件读取一个字节
//形参: 无
//返回: 一个字节
//明: 主器件从从器件里读一个字节  
//===============================================================================
u8 Soft_I2C_Recv_Byte(void)
{
  u8 bit,dat=0;
  Set_I2C_SDA_In;
  for(bit=0;bit<8;bit++)
  {
    dat<<=1;   //把上一时刻的值左移一位
    Set_I2C_SCL_HIGHT;   
    delay_us(5);   
    dat |= Get_I2C_SDA;
    Set_I2C_SCL_LOW;
    delay_us(5);
  }
  return dat;
}
//============================================================
//功能:单字节写入
//输入:无
//输出:无
//返回:无
//===============================================================================
void Single_Write_MMA8452(unsigned char REG_Address,unsigned char REG_data)
{
    Soft_I2C_Start();                    //起始信号
    Soft_I2C_Send_Byte(SlaveAddress);    //发送设备地址+写信号
    Soft_I2C_Send_Byte(REG_Address);     //内部寄存器地址
    Soft_I2C_Send_Byte(REG_data);        //内部寄存器数据
    Soft_I2C_Stop();                     //停止信号
}
//===============================================================================
//功能:连续读出MMA8452内部加速度数据,地址范围0x01~0x06
//输入:无
//输出:无
//返回:无
//===============================================================================
void Multiple_Read_MMA8452(void)
{   
    unsigned char i;
    Soft_I2C_Start();                          //起始信号
    Soft_I2C_Send_Byte(SlaveAddress);          //发送设备地址

    Soft_I2C_Send_Byte(0x01);                  //发送存储单元地址,从0x01开始
    Soft_I2C_Start();                          //起始信号
    Soft_I2C_Send_Byte(SlaveAddress+1);        //发送设备地址+读信号
       
    for (i=0; i<6; i++)                       //连续读取6个地址数据
    {
      BUF = Soft_I2C_Recv_Byte();          //BUF[0]存储0x32地址中的数据
      if (i == 5)
      {
        Soft_I2C_NAck();                      //最后一个数据需要回NACK         
      }
      else
      {
        Soft_I2C_Ack();                       //回应ACK
      }
   }
    Soft_I2C_Stop();                           //停止信号
    delay_us(5);
}
//===============================================================================
//功能:初始化IIC
//输入:无
//输出:无
//返回:无
//===============================================================================
void Init_MMA8452(void)
{
   Soft_I2C_Int();                  //
   Single_Write_MMA8452(0x2A,0x01); //
   Single_Write_MMA8452(0x2B,0x02); //
}
//====================X轴数据====================================================
float Get_x(void)
{   
    dis_data = (BUF[0]<<8)|BUF[1];//
        dis_data >>= 4;                  //
        x = (float)dis_data;
        return x;
}

//====================Y轴数据====================================================
float Get_y(void)
{   
    dis_data=(BUF[2]<<8)|BUF[3]; //
        dis_data>>=4;                 //
        y=(float)dis_data;
        return y;
}
//====================Z轴数据====================================================
float Get_z(void)
{  
    dis_data=(BUF[4]<<8)|BUF[5];//
    dis_data>>=4;                //
        z=(float)dis_data;
        return z;
}
//===============================================================================
//功能:us级别延时,必须大于0
//输入:无
//输出:无
//返回:无
//===============================================================================
void delay_us(volatile unsigned short time)
{
  do{
      asm("nop");
      asm("nop");
      asm("nop");
      asm("nop");
      asm("nop");
      asm("nop");
    }while(--time);
}


.h文件

#ifndef SOFT_I2C_H
#define SOFT_I2C_H
#include "stm8s.h"
#define I2C_PIN  GPIOB
#define I2C_SCL  GPIO_PIN_4
#define I2C_SDA  GPIO_PIN_5
#define Set_I2C_SCL_HIGHT    GPIO_WriteHigh(I2C_PIN, I2C_SCL)
#define Set_I2C_SCL_LOW      GPIO_WriteLow(I2C_PIN, I2C_SCL)
#define Set_I2C_SDA_HIGHT    GPIO_WriteHigh(I2C_PIN, I2C_SDA)
#define Set_I2C_SDA_LOW      GPIO_WriteLow(I2C_PIN, I2C_SDA)
#define Get_I2C_SDA          GPIO_ReadInputPin(I2C_PIN, I2C_SDA)
#define Set_I2C_SCL_Out1      GPIO_Init(I2C_PIN, I2C_SCL, GPIO_MODE_OUT_PP_HIGH_FAST)
#define Set_I2C_SDA_Out1      GPIO_Init(I2C_PIN, I2C_SDA, GPIO_MODE_OUT_PP_HIGH_FAST)
#define Set_I2C_SCL_Out0      GPIO_Init(I2C_PIN, I2C_SCL, GPIO_MODE_OUT_PP_LOW_FAST)
#define Set_I2C_SDA_Out0      GPIO_Init(I2C_PIN, I2C_SDA, GPIO_MODE_OUT_PP_LOW_FAST)

#define Set_I2C_SDA_In       GPIO_Init(I2C_PIN, I2C_SDA, GPIO_MODE_IN_FL_NO_IT)//PU换成FL

#define        SlaveAddress         0x38

void Soft_I2C_Int(void);
void Soft_I2C_Start(void);
void Soft_I2C_Stop(void);
void Soft_I2C_Ack(void);
void Soft_I2C_NAck(void);
void Soft_I2C_Send_Byte(u8 Byte);
u8 Soft_I2C_Recv_Byte(void);
void Single_Write_MMA8452(unsigned char REG_Address,unsigned char REG_data);
void delay_us(volatile unsigned short time);
BitStatus Soft_I2C_RecvAck(void);
void delay_init(unsigned char clk);
void Init_MMA8452(void);
void Multiple_Read_MMA8452(void);




float Get_x(void);
float Get_y(void);
float Get_z(void);


//void Multiple_Read_MMA8452(void)

//void I2C_MMA8452_ReadByte(void)
#endif[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
操作系统
2019-07-20 17:47
木子又 发表于 2017-4-19 23:00
谢谢,您的意思是我的引脚输出模式错误?

错倒是说不上.用推挽输出方式+上拉输入方式,两个方式切换也是可以完成I2C程序的.但这是不正确的解决办法.使用开漏输出的方式才是正确的.STM8的I2C引脚本身就强制了开漏功能.无推挽输出功能可设置.由此可见.I2C应该设置为开漏输出模式.个人意见..

一周热门 更多>