数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 1411|回复: 13

[手持表] 不用编程器&来回拆焊写个程序读写DTM0660/HY12P66之流的存储芯片

[复制链接]
发表于 2025-7-25 00:42:46 | 显示全部楼层 |阅读模式




一个破表,Victor的VC9801A+  PCB标:2013-07-09 9801(V0.7)
安装的EEPROM是: 丝印T24C08A 13SD2

原来发过帖,DCV档不切换档位,数值就不变。
板印HY12P66,正好拿来练手改9999。

编程器不爱用,每次得拆焊,感觉老费劲了,买了一个就不知道仍哪去了。

直接上Arduino Uno,空机连接AT24C08.
用Nano也可以,不过Uno自带单独的I2C接口,用起来方便多了。

接线:
Uno     AT24C08
----      -----------
3.3V    #8:Vcc
GND    #4:GND
SCL     #6: SCL
SDA     #5: SDA

另外24C08的WP脚要连到GND上,才能对存储器进行写入,不过这样表会进入校准状态,
需要写完后再断开。

这个表没有把上面的除供电外的接口引出,所以还是需要焊上几根引线,再杜邦线连到Uno板子上。

结果:
1. 单独某地址读出成功。
2. 全部到处成功,由于串口打印导出为文本格式,还需要另外的程序转换为二进制bin文件。
   写了个python程序搞定。已经能在大神的《万用表校准编辑器》中打开了。
   不过还是有很多的未知项,以后再研究。
3. 改写某个地址的单字节数据成功。




直接贴代码:
// ================= 代码开始 ==================

/*
型号       容量       器件寻址字节(8位)   一次装载字节数 (页长度)
AT24C08    1024×8    1010A2P1P0 R/W     16
外壳:VC9801A+  PCB标:2013-07-09 9801(V0.7)
安装的EEPROM是: 丝印T24C08A 13SD2*/
#include <Wire.h>

const byte DEVADDR = 0x50;

#include <Arduino_FreeRTOS.h>
#include <semphr.h>
#include <Wire.h>
#define SP  Serial.print
#define SPL Serial.println

void TaskSerial( void *pvParameters );
void TaskBlink ( void *pvParameters );

SemaphoreHandle_t activateActuatorSem;

char serin[64];
unsigned int iser = 0;

void setup() {
  Wire.begin();
  Serial.begin(19200);
  while (!Serial) {;}
  SPL(F("\n\n<OSSER24C08>"));
  pinMode(LED_BUILTIN, OUTPUT);
  
  activateActuatorSem = xSemaphoreCreateBinary();
  if ( activateActuatorSem != NULL ) {
    xSemaphoreGive( activateActuatorSem );  
  }
  xTaskCreate(TaskBlink, "LED", 128, NULL, 2, NULL);
  xTaskCreate(TaskSerial, "SER", 128, NULL, 1, NULL);
}

void loop() {}

void TaskSerial( void *pvParameters ) {
  (void) pvParameters;
  
  for (;;) {   
    if(Serial.available()>0){
      char c = Serial.read();
      if (c == '\n' || iser > 60) {
        serin[iser]='\0';
        SP(serin);
        iser = 0;
        Process_SerIN();
        xSemaphoreGive(activateActuatorSem);
      } else {
        serin[iser++] = c;
      }
    }
    vTaskDelay( 250 / portTICK_PERIOD_MS );
  }
}

void TaskBlink(void *pvParameters) {
  (void) pvParameters;
  for (;;) {
    xSemaphoreTake(activateActuatorSem, portMAX_DELAY);
    SPL(F("/LED"));
    for (byte lp=0;lp<5;lp++){
      digitalWrite(LED_BUILTIN, HIGH);  
      vTaskDelay( 250 / portTICK_PERIOD_MS );
      digitalWrite(LED_BUILTIN, LOW);
      vTaskDelay( 250 / portTICK_PERIOD_MS );
    }
  }
}

