This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] BQ76942EVM:RL78/F13 (R5F10BGE)微控制器的 SPI 接口问题

Guru**** 2585275 points
Other Parts Discussed in Thread: BQ76942, BQSTUDIO, BQ76952

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/961791/bq76942evm-spi-interface-problem-with-rl78-f13-r5f10bge-microcontroller

器件型号:BQ76942EVM
主题中讨论的其他器件:BQ76942BQSTUDIOBQ76952

用于读取 Cell 1电压的代码中的函数和变量:-//--functions

& Variable Declaration (函数和变量声明)---

uint8_t cell1_Vol_Lbyte_Txarr[3]、cell1_Vol_Lbyte_Rxarr[3];
uint8_t cell1_Vol_Hbyte_Txarr[3]、cell1_Vol_Hbyte_Rxarr[3];

Bit Flag_Device_Reset、Flag_Swap_0
、Flag_Swap_0、Enable_Swap_Swap_Swap_0

Flag_REG1_Config_Enable;


uint8_t swap_SPI_TxArr_L[2]、swap_SPI_TxArr_H[2]、swap_SPI_RxArr_L[2]、swap_SPI_RxArr_H[2];

uint8_t Device_Reset_TxArr_L[2]、Swap_ArxArr_RxArr_L[2]
、Uint_Reset_ArxArr_RxArr_RxArr_RxArr_RxArr_2]
、Uint_RxArr_RxArr_
DEVICE_RESET_RxArr_H[2];

