金南京 发表于 2026-3-21 20:18:54

这是一个ID号加密判断的程序,不知道问题出在哪里了,请高手老师帮忙看一下,谢谢!

#include <stc8h.h>
#include <intrins.h>

sbit S1 = P1^0;

// 类型重定义,增强代码可读性
typedef unsigned char u8;
typedef unsigned int u16;

// 修复:数组初始化必须用{},否则会编译警告/错误
u8 chip_id = {0};// 存储读取到的7字节芯片ID
u16 enc_sum = 0;      // 重命名:enc_num -> enc_sum,语义更清晰

// 200ms延时函数(@24.000MHz)
void Delay200ms(void)       
{
    unsigned char data i, j, k;
    _nop_();
    _nop_();
    i = 25;
    j = 90;
    k = 176;
    do
    {
      do
      {
            while (--k);
      } while (--j);
    } while (--i);
}

// ========== 需根据实际芯片ID修改以下宏定义 ==========
// !!!重要:需先读取自己芯片的真实ID替换以下值!!!
#define RAW_ID_0    0xf7// 芯片真实ID第0字节
#define RAW_ID_1    0x84// 芯片真实ID第1字节
#define RAW_ID_2    0xc9// 芯片真实ID第2字节
#define RAW_ID_3    0xb9// 芯片真实ID第3字节
#define RAW_ID_4    0x03// 芯片真实ID第4字节
#define RAW_ID_5    0x48// 芯片真实ID第5字节
#define RAW_ID_6    0x62// 芯片真实ID第6字节
#define AUTH_KEY    0x3f// 加密密钥(可自定义,建议0x01~0xFE)

// 读取芯片ID(STC8H的芯片ID固定地址:0xFDE0~0xFDE6)
void Read_ChipID(void)
{
    u8 i;
    // xdata修饰符:访问外部数据存储器(STC8H的ID存储在此区域)
    u8 *p = (u8 xdata *)0xFDE0;
    for(i = 0; i < 7; i++)
    {
      chip_id = *p++; // 逐字节读取ID到全局数组
    }
}

// 加密函数:异或密钥 + 计算校验和
// 参数说明:
//   chip_id:输入-原始芯片ID
//   enc_id:输出-加密后的ID
//   sum:输出-加密后ID的校验和
void EncryptID(u8 *chip_id, u8 *enc_id, u16 *sum)
{
    u8 i;
    *sum = 0; // 初始化校验和

    for(i=0; i<7; i++)
    {
      enc_id = chip_id ^ AUTH_KEY; // 异或加密核心逻辑
      *sum += enc_id;               // 累加计算校验和
    }
}

// ID校验函数:比对加密后的数据和校验和
// 返回值:1=合法,0=非法
u8 CheckChipID(void)
{
    u8 enc_id;      // 存储读取ID加密后的值
    u16 read_sum = 0;    // 存储读取ID加密后的校验和
    u8 i;                // 【关键修复】提前定义循环变量(C51要求)

    // 计算预设ID加密后的值和校验和
    u8 auth_id = {
      RAW_ID_0 ^ AUTH_KEY,
      RAW_ID_1 ^ AUTH_KEY,
      RAW_ID_2 ^ AUTH_KEY,
      RAW_ID_3 ^ AUTH_KEY,
      RAW_ID_4 ^ AUTH_KEY,
      RAW_ID_5 ^ AUTH_KEY,
      RAW_ID_6 ^ AUTH_KEY
    };
    u16 auth_sum = auth_id + auth_id + auth_id +
                   auth_id + auth_id + auth_id + auth_id;

    Read_ChipID();                  // 读取芯片真实ID
    EncryptID(chip_id, enc_id, &read_sum); // 加密并计算校验和

    // 【关键修复】循环变量i已提前定义,符合C51语法
    for(i=0; i<7; i++)
    {
      if(enc_id != auth_id)
      {
            return 0; // 任意一字节不匹配,直接返回非法
      }
    }

    // 校验和二次比对(双重验证)
    if(read_sum == auth_sum)
    {
      return 1; // ID合法
    }
    else
    {
      return 0; // 校验和不匹配,非法
    }
}

void main(void)
{
    u8 id_valid;

    // GPIO初始化:P1^0推挽输出(驱动LED)
    P1M0 = 0x01;// P1.0推挽输出模式(bit0置1)
    P1M1 = 0x00;// P1.0推挽输出模式(bit0置0)
    S1 = 1;       // 初始置高(LED灭,假设LED共阳接法)

    // 执行ID校验
    id_valid = CheckChipID();

    if(id_valid)
    {
      // ID合法:LED闪烁(200ms亮/200ms灭)
      while(1)
      {
            S1 = 0;
            Delay200ms();
            S1 = 1;
            Delay200ms();
      }
    }
    else
    {
      // ID非法:LED常亮
      S1 = 0;
      while(1); // 死循环
    }
}

乘风飞扬 发表于 2026-3-23 00:26:26

先确认你选择的芯片系列ID号存放位置在哪里。
有CHIPID寄存器的芯片存放在CHIPID寄存器,没有CHIPID寄存器的芯片在ROM指定地址读取。


参考附件例子先用串口打印正确的ID号数据,以及ID号加密结果

金南京 发表于 2026-3-23 13:04:12

乘风飞扬 发表于 2026-3-23 00:26
先确认你选择的芯片系列ID号存放位置在哪里。
有CHIPID寄存器的芯片存放在CHIPID寄存器,没有CHIPID寄存器 ...

谢谢乘风老师

金南京 发表于 2026-3-23 20:36:45

金南京 发表于 2026-3-23 13:04
谢谢乘风老师

乘风老师,对ID号加密基本上已经了解了,已经用于程序加密上了;忙了好几天,终于在你的大力帮助下解决了,非常之感谢!谢谢尽心尽力的支持!
页: [1]
查看完整版本: 这是一个ID号加密判断的程序,不知道问题出在哪里了,请高手老师帮忙看一下,谢谢!