void Process_SerIN(){
  if(serin[0]=='d' && serin[1]=='u' && serin[2]=='m' && serin[3]=='p'){
    SPL("=D:");
    eeprom_dump(DEVADDR, 0, 512);
    SPL();
    return;
  }

  // read a byte
  if(serin[0]=='r' && serin[1]=='e' && serin[2]=='a' && serin[3]=='d'){
    SP("=R:&");
    unsigned int ii=4;
    for (ii=4;ii<9;ii++){
      if (serin[ii] == '\0'){
        if ((ii-4)%2 !=0){
          SPL(F("BadDataAddr"));
          return;
        } else {
          break;/
        }
      }
    }
   
    size_t hexStrLen = ii-4;
    unsigned int dataAddr = 0;
    for (size_t i = 0; i < (hexStrLen/2); i++){
       dataAddr = dataAddr*256+composeByteSer(i*2+4);
    }
    SP(dataAddr, HEX);
    byte b = eeprom_read_byte(DEVADDR, dataAddr);
    SP("=");   
    SPL(b, HEX);
    return;
  }

  if(serin[0]=='w'&&serin[1]=='r'&&serin[2]=='i'&&serin[3]=='t'&&serin[4]=='e'){
    SP("=W:&");
    if (!(serin[7] == ' ')){
      SPL(F("BadAddr"));
      return;
    }
    unsigned int dataAddr = 0;
   
    dataAddr = composeByteSer(5);
    SP(dataAddr,  HEX);
    if (serin[7] == ' ' ){
      if( serin[10] != '\0'){
        SP(F("BadVal"));
        return;
      } else {
        dataVal = composeByteSer(8);
      }
    }
    SP("=");
    SPL(dataVal,  HEX);

    // 04. Write the data
    byte b = eeprom_read_byte(DEVADDR, dataAddr);
    SP(b, HEX); SP("->");delay(50);
   
    eeprom_write_byte(DEVADDR, dataAddr, dataVal);
    delay(50);
   
    b = eeprom_read_byte(DEVADDR, dataAddr);
    SPL(b, HEX);
   
    return;
  }
}

byte composeByteSer(byte i0){
  return (serin[i0]   % 32 + 9) % 25 * 16
       + (serin[i0+1] % 32 + 9) % 25;
}

int eeprom_read_byte(byte at24Addr, unsigned dataAddr) {
   byte rdata = -1;
   byte devAddr = at24Addr | ((dataAddr >> 8) & 0x07);

   Wire.beginTransmission(devAddr);
   Wire.write(int(dataAddr));
   Wire.endTransmission();
   Wire.requestFrom(int(devAddr), 1);
   if (Wire.available()) {
       rdata = Wire.read();
   }
   delay(100);
   return rdata;
}

// buffer 长度需要< 30.
int eeprom_read_buffer(byte deviceaddr, unsigned dataAddr, byte * buffer, byte length) {
   byte devAddr = deviceaddr | ((dataAddr >> 8) & 0x07);
   
   Wire.beginTransmission(devAddr);
   Wire.write(int(dataAddr));
   Wire.endTransmission();

   Wire.requestFrom(devAddr, length);
   int i;
   for (i = 0; i < length && Wire.available(); i++) {
       buffer[i] = Wire.read();
   }
   return i;
}


void eeprom_dump(byte devAddr, unsigned dataAddr, unsigned length) {
   unsigned startAddr = dataAddr & (~0x0f);
   unsigned stopAddr  = (dataAddr + length + 0x0f) & (~0x0f);
   for (unsigned i = startAddr; i < stopAddr; i += 16) {
       byte buffer[16];
       char outbuf[6];
       sprintf(outbuf, "%03x: ", i);
       SP(outbuf);
       eeprom_read_buffer(devAddr, i, buffer, 16);
       for (int j = 0; j < 16; j++) {
           sprintf(outbuf, "%02x ", buffer[j]);
           SP(outbuf);
       }
       SPL();
   }
}

void eeprom_write_byte(byte devAddr0, int dataAddr, byte dataVal) {
   byte devAddr = devAddr0 | ((dataAddr >> 8) & 0x07);
   Wire.beginTransmission(devAddr);
   Wire.write(int(dataAddr));
   Wire.write(int(dataVal));
   Wire.endTransmission();
   delay(10);
}


// ================= 代码结束 ==================



已经成功改成6千字,高级用法还不会.....




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 4家元 +141 收起 理由
steedqn + 7 優秀文章
家睦 + 80
zto中通快递 + 27
jf201006 + 27 謝謝分享

查看全部打赏

发表于 2025-7-25 10:45:21 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-7-25 10:54:51 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2025-7-25 14:21:42 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-7-25 16:04:35 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2025-7-25 18:28:29 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-7-25 19:07:41 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2025-7-25 21:08:16 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-7-31 17:50:49 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2025-8-1 10:18:30 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2025-12-29 11:33:12 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2026-4-25 06:44:55 来自手机浏览器 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2026-4-25 20:00:19 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-4-25 23:16:54 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-4-25 23:21:20 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|数码之家-技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2026-6-1 11:29 , Processed in 0.265200 second(s), 10 queries , Gzip On, Redis On.

Powered by Discuz!

© MyDigit.Net Since 2006

快速回复 返回顶部 返回列表