uint8_t REG0_TxCmdAdd_L[2]、REG0_RxCmdAdd_L[2]、
REG0_TxCmdValue Add_H[2]、REG0_RxCmdAdd_H[2]、REG0_RxDataAdd_H[2]、
REG0_RxRx1[REG0_RxData1]、REG0_RxRxG1[REG0_RxG1]、REG0_RxDataAdd_RxRxG1]
、REG0_RxG1[REG0_RxR

uint8_t REG1_TxCmdAdd_L[2]、REG1_RxCmdAdd_L[2]、
REG1_TxCmdAdd_H[2]、REG1_RxCmdAdd_H[2]、
REG1_TxDataAdd[1]、REG1_RxDataAdd[1]、REG1_RxCmdAdd_H[1]、REG1_U0xBTE_1_0_RxValue_BTE_1
、REG1_0_RxBTE_1

、REG1_0_RxBTE_1、REG1_0_RxValu_1、REG1_0_1、REG1_UV_1、REG1_UV_1

void ucSPI00_read_Cell_1_单字 节电压(void);
void ucSPI00_read_Cell_1_单字 节电压(void);
void swap_TO_SPI_Communication_Init (void);
void BQ76942_Device_Reset (void);
void REG0_Config_Enable (void);
void REG1_Config_Enable (void);



//---主函数调用-----

void main (void)
{
PIOR4 = 0x00U;
SELLOSC = 1U;
MDIV = 0x00;
SELPLL = 0U;

CMC = 0x00; 振荡器的//X1和 X2引脚作为输入;端口引脚。
CKC = 0x00;//选择内部高速振荡器。
CSC = 0xC0;//外部振荡器 X1-X2和 XT1-XT2停止、内部高速振荡器运行。
HOCODIV = 0x00;//无频分频---总线时钟= 24MHz
CRC0CTL = 0x00;
IAWCTL = 0x00;

vMain_PowerOnInit ();
EI ();

//---
//--Date 03-12-2020 @ 016:51 PM
///--- 设备重置命令=0x0012
Device_Reset_TxArr_L[0]=0xBE;//-(R/W 位=1表示写入)+0x3E =0xBE
Device_Reset_TxArr_L[1]=0x12;//-低位字节=0x12

Device_Reset_TxArr_H+0x3F;-/'/'= 0x100------/'/'= 0xBfB=100----------
----/-- 0xB=0x100------------/------ 0xB=100--

//--swap 至 SPI 命令=0x7C35----
Swap_SPI_TxArr_L[0]=0xBE;//-(R/W 位=1表示写入)+0x3E =0xBE
SWAP_SPI_TxArr_L[1]=0x35;//Lower Byte =0x35

SWAP_SPI_TxArr_H[0]= 0x3F;//+7Bf=------ 0x7W--------/<--/<------ 0x7B------------/---- 0xBEN---------- 0xB----


/--REG0配置使能:地址= 0x921B,数据= 0x01 (REG0_EN 位= 1)
//--addres 写入(0x921B)
REG0_TxCmdAdd_L[0]=0xBE;//--(R/ W=1写入)+0xG0=0x40/






写入0xG0=0xB0=0xB0/写入0xG1/ 0xB0=0xB+R=0xB0=0xG0=0xB0/写入0xG0=0xB0/ 0xB0=0xB+R/ 0xG0=0xB0=0xB+R/写入0xG0=0xB+R=0xB0=0xG0=0xB+R/ 0xG0_R=0xG0_R/写入0xG0=0xB0=0xB+R/ 0xB0=0xB0=0xG0=0xG0=0xB+R/(0xG0=0xG0=0xB+R/写入0xG0=0xB=0xB=0xB=0xB=0xB=0xG0=0x @



/--REG1=3.3V 使能:地址=0x921A,数据=0x0D (3.3伏)[REG1V_2=1,REG1V_1=1,REG1V_0=0,REG0_EN 位=1]
/--addr 写入(0xG1+0x40=0x40/



REG1=0x40/ REG1=0x40/ REG1=0x40/ REG1+R=0x40/ REG1/ REG1=0xG1=0xB+R/
(0xG1=0xB=0xB+R/ 0xB+R=0xB=0xB+R/ 0xB+D/ 0xB=0x40/(0xB=0xB=0xB+R/ 0xB=0xB+R/ 0xB=0xB+D/ 0xB=0xB=0x40/ 0xB+R/ 0xB+R/ 0xB=0xB=0/ 0xB=0x40/(0xB=0xB=0xB=0xB+R/ 0xB=0xB=0xB=0xB+R/ 0xB=0xB=0/ 0x40/ 0x


@




//--电池1单字节读数--cell1_Vol_Lbyte_Txarr[0]
= 0x14;//0x14位置读
数 cell1_Vol_Lbyte_Txarr[1]=0xFF;

//--Cell 1单字节读数---
CELL1_Vol_Hbyte_Txarr[0]= 0x15;//0x15位置读取
CELL1_Vol_Hbyte_Txarr[1]=0xFF;


Flag_Device_Reset=1;
Flag_Swap_TO_SPI=1;
Flag_REG0_Config_Enable=1;
Flag_REG1_Config_Enable=1;

while (1)
{//main while start
//-------------------- BQ76942设备初始化-------------------------------------------------------
While (Flag_Device_Reset)//- Send Device Reset commmand->0x0012直到正确的值返回
{
BQ76942_Device_Reset ();

if (Device_Reset_TxArr_L[0]=Device_Reset_RxArr_L[0]&(Device_Swap_RxSpi_Reset_Rx_0]=SPI_Reset_RxRF_Rx_0]=器件








交换);while (Device_Swap_RxRF_Rx_Rx_Rx_RxRF_0=SP_0_Rx_Rx_Rx_Rx_Rx_Rx_Rx_Rx_Rx_0]=SP_Rx_Rx_Rx_Rx_Rx_Rx_Rx_Rx_Rx_Rx_Rx_Rx_Rx_RxRF=SP_0]=器件交换)(while)/Spi_RESP_Rx_Rx_Rx_Rx_RESP=SP_


>value=0x01 (REG0_EN 位=1) REG0配置的地址=0x921B
{
REG0_Config_Enable ();

if (REG0_TxCmdAdd_L[0]=REG0_RxCmdAdd_L[0])&(REG0_TxC0 =



REG1=REG0_REG1=REG0_REG1=REG0_REG0_REG1=REG0_REG1=REG0_REG0_REG1=REG0_REG1=REG0_REG0_REG0_REG1=REG1=REG0_REG0_REG0_REG1=REG1=REG0_REG0_REG0_REG0_REG1V=REG0_REG1=REG0_REG0_REG1=REG0_REG0_REG0_REG0_REG0_REG1=REG0_REG1V=REG1=REG







/---0x14和0x15位置处的电池1电压读
数 while (1)//--Cell 1电压的连续读数低字节
{
ucSPI00_Read_Cell_1_单字 节电压();//读取 Cell_1电压低字节---Send at MOSI (0x14、0xFF)

if (1_cellx1_byte_1






)= 0x14_lmix1;[cell_r_byte_lvol=0x14_lbyte_l= 0x14_byte_lbyte_lbyte_/<= 0x14_r= 0x14_byte_lbyte_lbyte_lbyte_/<= 0x14_byte_lbyte_r= 0x14_byte_r= 0x14_byte_r/2_r= 0x14_byte_r= 0x14_ 连续读取 Cell 1电压高位字节
{ucSPI00_Read_Cell_1_Hbyte_Voltage()
;//读取高位字节的 Cell_1电压

if (cell1_Vol_Hbyte_Txarr[0]=cell1_Vol_Hbyte_Rxarr[0])//读取当(MOSI=0x15_Hbyte_Rxarr[0])时的电压






}//main while end
}//-----------------







函数定义-------------------------------------------------------

void REG1_Config_Enable (void)
{
/--Enable REG1 Config:WRITE value =0x0D (REG1V_2=1、REG1V_1=1、REG1V_0=0、REG0_EN 位=1) at REReadconfig Address=0x921A

、REG1V_WriteData+RHD*1


(0x000_RHD_1)、REG1*1 (RHD_1)、REG1&RHD_RHD_1 (0x000_RHD_1)、REG1*1、REHD_RHD_RHD_1 (0x000_1)、REG1*1 (RHD_RHD_RHD_1)、REHD_RHD_1)、REG1*1 (RHD_RHD_RHD_1、REG1&RHD_1)、REHD_RHD_1 (0x1)、REG1&RHD_1、REG1&RHD_RHD_RHD_1、REG1*1 (0x000_RHD_1)、REHD_1 (0x


@
//写入值=0x0D (REG1V_2=1、REG1V_1=1、REG1V_0=0、REG0_EN 位=1)位于0xC0
}

void REG0_Config_Enable (void)
{
/--Enable REG0 Config:WRITE 值=0x01 (REG0_EN 位=1)

、REG0_REG0_REUCD1*
、REG0_REG0_REG0_REUCD1*、REG0_REG0_REG0_REG0_REG0_REG0_REG0_REUCC0_REG0_REG0_REG0_REUCC0_REG0_REG0_REG0_REG0_REG0_REUCC0_REG0_REG0_REG0_REUCC0_REG0_REG0_REG0_REG0_REUCC0_REG0_REG0_REG0_REG0_REG0_REUCC0_REG0_REU




//写入数据 Addr=0xC0 (W=1+0x40、写入值@ 0x40)
ucSPI00_ReadWriteData (1、(uint8_t*)&REG0_TxValue[0]、1、(uint8_t*)&REG0_RxWriteData (1、(uint8_t*);//WriteValue- 0x42-


EN-0x000- EN-0x000- EN-0x000- EN/EN-EN-EN-EN-EN-EN-EN-=VACT-01220_EN-EN/EN-EN-EN-EN-EN-EN-EN-EN-EN-EN
设备重置命令0x0012

ucSPI00_ReadWriteData (1、(uint8_t*)&Device_Reset_TxArr_L[0]、1、(uint8_t*)&Device_Reset_RxArr_L[0]);//写入命令 Addr=0xBE (W=1+WriteData_RHD_R0*



、Uint8_RxRxRxR0*、UCD_R0_R0_R&RHD_R0_R0_RHD_R0*、UCD_R0_R0_R0_RHD_R0_R0_R_RHD_R0_R_R&RHD_RHD_R0_RHD_R0_R0_RHD_R0_R_RHD_R0_R_RHD_R0_R_R0_R_RHD_R_RHD_R0_RIN_RIN_R&RIN_RIN_R0_RIN_RIN_RIN_RIN_RIN_R0











//写入命令 Addr=0xBF (W=1+0x3F,写入过程)
ucSPI00_ReadWriteData (1,(uint8_t*)&swap_SPI_TxArr_H[1],1,(uint8_t*)&swap_RxArr_H[1];/swap_1




,t_1 (uint8_r_r)/uint1,t_1,t_1,t_1,t1 (uint1)






cell1_VOL_Hbyte_Txarr[0]=0x15;//0x15位置读取
cell1_VOL_Hbyte_Txarr[1]=0xFF;

ucSPI00_ReadWriteData (1、(uint8_t*)&Read1_Hvol_Txarr[0]、1、
1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、2、1、1、1、1、1、1、1、1、1、1、1、1、1、2、1、1、1、1、1、1、1、1、1、1、1、1、1、2、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、2、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1





名称:ucSPI00_ReadWriteData
参数:pTxBuf:Tx 缓冲器的起始地址
:ucTxByte:要发送的字节数
:pRxBuff:RX 缓冲器地址
返回:无
说明:在 SPI 总线 CH0上发送和接收数据
/

uint8_t ucSPI00_ReadWriteData (uint8_t ucDevID、uint8_t * pTxBuf、uint8_t ucTxByte、uint8_t * pRxBuf)
{
if (1U TxBMS <)

}return 0;
}

否则{uCDSPI_ducDevID_t = pUCC0_Spi_Spi_Spi_dumxByte














;= pUCC0_Spi_Spi_Spi_Spi_Spi_dumbyte = pxId=pxId=dumbyte;
= p01_spi_spi_spi_dumbid_spi_spxId=pxId_dumbyte = pxId_duSpi_spxId=pxId_dumbyte;}pxId=pxId=pxId=pxId_duSpi_dum_spi_dumbyte;pxId=pxId=pxId=pxId=
}CSIMK00

= 1U;//禁用中断
SDR00L =*pSPI_TxADD;//发送第一个字节
pSPI_TxAdd++;
ucSPI_TxByteCount-;
CSIMK00 = 0U;//启用 INTCSI00中断
}

返回1;
}

/
名称:vSPI_ISR_SPI00
参数:无
返回:无
说明:ISR 要在 SPI 总线 CH0上传输数据
/
__interrupt static void vSPI_ISR_SPI00 (void)
{
*pSPI00_RxADD = SDR00L;
pSPI00_RxAdd++;

if (ucSPI_TxByteCount!= 0U)
{
SDR00L =*pSPI_TxAdd;
pSPI_TxAdd+;}uucSPI ByteCount = 0U;}




= TxStybSPI = TxStybThe_TxCount


;}= TxStybSPI = TxStybt The_TxCount (The_TxCount)


尊敬的 TI 论坛团队:

我正在使用 BQ76942 EVM 板。 实际上、我希望通过 SPI00通道、通过 Renesas RL78/F13 (R5F10BGE) LQFP-48引脚微控制器对 BQ76942器件进行 SPI 通信。

下面提供了硬件连接详细信息 BQ76942 BMS 如何通过 RL78/F13 (R5F10BGE)微控制器连接 SPI00。

BQ76942引脚--- >> RL78/F13 (R5F10BGE)引脚

(1) SPI_SCLK (26引脚)--> P1.7 (SCK00)

(2) SPI_MISO (27引脚)--- >>P1.6 (SI00)

(3) SPI_MOSI (28引脚)--- >>P1.5 (SO00)

(4) SPI_CS (29引脚)--- >> P3.0 (SSI00)

我的问题要点:-

(1)当我发送以下命令序列来读取电池1电压时、该电压位于 BQ76941 RAM 位置的0x14和0x15。 我没有得到电池1电压读数的值、

我们有一段时间从这两个位置都获得0x00和0xFF。

(2)请查看我的命令序列或我发送的电池1电压读数命令是否正确?

(3)如果上述命令及其顺序不正确、请告知我正确的命令及其电芯1电压读数顺序

注:-(1.)  我已将控制器侧的 SPI 通信频率保持在2MHz、如 BQ76942数据表中的 SPI 支持速度所述。

      (2.)  我保留了与 BQ76942数据表以及中提到的时钟和数据时序图相同的 BQ76942 SPI 接口逻辑以时钟极性(CPOL=0)和时钟相位(CPHA=0)运行              微控制器(R5F10BGE)在类型4中进行了介绍、并在随附的屏幕截图中突出显示。

                                               BQ76942 SPI 时序图

                        

                  微控制器 RL78/R5F10BGE SPI 模式时序图

    (3) 如上所述,两个时序图微控制器时序图类型4等效于 BQ76942 CPOL=0和 CPHA=0。 因此、我们在微控制器方面具有保持模式=Type4。  

    (4)上述设置已保留在微控制器端的 SPI 通信的源代码中。

我们在电芯1电压读数源代码中实施的命令及其顺序:-

(1)---- 器件复位命令= 0x0012
DEVICE_RESET_TxArr_L[0]=0xBE;//-(R/W 位=1表示写入)+0x3E=0xBE
DEVICE_RESET_TxArr_L[1]=0x12;//--lower byte =0x12

DEVICE_RESET_TxArr_H[0]=0xBF;//-(R/W 位=1表示写入)+0x3F=0xBF
DEVICE_RESET_TxArr_H[1]=0x00;//-高位字节=0x00
///----------------------------------
(2)--swap 到 SPI 命令=0x7C35----
SWAP_SPI_TxArr_L[0]=0xBE;//-(R/W 位=1表示写入)+0x3E=0xBE
SWAP_SPI_TxArr_L[1]=0x35;//低位字节=0x35

SWAP_SPI_TxArr_H[0]=0xBF;//-(R/W 位=1表示写入)+0x3F=0xBF
SWAP_SPI_TxArr_H[1]=0x7C;//较高字节=0x7C
///----------------------------------
(3)--REG0配置使能:地址= 0x921B,数据= 0x01 (REG0_EN 位= 1)
//--addres 写入(0x921B)
REG0_TxCmdAdd_L[0]=0xBE;//--(R/W 位=1表示写入)+0x3E=0xBE
REG0_TxCmdAdd_L[1]=0x1B;//低位字节=0x1B

REG0_TxCmdAdd_H[0]= 0xBF;//-(R/W 位= 1表示写入)+0x3F = 0xBF
REG0_TxCmdAdd_H[1]=0x92;//高位字节=0x92

//-数据地址写入0x40=0x01
REG0_TxDataAdd[0]= 0xC0;//-(R/W 位=1表示写入)+0x40=0xC0 (写入值@ 0x40)
//--值写入
REG0_TxValue[0]= 0x01;//数据= 0x01 (REG0_EN 位= 1)
///----------------------------------
(4)--REG1=3.3V 使能:地址=0x921A,数据=0x0D (3.3V)[REG1V_2=1,REG1V_1=1,REG1V_0=0,REG0_EN 位=1]
//--addres 写入(0x921A)
REG1_TxCmdAdd_L[0]= 0xBE;//-(R/W 位=1表示写入)+0x3E=0xBE
REG1_TxCmdAdd_L[1]=0x1A;//lower byte=0x1A

REG1_TxCmdAdd_H[0]= 0xBF;//-(R/W 位= 1表示写入)+0x3F = 0xBF
REG1_TxCmdAdd_H[1]=0x92;//高位字节=0x92

//-数据地址写入0x40=0x0D
REG1_TxDataAdd[0]= 0xC0;//-(R/W 位=1表示写入)+0x40=0xC0 (写入值@ 0x40)
//--值写入
REG1_TxValue[0]= 0x0D;//-数据= 0x0D (REG1V_2=1、REG1V_1=1、REG1V_0=0、REG0_EN 位=1)

///----------------------------------
(5)--单元格1单字节读数--
CELL1_VL_Lbyte_Txarr[0]= 0x14;//0x14位置读取
CELL1_Vol_Lbyte_Txarr[1]=0xFF;

(6)--单元格1字节读数----
CELL1_Vol_Hbyte_Txarr[0]= 0x15;//0x15位置读取
CELL1_Vol_Hbyte_Txarr[1]=0xFF;
///----------------------------------

请告诉我哪里有问题、以便 SPI 通信 b/w BQ76942和 R5F10BGE 控制器不会发生。

您的合作值得赞赏。

谢谢、此致

Pankaj Kumar

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Pankaj、

    从代码的快速看、您可能错过了 BQ76942 SPI 文档中的一些内容。 如果您有一个逻辑分析仪、那么首先捕获 BQStudio 和 EVM 之间的 SPI 流量是一个不错的练习、以便查看 SPI 协议的一些示例。

    我建议查看 BQ76942软件开发指南(https://www.ti.com/lit/an/sluaa11a/sluaa11a.pdf)第5节中的示例、该示例遵循 BQStudio 使用的样式。 它使用对每个字节的多次写入来验证命令是否已成功接收。  这是因为、如果内部振荡器未运行(如果器件处于睡眠模式)或处理器繁忙、器件会忽略某些事务。 一旦 MISO 引脚上的数据(应反映先前写入 MOSI 的数据)显示正确的数据、则确认数据包已成功写入。

    《BQ76952技术参考手册》(https://www.ti.com/lit/ug/sluuby2/sluuby2.pdf)还包含一些有关 SPI 接口的非常重要的信息。 (由于器件尚未完全投入生产、因此 BQ76942技术参考手册的最终版本尚未发布、因此我建议现在使用 BQ76952文档。) 它讨论了在某些情况下重试的使用、并给出了不同命令完成的大致时间。  

    当从0x14和0x15读取多字节数据(例如电池1电压)时、当读取第一个字节时、会锁存第二个字节、以便两个字节的电压读数相同。 因此、如果您将该命令重复到0x14、直到看到该命令在 MISO 上回传、则应在首次写入0x15时读取0x14数据(这将是与0x15中的锁存读数配对的值)。  

    当然、可能没有必要对每条命令都采用这种非常谨慎的重试方法、但这种方法可以帮助您了解时间安排。 例如、从0x14读取后、您需要在下一次 SPI 读取命令之前等待~50us 才能完成执行。

    此致、

    Matt