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.

[参考译文] BQ35100:读取和写入数据闪存 BQ35100

Guru**** 2387830 points
Other Parts Discussed in Thread: BQ35100, BQSTUDIO
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1418379/bq35100-read-and-write-data-flash-memory-bq35100

器件型号:BQ35100
Thread 中讨论的其他器件: BQSTUDIO

工具与软件:

下午好!
我是一个经验不足的程序员,所以我很抱歉,如果问题有点不合适。

我正在尝试更改 bq35100的数据闪存中的某个值。 为此、我首先要确认器件是否处于 FULL ACCESS 模式。 然后我读取 ccgain 的值、得到的结果是17276。

尝试将值更改为以下值后:0x1234和0x5678。 之后我​​再次读取 CCGain 值、但它们仍然给出17276。 我在做什么错? 我是否在两者之间遗漏了一些东西? 我附上我使用的代码:

功能:

此函数用于读取16位寄存器
uint16_t read16bitRegister (uint8_t reg_addr、unsigned char numBytesReceived){
uint16_t 数据;
twi_BQRead (reg_addr、numBytesReceived);//从指定的寄存器读取2个字节
DATA =(twi_data_buffer[1]<< 8)| twi_data_buffer[0];//将以小端字节序格式读取的两个字节组合在一起
返回数据;
}

//此函数用于以小端字节序格式写入16位寄存器
void write16bitRegister (uint8_t reg_addr、uint16_t data){
uint8_t low_byte =数据和0xFF;
uint8_t high_byte =(DATA >> 8)和0xFF;
twi_BQWrite (reg_addr、low_byte、high_byte);//以小端字节序格式写入两个字节
_delay_ms (10);//添加一个较小的延迟以确保写入完成
}

uint16_t readCCGain (){
uint16_t cc_gain;

//步骤1:将寄存器地址写入 ManufacturerAccessControl
write16bitRegister (MANUFACTURER_ACCESS_REG、0x4000);// DataFlash 中 CC Gain 的地址
_delay_ms (10);//暂停以进行处理

//步骤2:开始从 MACData 读取(0x40)
TWI_BQRead (0x40、2);//从 MACData 地址(0x40)读取2个字节

//步骤3:组合以小端字节序格式读取的两个字节
CC_GAIN =(twi_data_buffer[1]<< 8)| twi_data_buffer[0];

Return cc_gain;//返回 CC Gain 值
}

void writeCCGain (uint16_t new_value){
uint8_t 校验和;

//步骤1:将寄存器地址写入 ManufacturerAccessControl
write16bitRegister (MANUFACTURER_ACCESS_REG、0x4000);// DataFlash 中 CC Gain 的地址
_delay_ms (10);//暂停以进行处理

//步骤2:将新值写入 MACData (0x40)
TWI_BQWrite (0x40、NEW_VALUE & 0xFF、(NEW_VALUE >> 8)和0xFF);//以小端字节序格式写入值

//步骤3:计算校验和
CHECKSUM = 0x00 + 0x40 +(NEW_VALUE & 0xFF)+((NEW_VALUE >> 8)& 0xFF);//添加地址和数据值
checksum =~checksum + 1;//二进制补码

//步骤4:写入校验和和和长度
TWI_BQWrite (0x60、CHECKSUM、0x02);//写入校验和及长度(2个字节)
_delay_ms (10);//暂停以确保写入完成
}

void displayCCGainOnConsole (){
uint16_t cc_gain;
char buffer[10];//用于存储转换到字符串的值的缓冲区

//读取 CC Gain 值
cc_gain = readCCGain ();//调用读取 CC Gain 的函数

//将 CC 增益值转换为字符串(十进制)
itoa (cc_gain、buffer、10);//将值转换为十进制字符串(以10为底)

//将值发送到控制台
send_at_command ("CC 增益值:");
send_at_command (buffer);//以字符串的形式发送转换后的值
}

