BQ24195的使用:与MSP430G2553的I2C通信

发布者:草莓熊猫最新更新时间:2020-06-21 来源: eefocus关键字:BQ24195  MSP430G2553  I2C通信 手机看文章 扫描二维码
随时随地手机看文章

前言

本文作为bq24195的I2C使用教程,主要涉及I2C通信代码的实现以及一些注意事项,硬件部分稍有涉及但不是主要内容。


正文

硬件连接图:

I2C的上拉电阻10K或4.7K都行,阻值影响的是跳变沿的时间,即使fast mode I2C通信的频率也才400k左右,所以影响不大。


软件例程

我们用的是G2553的硬件I2C,有中断法和查询法,不想用中断的可以用查询法。如果选择了低功耗,建议用中断法。


MSP430G2553硬件I2C驱动-中断法

IT已经给我们准备好了,直接照搬msp430g2xx3_usci_i2c_standard_master.c例程就行。稍微整理一下做成i2c.h和i2c.c文件,力求简洁美观。


/*

 * i2c.h

 */

 

#ifndef I2C_H_

#define I2C_H_

 

#include

 

#define SLAVE_ADDR  0x6B    //BQ24195

 

#define MAX_BUFFER_SIZE     20

 

//******************************************************************************

// General I2C State Machine ***************************************************

//******************************************************************************

 

typedef enum I2C_ModeEnum{

    IDLE_MODE,

    NACK_MODE,

    TX_REG_ADDRESS_MODE,

    RX_REG_ADDRESS_MODE,

    TX_DATA_MODE,

    RX_DATA_MODE,

    SWITCH_TO_RX_MODE,

    SWITHC_TO_TX_MODE,

    TIMEOUT_MODE

} I2C_Mode;

 

void initClockTo16MHz();

void initI2C();

void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);

I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);

I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);

 

#endif /* I2C_H_ */

 

下面是i2c.c文件:


/*

 * i2c.c

 */

 

#include

#include

#include

#include "i2c.h"

 

I2C_Mode MasterMode = IDLE_MODE;

uint8_t TransmitRegAddr = 0;

 

 

uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};

uint8_t RXByteCtr = 0;

uint8_t ReceiveIndex = 0;

uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};

uint8_t TXByteCtr = 0;

uint8_t TransmitIndex = 0;

 

 

I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)

{

    /* Initialize state machine */

    MasterMode = TX_REG_ADDRESS_MODE;

    TransmitRegAddr = reg_addr;

    RXByteCtr = count;

    TXByteCtr = 0;

    ReceiveIndex = 0;

    TransmitIndex = 0;

 

    /* Initialize slave address and interrupts */

    UCB0I2CSA = dev_addr;

    IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);       // Clear any pending interrupts

    IE2 &= ~UCB0RXIE;                       // Disable RX interrupt

    IE2 |= UCB0TXIE;                        // Enable TX interrupt

 

    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition

    __bis_SR_register(CPUOFF + GIE);              // Enter LPM0 w/ interrupts

 

    return MasterMode;

 

}

 

I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)

{

    /* Initialize state machine */

    MasterMode = TX_REG_ADDRESS_MODE;

    TransmitRegAddr = reg_addr;

 

    //Copy register data to TransmitBuffer

    CopyArray(reg_data, TransmitBuffer, count);

 

    TXByteCtr = count;

    RXByteCtr = 0;

    ReceiveIndex = 0;

    TransmitIndex = 0;

 

    /* Initialize slave address and interrupts */

    UCB0I2CSA = dev_addr;

    IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);       // Clear any pending interrupts

    IE2 &= ~UCB0RXIE;                       // Disable RX interrupt

    IE2 |= UCB0TXIE;                        // Enable TX interrupt

 

    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition

    __bis_SR_register(CPUOFF + GIE);      // Enter LPM0 w/ interrupts

 

    return MasterMode;

}

 

 

void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)

{

    uint8_t copyIndex = 0;

    for (copyIndex = 0; copyIndex < count; copyIndex++)

    {

        dest[copyIndex] = source[copyIndex];

    }

}

 

void initClockTo16MHz()

{

    if (CALBC1_16MHZ==0xFF)                  // If calibration constant erased

    {

        while(1);                               // do not load, trap CPU!!

    }

    DCOCTL = 0;                               // Select lowest DCOx and MODx settings

    BCSCTL1 = CALBC1_16MHZ;                    // Set DCO

    DCOCTL = CALDCO_16MHZ;

}

 

 

void initI2C()

{

    P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0

    P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0

 

    UCB0CTL1 |= UCSWRST;                      // Enable SW reset

    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode

    UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset

    UCB0BR0 = 160;                            // fSCL = SMCLK/160 = ~100kHz

    UCB0BR1 = 0;

    UCB0I2CSA = SLAVE_ADDR;                   // Slave Address

    UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation

    UCB0I2CIE |= UCNACKIE;

}

 

 

#pragma vector = USCIAB0TX_VECTOR

__interrupt void USCIAB0TX_ISR(void)

{

  if (IFG2 & UCB0RXIFG)                 // Receive Data Interrupt

  {

      //Must read from UCB0RXBUF

      uint8_t rx_val = UCB0RXBUF;

 

      if (RXByteCtr)

      {

          ReceiveBuffer[ReceiveIndex++] = rx_val;

          RXByteCtr--;

      }

 

      if (RXByteCtr == 1)        //特别注意

      {

          UCB0CTL1 |= UCTXSTP;

      }

      else if (RXByteCtr == 0)

      {

          IE2 &= ~UCB0RXIE;

          MasterMode = IDLE_MODE;

          __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0

      }

  }

  else if (IFG2 & UCB0TXIFG)            // Transmit Data Interrupt

  {

      switch (MasterMode)

      {

          case TX_REG_ADDRESS_MODE:

              UCB0TXBUF = TransmitRegAddr;

              if (RXByteCtr)

                  MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now

              else

                  MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer

              break;

 

          case SWITCH_TO_RX_MODE:

              IE2 |= UCB0RXIE;              // Enable RX interrupt

              IE2 &= ~UCB0TXIE;             // Disable TX interrupt

              UCB0CTL1 &= ~UCTR;            // Switch to receiver

              MasterMode = RX_DATA_MODE;    // State state is to receive data

              UCB0CTL1 |= UCTXSTT;          // Send repeated start

              if (RXByteCtr == 1)

              {

                  //特别注意

                  //Must send stop since this is the N-1 byte

                  while((UCB0CTL1 & UCTXSTT));

                  UCB0CTL1 |= UCTXSTP;      // Send stop condition

              }

              break;

 

          case TX_DATA_MODE:

              if (TXByteCtr)

              {

                  UCB0TXBUF = TransmitBuffer[TransmitIndex++];

                  TXByteCtr--;

              }

              else

              {

                  //Done with transmission

                  UCB0CTL1 |= UCTXSTP;     // Send stop condition

[1] [2]
关键字:BQ24195  MSP430G2553  I2C通信 引用地址:BQ24195的使用:与MSP430G2553的I2C通信

上一篇:msp430g2553的IIC通信
下一篇:MSP430系列单片机的DMA使用全面认识

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved