微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 硬件电路设计 > TI电源管理交流 > 有哪位朋友做过STM32的IO口模拟I2C读取BQ34Z100电量计数据吗,在下老读到数据时0xffff

有哪位朋友做过STM32的IO口模拟I2C读取BQ34Z100电量计数据吗,在下老读到数据时0xffff

时间:10-02 整理:3721RD 点击:

#include "config.h"
extern unsigned char TxData[BUFFERSIZE];
extern unsigned char RxData[BUFFERSIZE];

void BQ34Z100_I2C_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin=I2C_SCL|I2C_SDA;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);

I2C_SCL_H;
I2C_SDA_H;
}
/**********************************************************
I2C_SDA_OUT初始化函数
**************************************************************/
void BQ34Z100_I2C_SDA_OUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure; 
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin=I2C_SDA;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
 /**********************************************************
I2C_SDA_IN初始化函数
**************************************************************/
void BQ34Z100_I2C_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure; 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin=I2C_SDA;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}

//void MSP430_SWI2CMST_delay(void)
//{
//  __delay_cycles(GPIODELAYCYCLES);          // Quick delay
//}

void BQ34Z100_I2C_start(void)
{
 BQ34Z100_I2C_SDA_OUT();  
I2C_SDA_H;
I2C_SCL_H;
delay_us(4);
I2C_SDA_L;
delay_us(4);
 I2C_SCL_L;
delay_us(4);

}

void BQ34Z100_I2C_stop(void)
{
BQ34Z100_I2C_SDA_OUT();  
I2C_SDA_L;
 delay_us(4);
I2C_SCL_H;
delay_us(4); 
I2C_SDA_H;
delay_us(4);

}

unsigned char BQ34Z100_I2C_txByte(unsigned char data)
{
  unsigned char bits, temp, ack;

   I2C_SCL_L;
  temp = data;                              // Initialize temp variable
  bits = 0x08;  
 BQ34Z100_I2C_SDA_OUT();                            // Load I2C bit counter
  while (bits != 0x00)                      // Loop until all bits are shifted
  {
    if (temp & 0x80)                        // Test data bit
      I2C_SDA_H;                              // SDA = 1
    else
    I2C_SDA_L;                             // SDA = 0
    delay_us(4);                              // Quick delay
  I2C_SCL_H;                               // SCL = 1
   // while (I2C_SCL_READ() == 0);              //111去掉   Wait for any SCL clock stretching change1
    delay_us(4);                           // Quick delay
    temp = (temp << 1);                     // Shift bits 1 place to the left
     I2C_SCL_L;                                 // SCL = 0
    bits = (bits - 1);                      // Loop until 8 bits are sent
  }
delay_us(4);//  I2CDELAY;
   I2C_SDA_H;                                   // SDA = 1
  I2C_SCL_H;  
// while (I2C_SCL_READ() == 0);          // Wait for any SCL clock stretchingchange2
 delay_us(4);                              // Quick delay
  ack=I2C_SDA_READ();                    // Read ACK state from Slave
  I2C_SCL_L;                                 // SCL = 0
  if (ack)                                  // Return ACK state to calling app
    return (1);
  else
    return (0);




}

unsigned char BQ34Z100_I2C_rxByte(char ack)
{
  unsigned char bits, data = 0;
 BQ34Z100_I2C_SDA_IN();
 I2C_SDA_H;                                 // SDA = 1
  bits = 0x08;                              // Load I2C bit counter
  while (bits > 0)                          // Loop until all bits are read
  {
    I2C_SCL_H;                               // SCL = 1
// while (I2C_SCL_READ() == 0);  //    while ((PxIN & SCL) == 0); 111去掉             // Wait for any SCL clock stretchingchange3
    delay_us(4);                             // Quick delay
    data = (data << 1);                     // Shift bits 1 place to the left
    if(I2C_SDA_READ()==1)                        // Check digital input
      data = (data + 1);                    // If input is high, store a '1'
    I2C_SCL_L;                                // SCL = 0
   delay_us(4);                            // Quick delay
    bits = (bits - 1);                      // Decrement I2C bit counter
  }
  if (ack)                                  // Need to send ACK to Slave?
    I2C_SDA_L;/                               // Yes, so pull SDA low
  else


I2C_SDA_H;                               // No, so keep SDA high
I2C_SCL_H;                                // SCL = 1
  delay_us(4);                               // Equivalent to sending N(ACK)
  I2C_SCL_L;                                  // SCL = 0
  I2C_SDA_H;                                   // SDA = 1

  return (data);                            // Return 8-bit data byte
}

void BQ34Z100_I2C_writeBlock(unsigned char SlaveAddress,
                                unsigned int numBytes, unsigned char multi,
                                void* TxData)
{
  unsigned int  i;
  unsigned char *temp;

  temp = (unsigned char *)TxData;           // Initialize array pointer
  BQ34Z100_I2C_start();                  // Send Start condition
  BQ34Z100_I2C_txByte(SlaveAddress); // [ADDR] + R/W bit = 0
  for (i = 0; i < numBytes; i++)
  {
    BQ34Z100_I2C_txByte(*(temp));        // Send data and ack
    temp++;                                 // Increment pointer to next element
  }
  if (multi == 0)                           // Need STOP condition?
  {
    BQ34Z100_I2C_stop();                 // Yes, send STOP condition
  }
 delay_us(4);// I2CDELAY;                                 // Quick delay
}

void BQ34Z100_I2C_readBlock(unsigned char SlaveAddress,
                               unsigned int numBytes, void* RxData)
{
  unsigned int  i;
  unsigned char* temp;

  temp = (unsigned char *)RxData;           // Initialize array pointer
  BQ34Z100_I2C_start();                  // Send Start condition
  BQ34Z100_I2C_txByte(SlaveAddress+0x01); // [ADDR] + R/W bit = 1
  for (i = 0; i < numBytes; i++)
  {
    if (i == (numBytes - 1))
      *(temp) = BQ34Z100_I2C_rxByte(0);// Read last 8-bit data with no ACK
    else
      *(temp) = BQ34Z100_I2C_rxByte(1);// Read 8-bit data & then send ACK
    temp++;                                 // Increment pointer to next element
  }
 BQ34Z100_I2C_stop();                   // Send Stop condition
}



unsigned int transBytes2UnsignedInt(unsigned char msb, unsigned char lsb)
{
  unsigned int tmp;

  tmp = ((msb << 8) & 0xFF00);
  return ((unsigned int)(tmp + lsb) & 0x0000FFFF);
}

void BQ34Z100_read(unsigned char cmd, unsigned int bytes)
{
  unsigned char tx[1];

  tx[0] = cmd;

  BQ34Z100_I2C_writeBlock(I2CSLAVEADDR, 1, 1, tx);
  
  BQ34Z100_I2C_readBlock(I2CSLAVEADDR, bytes, RxData);
}

主函数里:

BQ34Z100_read(0x0C, 2);//读取温度


vale= transBytes2UnsignedInt(RxData[1], RxData[0]);

我做过430 模拟    stm8 IIC        但是开发的不是这款片子       根据我之前遇到的问题  1  SMBbus  通信首先速率 大于10K?记不清了  小于100K         2 地址0x16     3类似IIC 从机有时会拉低时钟线 请求主机等待  这一点大多数人没留意    4 通信有时配置为有校验     我当时用EV2300通信示波器捕捉 拍照片比对   你就仿照波形去写代码  挺有效的   也是搞了好久成功 祝你成功

 用STM32单片机模拟I2C,发送地址0xAA,BQ34Z100的SDA没有回复ACK

地址不对吧  对了就会有应答啊

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top