void verifyDeviceStatus(){
uint16_t CONTROL_STATUS;
字符缓冲器[10];

//从控制状态寄存器中读取值
CONTROL_STATUS = read16bitRegister (CONTROL_STATUS_REG、2);//从控制状态寄存器读取2个字节

//提取 SEC1和 SEC0位(位14和13)
uint8_t sec_bits =(CONTROL_STATUS >> 13)& 0x03;//获取 SEC1和 SEC0位

//在控制台上显示当前模式
if (sec_bits == 0x01){
send_at_command ("模式:完全访问");
}否则为(sec_bits == 0x02){
send_at_command ("Mode:unsealed");
}否则 if (sec_bits == 0x03){
send_at_command ("Mode:Sealed");
其他{
send_at_command ("模式:保留或未知");
}

//在控制台上显示 Control Status 值(可选)
itoa (control_status、buffer、16);
SEND_AT_COMMAND ("控制状态值:");
send_at_command (buffer);
}

void unlockDevice(){
verifyDeviceStatus();//尝试解锁之前验证当前状态

uint16_t CONTROL_STATUS = read16bitRegister (CONTROL_STATUS_REG、2);//读取当前状态
uint8_t sec_bits =(CONTROL_STATUS >> 13)& 0x03;//获取 SEC1和 SEC0位

//如果器件处于 SEALED 模式(11)、则发送 UNSEAL 命令
if (sec_bits == 0x03){
send_at_command ("尝试解锁器件...");

//步骤1:发送解封命令(通常为0x8000)
write16bitRegister (MANUFACTURER_ACCESS_REG、0x8000);//发送解封命令
_delay_ms (1000);//暂停以进行处理

//步骤2:如有必要、发送完全访问命令(0xFFFF)
write16bitRegister (MANUFACTURER_ACCESS_REG、0xFFFF);//发送完全访问命令
_delay_ms (1000);//暂停以进行处理

SEND_AT_COMMAND ("已发送解锁命令。 正在验证状态...");

//尝试解锁后验证状态
verifyDeviceStatus();//在控制台上显示新状态
其他{
send_at_command ("设备已解锁。");
}
}

void writeToDataFlash (uint16_t address、uint16_t value1、uint16_t value2){
uint8_t 校验和;
uint8_t macData[4];
uint8_t sum = 0;

//以小端字节序将地址写入 ManufacturerAccessControl (0x3E、0x3F)
write16bitRegister (Manufacturer_access_REG、address);//将地址0x4000写入 ManufacturerAccessControl
_delay_ms (500);//暂停以进行处理

//以大端字节序将数据写入 MACData (0x40–0x43)
macData[0]=(value1 >> 8)& 0xFF;// value1的高字节
macData[1]= Value1 & 0xFF;// value1的低字节
macData[2]=(value2 >> 8)& 0xFF;// value2的高字节
macData[3]= value2 & 0xFF;// value2的低字节

//将4字节的数据写入 MACData
TWI_BQWrite (0x40、macData[0]、macData[1]);//写入前两个字节(0x40-0x41)
TWI_BQWrite (0x42、macData[2]、macData[3]);//写入后两个字节(0x42-0x43)
_delay_ms (500);//暂停以进行处理

//计算校验和:ManufacturerAccessControl 和 MACData 之和的补码
sum +=(address & 0xFF);//地址的低字节
sum +=(地址>> 8)& 0xFF;//地址的高字节
sum += macData[0];//数据之和
sum += macData[1];
sum += macData[2];
sum += macData[3];
校验和=~sum + 1;//二进制补码

//将校验和写入 MACDataSum (0x60)
TWI_BQWrite (0x60、CHECKSUM、0x00);//写入校验和
_delay_ms (500);//暂停以进行处理

//将数据长度写入 MACDataLen (0x61)
TWI_BQWrite (0x61、0x08、0x00);//总长度:4 + MACData 的长度
_delay_ms (500);//暂停以进行处理
}

void changeCCGainValue (){
uint16_t new_value1 = 0x1234;//要写入的第一个值(十六进制0x1234)
uint16_t new_value2 = 0x5678;//要写入的第二个值(十六进制0x5678)

unlockDevice();//确保设备已解锁

_delay_ms (1000);

//调用该函数以写入位于地址0x4000的 DataFlash
writeToDataFlash (0x4000、NEW_VALUE1、NEW_VALUE2);

//向控制台发送消息以进行确认
SEND_AT_COMMAND ("写入 CC 增益的新值:0x1234和0x5678");
}

主页:

_delay_ms(3000);  

SEND_AT_COMMAND ("读取 CC 增益值...");

displayCCGainOnConsole ();

_delay_ms (1000);  

send_at_command ("更改 CC 增益值...");

changeCCGainValue();

_delay_ms(3000);  

谢谢你。 祝你一切顺利

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

    Christian、您好!

    您能否尝试更改不同寄存器的值、仅查看该过程是否可在单独的寄存器上进行。 我建议尝试更改任何 Manufacturer Info Block 寄存器中的值。

    此致、

    Adrian

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

    您好、Adrian、

    我已经尝试写入制造商块,特别是在地址0x4040 ,但同样的事情不断发生,注册表值没有更新。 使用的代码如下:

    void readManufacturerBlock (uint16_t 地址){
    字符缓冲器[10];

    //步骤1:将地址写入 ManufacturerAccessControl (0x3E)
    escribirRegister16bits (manufacturer_access_REG、address);//设置要读取的地址
    _delay_ms (500);//暂停以进行处理

    //步骤2:从 MACData 读取4个字节(0x40–0x43)
    lecturaTWI_BQ (0x40、4);//从 MACData 读取4个字节(0x40–0x43)

    //步骤3:将字节组合成两个16位值(大端字节序格式)
    uint16_t value1 =(twi_data_buffer[1]<< 8)| twi_data_buffer[0];//前2个字节(小端字节序到大端字节序)
    uint16_t value2 =(twi_data_buffer[3]<< 8)| twi_data_buffer[2];//最后2个字节(小端字节序到大端字节序)

    //步骤4:将值打印到控制台
    enviar_comando_at ("制造商块值:");

    //转换并打印第一个值
    itoa (value1、缓冲器、16);//转换为十六进制
    enviar_comando_at ("0x");
    enviar_comando_at (buffer);
    enviar_comando_at (");

    //转换并打印第二个值
    itoa (value2、缓冲器、16);//转换为十六进制
    enviar_comando_at ("0x");
    enviar_comando_at (buffer);
    enivar_comando_at ("\r\n");//格式化换行符
    }

    void changeManufacturerInfoBlock(){
    uint16_t new_value1 = 0xAAAA;//要写入的第一个值(十六进制的0xAAAA)
    uint16_t new_value2 = 0xBBBB;//要写入的第二个值(十六进制的0xBBBB)

    desbloquearDispositivo();//确保设备已解锁

    _delay_ms (1000);

    //步骤1:从制造商信息块中读取并打印当前值
    enviar_comando_at ("写入前读取制造商块...");
    readManufacturerBlock (0x4040);//读取并打印当前值

    _delay_ms (1000);

    //步骤2:将新值写入地址0x4040处的制造商信息块
    enviar_comando_at ("将新值写入制造商块...");
    writeManufacturerBlock (0x4040、NEW_VALUE1、NEW_VALUE2);//使用您的函数

    _delay_ms (1000);

    //步骤3:从制造商信息块中读取并打印新值
    enviar_comando_at ("写入后读取制造商块...");
    readManufacturerBlock (0x4040);//读取并打印新值
    }


    void writeManufacturerBlock (uint16_t address、uint16_t value1、uint16_t value2){
    uint8_t 校验和;
    uint8_t macData[4];
    uint8_t sum = 0;

    //步骤1:以小端字节序格式将地址写入 ManufacturerAccessControl (0x3E)
    escribirRegister16bits (Manufacturer_access_REG、address);//将该地址写入 ManufacturerAccessControl
    _delay_ms (500);//暂停以进行处理

    //步骤2:以大端字节序格式将数据写入 MACData (0x40–0x43)
    macData[0]=(value1 >> 8)& 0xFF;// value1的高字节
    macData[1]= Value1 & 0xFF;// value1的低字节
    macData[2]=(value2 >> 8)& 0xFF;// value2的高字节
    macData[3]= value2 & 0xFF;// value2的低字节

    //将前两个字节写入 MACData (0x40–0x41)
    escrituraTWI_BQ (0x40、macData[0]、macData[1]);

    //将接下来的两个字节写入 MACData (0x42–0x43)
    escrituraTWI_BQ (0x42、macData[2]、macData[3]);
    _delay_ms (500);//暂停以进行处理

    //步骤3:计算校验和(ManufacturerAccessControl 和 MACData 的补码)
    sum +=(address & 0xFF);//地址的低字节
    sum +=(地址>> 8)& 0xFF;//地址的高字节
    sum += macData[0];//添加数据
    sum += macData[1];
    sum += macData[2];
    sum += macData[3];
    校验和=~sum + 1;//二进制补码

    //步骤4:将校验和写入 MACDataSum (0x60)
    escrituraTWI_BQ (0x60、checksum、0x00);//写入 checksum
    _delay_ms (500);//暂停以进行处理

    //步骤5:将数据长度写入 MACDataLen (0x61)
    escrituraTWI_BQ (0x61、0x08、0x00);//总长度:4字节数据+ 4 (总计8个)
    _delay_ms (500);//暂停以进行处理
    }

    主页:

    //尝试读取和写入新值到制造商信息块
    enviar_comando_at ("向/从制造商信息块写入和读取值...");
    changeManufacturerInfoBlock();

    控制台日志:

    在写入之前读取制造商块...
    制造商块值:
    0x
    0

    0x
    0


    正在将新值写入制造商块...
    写入后读取制造商块...
    制造商块值:
    0x
    0

    0x
    0

    谢谢你。

    此致。

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

     Christian、您好!

    您是否能够使用 BQStudio? 这有助于调试代码。 在对器件进行写入和读取时、您是否能够共享通信线路的数字逻辑捕获?

    此致、

    Adrian