#include<reg52.h>
#include<intrins.h>
#define _Nop()_nop_() // 延时1us
sbit SDA=P1^3; // 定义SDA
sbit SCL=P1^2; // 定义SCL
sbit pwr=P3^5; // 供电
unsigned char data GPA[20]; //GPA 单元使用频率高,应直接寻址
unsigned char idata rwdata[0x14];//min=0x04(不读写) max=0x0c(读最大字节数为0x20H,写最大为0x10H)
//前4字节用做命令,数据存放在rwdata[0x04]=>rwdata[0x13]
//参数也可分配成0x0C,但后面一次只能读写8字节数据
//所有从器件解密出的数据和写入器件的数据暂放在此
//******************请填写GC************************************
//GC_TABLE:
unsigned char code GC0[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//GC0
unsigned char code GC1[]={0x00,0x00,0x06,0x09,0x02,0x06,0x16,0x00};//GC1
unsigned char code GC2[]={0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11};//GC2
unsigned char code GC3[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//GC3
//******************请填写PASSWORD************************************
//PASSWORD_TABLE:
unsigned char code PW_WRITE0[]={0x80,0x00,0x00};//WRITE PASSWORD 0
unsigned char code PW_READ0[]= {0x00,0x00,0x00};//READ PASSWORD 0
unsigned char code PW_WRITE1[]={0x11,0x00,0x11};//WRITE PASSWORD 1
unsigned char code PW_READ1[]= {0x00,0x00,0x00};//READ PASSWORD 1
unsigned char code PW_WRITE2[]={0x00,0x00,0x00};//WRITE PASSWORD 2
unsigned char code PW_READ2[]= {0x00,0x00,0x00};//READ PASSWORD 2
unsigned char code PW_WRITE3[]={0x00,0x00,0x00};//WRITE PASSWORD 3
unsigned char code PW_READ3[]= {0x00,0x00,0x00};//READ PASSWORD 3
unsigned char code PW_WRITE4[]={0x22,0x22,0x22};//WRITE PASSWORD 4
unsigned char code PW_READ4[]= {0x22,0x22,0x22};//READ PASSWORD 4
unsigned char code PW_WRITE5[]={0x00,0x00,0x00};//WRITE PASSWORD 5
unsigned char code PW_READ5[]= {0x00,0x00,0x00};//READ PASSWORD 5
unsigned char code PW_WRITE6[]={0x00,0x00,0x00};//WRITE PASSWORD 6
unsigned char code PW_READ6[]= {0x00,0x00,0x00};//READ PASSWORD 6
unsigned char code PW_WRITE7[]={0xdd,0x42,0x97};//WRITE PASSWORD 7
unsigned char code PW_READ7[]= {0x00,0x00,0x00};//READ PASSWORD 7
void SMSTART(void);//功能:启动I2C
void SMSTOP(void); //功能:停止I2C
void delay_ms(); //功能:延时1ms
void Wait_For_AckPolling(void);
//功能:检查所发送的命令是否已被执行
//只有当AckPolling_return=1或bytecounter=0时,该程序才退出
void GPA_CLOCK(unsigned char Datain,unsigned char times);
//GPA函数
//入口:Data_in
//出口:GPA[0]:GPA_byte
//参数:times GPA函数计算的次数
void read(rd);
//功能:对at88scxx I2C读操作函数
//本程序中以read(rwdata)调用;
//入口:rwdata数组
//出口:rwdata数组
//rd数组长度可改
//cmd_send_counter发送命令次数,超出8次,本函数退出,并认为I2C线路上无器件
void write(SDATA);
//功能:对at88scxx I2C写操作函数
//本程序中以write(rwdata)调用;
//入口:rwdata数组
//出口:rwdata数组
//rd数组长度可改
//cmd_send_counter发送命令次数,超出8次,本函数退出,并认为I2C线路上无器件
unsigned char AUTHENTICATION(unsigned char GC_select);
//双向认证函数
//入口:GC_select:选择密钥套数
//出口:AAC: 认证结果
//过程:
//1.从器件读出CIx,产生随机数Q0,计算密钥;计算出Q1,将Q0、Q1发送给器件,计算出新的CIx,SKx
//2.用读回的CIx与计算出的CIx比较
//3.用计算出的SKx替代GCx,重复1过程
//AAC:认证错误计数器.AAC!=0xff表示双向认证未通过或无器件
//需产生随机数则应在程序里修改
unsigned char verify_write_password(unsigned char pw_select);
//校验写密码组主函数,正确校验了写密码后开放读写
//pw_select:密码套数选择
//PAC:密码校验错误计数器.PAC!=0xff表示认证未通过或无器件
void set_user_zone(unsigned char zone);
//选择用户区
//zone:用户区序号
void read_user_zone(unsigned char idata rd_high_addr,unsigned char idata rd_low_addr,unsigned char idata rd_number);
//读出用户区密文数据,并解出明文数据
//rd_high_addr 用户区高字节地址
//rd_low_addr 用户区低字节地址
//rd_number 读取密文数据及解出明文数据的个数
//解密出的明文数据存放在rwdata[0x04]=>rwdata[0x13]
void read_config_zone(unsigned char idata rd_high_addr,unsigned char idata rd_low_addr,unsigned char idata rd_number);
//当rd_low_addr往后不应滚动到0xb0
//如想读 0xb0<rd_low_addr<0xef 单元则应重新调用
void encrypto_data(unsigned char encryptodatanumber);
//对明文数据进行加密
//encryptodatanumber加密数据的个数
//需加密的明文数据存放在 rwdata[4]至rwdata[0x13]
void write_user_zone(unsigned char wr_high_addr,unsigned char wr_low_addr,unsigned char wr_number);
//功能:把已加密了的密文数据写到器件
//wr_high_addr 用户区高字节地址
//wr_low_addr 用户区低字节地址
//wr_number 写入数据的个数
//将存放在 rwdata[4]至rwdata[0x13]明文数据写入器件
void send_checksum();
//功能:发送校验和到器件(以密文形式写入数据后,需发送校验和)
void write_config_zone(unsigned char wr_high_addr,unsigned char wr_low_addr,unsigned char wr_number);
//当rd_low_addr往后不应滚动到0xb0
//如想读 0xb0<rd_low_addr<0xef 单元则应重新调用
//熔丝断后不可写
//****************明文读写部分******************************
unsigned char verify_sc_plaintext(unsigned char sc_first_byte,unsigned char sc_second_byte,unsigned char sc_third_byte);
//功能:校验安全密码(传输密码),该密码位置在write7_password
//在器件熔丝未断前,校验安全密码成功后,可以对器件配置区,用户区的随意读写
//sc_firsr_byte 密码的第1个字节数据
//sc_second_byte 密码的第2个字节数据
//sc_third_byte 密码的第3个字节数据
//如verify_sc_plaintext(0xDD,0x42,0x97)
//0xDD,0x42,0x97分别为密码的第123个字节数据
void set_user_zone_plaintext(unsigned char zonep);
//选择用户区(明文)
//zonep:用户区序号
void read_paintext(unsigned char rd_cmd,unsigned char A1,unsigned char A2,unsigned char N);
//读操作(明文)
//rd_cmd:0xb2 读用户区 /0xb6 读配置区 /0xb6 0x01 0x00 0x01 读熔丝
//A1 :高字节地址
//A2 :地字节地址
//N :读取数据个数
void write_paintext(unsigned char wr_cmd,unsigned char A1,unsigned char A2,unsigned char N);
//写操作(明文)
//rd_cmd:0xb0 写用户区 /0xb4 写配置区 /0xb4 0x01 ID 0x00 写熔丝
//A1 :高字节地址
//A2 :地字节地址
//N :写数据个数
//注意:烧断熔丝时只能从ID=0x06=>0x04=>0x00
////////////////////////////////////////
void main()
{
unsigned char data j;
unsigned char idata PAC_WR7;//PAC_WR7=0xFF则表明校验SC正确
unsigned char idata AAC; //AAC=0xFF则表明校验GCx正确
unsigned char idata PAC; //PAC=0xFF则表明校验PWx正确
pwr=0; //上电
AAC=0;
PAC=0;
//goto MTZ_Test;
//goto Set_AAC_PAC_FF;
//goto RW_Config_User_Zone_Plaintext;
//goto RW_User_Zone_Encryptoed;
//goto RW_Config_Zone_Encryptoed;
////////////////////密文读写部分////////////////////////////////////////
RW_User_Zone_Encryptoed:
AAC=AUTHENTICATION(0x02); //0x02使用02套密钥
评论1