📄 x24c04.c
字号:
/***********************************************************************************************************
2008.4.27 首次完成调试
X24C系列芯片离线专用编程器 V1.0版 凹凸编制!!!
调试单片机:STC89C51RC
工作频率:11.0592MHZ
2008.4.28
由于受单片机容量限制,改用89C52,须将容量限制在8K以内
在1.0的基础上对数据容量进行了128字节压缩,对相同的128字节数据进行重复利用
X24C系列芯片离线专用编程器 V1.01版 凹凸编制!!!
2008.4.28
在1.01的基础上对按键防抖进行改进
X24C系列芯片离线专用编程器 V1.11版 凹凸编制!!!
2008.4.28
在1.11的基础上对蜂鸣器进行改进,以支持非自带音频发生器的蜂鸣器和普通喇叭
X24C系列芯片离线专用编程器 V1.21版 凹凸编制!!!
***********************************************************************************************************/
#include "reg52.h"
#include <stdio.h>
#include<intrins.h>
sbit K3=P3^3;//按键3,芯片选择
sbit K2=P3^4;//按键3,写芯片
sbit K1=P3^5;//按键3
sbit BELL=P1^1;//蜂鸣器
//sn[0]~sn[4]为5位从高位到低位序列号;sn[5]为序列号校验码;
//sn_address1是序列号防掉电备份器件地址;sn_address2是序列号防掉电备份数据地址
//sn_address3是写入序列号器件地址;sn_address4是写入序列号数据地址
unsigned char sn[6],sn_address1,sn_address2,sn_address3,sn_address4;
//zz_code代码开始地址指针;
unsigned char code *zz_code,*zz_code1,*zz_code2,*zz_code3,*zz_code4;
//jy_code代码校验数据
unsigned int jy_code;
/*************************************************************************************************************/
/*************************************************************************************************************/
/*************************************************************************************************************/
////////串口初始化
//
void rs232reset(void)
{
SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x20; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80; //SMOD=1;
TH1 = 0xFF; //Baud:57600 fosc=11.0592MHz
IE |= 0x90; //Enable Serial Interrupt
TR1 = 1; // timer 1 run
TI = 1;
printf("\nX24C系列芯片离线专用编程器 V1.21版 凹凸编制!!!\n\n");
}
/*************************************************************************************************************/
/*************************************************************************************************************/
/*************************************************************************************************************/
/////////24C08读写驱动程序////////////////////
sbit scl=P3^7; //24c08 SCL
sbit sda=P3^6; //24c08 SDA
void delay1(unsigned int x)
{ unsigned int i;
for(i=0;i<x;i++);
;}
void flash()
{;;}
void x24c08_init() //24c08初始化子程序
{scl=1; flash(); sda=1; flash();}
void start() //启动I2C总线
{sda=1; flash(); scl=1; flash(); sda=0; flash(); scl=0; flash();}
void stop() //停止I2C总线
{sda=0; flash(); scl=1; flash(); sda=1; flash();}
void writex(unsigned char j) //写一个字节
{ unsigned char i,temp;
temp=j;
for (i=0;i<8;i++)
{temp=temp<<1; scl=0; flash(); sda=CY; flash(); scl=1; flash();}
scl=0; flash(); sda=1; flash();
}
unsigned char readx() //读一个字节
{
unsigned char i,j,k=0;
scl=0; flash(); sda=1;
for (i=0;i<8;i++)
{ flash(); scl=1; flash();
if (sda==1) j=1;
else j=0;
k=(k<<1)|j;
scl=0;}
flash(); return(k);
}
void clock() //I2C总线时钟
{
unsigned char i=0;
scl=1; flash();
while ((sda==1)&&(i<255))i++;
scl=0; flash();
}
////////从24c02的地址address中读取一个字节数据/////
//器件地址_address1;数据地址_address2;
unsigned char x24c08_read(unsigned char address1,unsigned char address2)
{
unsigned char i;
EA=0;
start(); writex(address1&0xfe);
clock(); writex(address2);
clock(); start();
writex(address1|0x01); clock();
i=readx(); stop();
EA=1;
delay1(10);
return(i);
}
//////向24c02的address地址中写入一字节数据info/////
//器件地址_address1;数据地址_address2;要写入的数据_info;
void x24c08_write(unsigned char address1,unsigned char address2,unsigned char info)
{
EA=0;
start(); writex(address1);
clock(); writex(address2);
clock(); writex(info);
clock(); stop();
EA=1;
delay1(350);
}
/*************************************************************************************************************/
/*************************************************************************************************************/
/*************************************************************************************************************/
////////连续写入128字节数据///////////////////////////////////////////////////////////////////////////////////////////
//
x24c08_write128(unsigned char address1,unsigned char address2)
{
unsigned char loop;
for(loop=0;loop<0x80;loop++)
{
x24c08_write(address1,address2+loop,*(zz_code+loop));//在24c08的地址中连续写入数据
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////显示x24c04数据///////////////////////////////////////////////////////////////////////////////////////////
//
void x24c04_read_all()
{
unsigned char loop,loop0,tmp;
for(loop0=0;loop0<=0x0f;loop0++)
{
printf("00%BX0: ",loop0);
for(loop=0;loop<=0x0f;loop++)
{
tmp=x24c08_read(0xa0,(loop0<<4)+loop);//读出保存的数据赋于tmp
printf("%BX ",tmp);
}
printf("\n");
}
printf("\n\n");
delay1(50000);delay1(50000);delay1(50000);delay1(50000);delay1(50000);//延时
for(loop0=0;loop0<=0x0f;loop0++)
{
printf("01%BX0: ",loop0);
for(loop=0;loop<=0x0f;loop++)
{
tmp=x24c08_read(0xa2,(loop0<<4)+loop);//读出保存的数据赋于tmp
printf("%BX ",tmp);
}
printf("\n");
}
printf("\n\n");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*************************************************************************************************************/
/*************************************************************************************************************/
/*************************************************************************************************************/
////////蜂鸣器///////////////////////////////////////////////////////////
//鸣响时长_sc
fmq(unsigned int sc)
{
unsigned char i;
while(sc--)
{
BELL=0;
i=55;while(i)i--;
BELL=1;
i=47;while(i)i--;
}
}
/*************************************************************************************************************/
/*************************************************************************************************************/
/*************************************************************************************************************/
////////序列号写入///////////////////////////////////////////////////////////////////////////////////////////
//序列号写入器件地址_address1;序列号写入数据地址_address2;放掉电序列号保存地址_address3
sn_write()
{
unsigned char i,loop,sn_temp[5];
for(loop=0;loop<5;loop++)sn_temp[loop]=sn[loop]&0x0f;//屏蔽序列号的高四位,并暂存sn_temp[]
//BCD码计数器
i=4;
sn_temp[i]=sn_temp[i]+1;
for(loop=0;loop<8;loop++)
{
if(sn_temp[i]>9){sn_temp[i]=0;i--;sn_temp[i]=sn_temp[i]+1;}
}
//序列号计数器溢出报警
if(sn_temp[0]==9)
{
while(1)
{
printf("序列号计数器溢出,请联系工程人员解决.\n\n");
//BELL=0;i=60000;while(i>0)i--;i=40000;while(i>0)i--;
//BELL=1;BELL=1;i=60000;while(i>0)i--;
fmq(3000);
i=6000;while(i>0)i--;
}
}
for(loop=0;loop<5;loop++)sn[loop]=sn_temp[loop]+0x30;//BCD码转ASCII,并存回sn[]
sn[5]=sn[0]+sn[1]+sn[2]+sn[3]+sn[4];//计算序列号校验和
for(loop=0;loop<5;loop++) x24c08_write(sn_address3,loop+sn_address4,sn[loop]);//向新芯片中写入序列号
for(loop=0;loop<6;loop++) x24c08_write(sn_address1,loop+sn_address2,sn[loop]);//保存序列号和序列号校验码,防止掉电丢失
printf("芯片序列号:%c%c%c%c%c\n\n",sn[0],sn[1],sn[2],sn[3],sn[4]);//输出序列号到显示器
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////序列号数据初始化///////////////////////////////////////////////////////////////////////////////////////////
//
sn_csh()
{
unsigned char loop,temp;
unsigned int i;
printf("初始化序列号中\n\n");
for(loop=0;loop<6;loop++) sn[loop]=x24c08_read(sn_address1,loop+sn_address2);//读取序列号/序列号检验和/
//校验序列号的正确性
temp=sn[0]+sn[1]+sn[2]+sn[3]+sn[4];
if((temp==sn[5]))printf("成功读取系列号: %BX %BX %BX %BX %BX %BX \n\n",sn[0],sn[1],sn[2],sn[3],sn[4],sn[5]);
else{printf("读取序列号时出错,请对编程器复位或联系工程人员\n\n");
//BELL=0;i=60000;while(i>0)i--;i=40000;while(i>0)i--;BELL=1;BELL=1;
fmq(3000);
i=60000;while(i>0)i--;
//BELL=0;i=60000;while(i>0)i--;i=40000;while(i>0)i--;BELL=1;BELL=1;
fmq(3000);
i=60000;while(i>0)i--;
//BELL=0;i=60000;while(i>0)i--;i=40000;while(i>0)i--;BELL=1;BELL=1;
fmq(3000);
while(1);while(1);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////编程函数///////////////////////////////////////////////////////////////////////////////////////////
//
bc()
{
//unsigned long i0;
unsigned int i0,i,tmp_jy=0;//延时计数器; 临时校验和;
unsigned char tmp_k1,loop;//编程按键状态位; 计数器;
sn_csh();//序列号数据初始化
while(1)
{
printf("请安装好芯片后,按下选择/编程键启动编程器\n\n");
while(tmp_k1==0)
{
i0=0;while(K1==0){i0++;if(i0>500)tmp_k1=1;else tmp_k1=0;}//按键防抖,按键检测
//while(K1==0){while(K1==0);tmp_k1=1;}
}
while(tmp_k1)
{
//编程开始
tmp_k1=0;
//x24c04_read_all();//读芯片
printf("编程中\n\n");
zz_code=zz_code1;
x24c08_write128(0xa0,0x00);
zz_code=zz_code2;
x24c08_write128(0xa0,0x80);
zz_code=zz_code3;
x24c08_write128(0xa2,0x00);
zz_code=zz_code4;
x24c08_write128(0xa2,0x80);
sn_write();//写入系列号
//x24c04_read_all();//读芯片
printf("校验中\n\n");
tmp_jy=0;//校验变量归零
for(loop=0;loop<=127;loop++)tmp_jy=tmp_jy+x24c08_read(0xa0,0x00+loop);
for(loop=0;loop<=127;loop++)tmp_jy=tmp_jy+x24c08_read(0xa0,0x80+loop);
for(loop=0;loop<=127;loop++)tmp_jy=tmp_jy+x24c08_read(0xa2,0x00+loop);
for(loop=0;loop<=127;loop++)tmp_jy=tmp_jy+x24c08_read(0xa2,0x80+loop);
printf("校验码=0x%X\n\n",tmp_jy);
if(!(tmp_jy-(jy_code+(sn[5]-0xf0))))
{
printf("校验成功\n\n");
//BELL=0;i=20000;while(i>0)i--;BELL=1;
fmq(300);
}
else
{
printf("校验失败\n\n");
//BELL=0;i=60000;while(i>0)i--;i=40000;while(i>0)i--;BELL=1;BELL=1;
fmq(3000);
i=60000;while(i>0)i--;
//BELL=0;i=60000;while(i>0)i--;i=40000;while(i>0)i--;BELL=1;BELL=1;
fmq(3000);
i=60000;while(i>0)i--;
//BELL=0;i=60000;while(i>0)i--;i=40000;while(i>0)i--;BELL=1;BELL=1;
fmq(3000);
}
}//编程完成
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -