cpubbs 发表于 2005-11-2 00:07:08

[转帖]P89CXX 编程器51接受程序(dhd0)

<P>转贴自:世纪开发网</P>
<P> </P>
<P>/*P89CXX编程器控制CPU接收和控制程序*/
#include &lt;reg52.h&gt;
#include &lt;intrins.h&gt; </P>


<P>unsigned char time,b_break,b_break_3;
//35.555ms
void int_t0(void) interrupt 1 {
TH0=0;
if ((++b_break_3)&gt;2) b_break=1;
time++;
}</P>
<P>void wait20us(void) {
TL0=180;TH0=0xff;
time=0;
while (!time) {}
}
void wait500ms(void) {
time=0;
while (time&lt;15) {}
}</P>
<P>
unsigned char rec(void) {
TH0=0;b_break_3=0;b_break=0;
while (RI==0) {
if (b_break) return(1);
}
RI=0;
SBUF=SBUF;
return(SBUF);
}</P>
<P>/*返回1表示失败*/
bit sen(unsigned char d) {
SBUF=d;
TH0=0;b_break_3=0;b_break=0;
while (RI==0) {
if (b_break) return(1);
}
RI=0;
if (SBUF!=d) return(1);
return(0);
}</P>
<p>
<P>#define b_init 0</P>
<P>#define b_erase 1
#define b_erase_block 2 //P89C51RC+、P89C51RD+特有
#define b_erase_sbyte_bvec 3 //P89C51RC+、P89C51RD+特有</P>
<P>#define b_read 4</P>
<P>#define b_program_byte 5
#define b_program_sbyte 6 //P89C51RC+、P89C51RD+特有
#define b_program_boot_vector 7 //P89C51RC+、P89C51RD+特有</P>
<P>#define b_lock1 8
#define b_lock12 9
#define b_lock123 10</P>
<P>#define b_cpu 12 //定义需要编程的cpu类型,0:P89C51 1:P89C52 2:P89C54
3:P89C58 4:P89C51RC+ 5:P89C51RD+</P>
<P>sbit p_oe=P3^2;
sbit p_we=P3^3;</P>
<P>//输入控制模式
void mode(unsigned char m) {
P3=(m&lt;&lt;4)|0xf;
}
//输出地址
void out_adds(unsigned int adds) {
P0=adds;
P2=adds/256;
}
//读入地址
unsigned char in_data(void) {
P1=0xff;
p_oe=0;
return(P1);
p_oe=1;
}
//判别cpu类型
unsigned char code un_cpu[]={0xf4,0xff,0xfb,0xf9,0x89,0x80};
unsigned int code un_adds_max[]={4096,8192,16384,32768,32768,0};
unsigned char read_id(void){
unsigned char d;
mode(0xf);
//读Mft ID
out_adds(0);d=in_data();
if (d!=0x15) return(0);
//读Mft ID1
out_adds(1);d=in_data();
if (d!=0xc2) return(0);
//读Mft ID2
out_adds(2);d=in_data();
return(d); //返回Mft ID2
}</P>
<P>//初始化芯片,等效于擦除芯片、擦除加密位等等
bit init(unsigned char cpu) {
unsigned char i,b_error=0;
unsigned int adds,adds_max=un_adds_max;
//写入所有字节全零3次,不校验
mode(3);
P1=0;
adds=0;
do {
out_adds(adds);
for (i=0;i&lt;3;i++) {
p_we=0;
wait20us();
p_we=1;
}
adds++;
} while (adds!=adds_max);
//初始化,校验,3次机会
for (i=0;i&lt;3;i++) {
//初始化
mode(0xe);
p_we=0;
time=0;
while (time&lt;15) {}
p_we=1;
//擦除校验
mode(4);
adds=0;
do {
out_adds(adds);
if (in_data()!=0xff) break;
adds++;
} while (adds!=adds_max);
if (adds==adds_max) break;
}
if (i==3) b_error=1;//擦除错误
else {
mode(9);
out_adds(0);
if (in_data()&amp;0x3) b_error=1;
//P89C51RX专用
if (cpu&gt;3) {
out_adds(1);
if (in_data()) b_error=1;
out_adds(2);
if (in_data()) b_error=1;
}
}
sen(b_error);
return(b_error);
}
//读入
bit read(unsigned char cpu) {
unsigned int adds,adds_max=un_adds_max;
adds=0;
mode(0);
wait20us();
do {
out_adds(adds);
if (sen(in_data())) return(1); //通信出错
adds++;
} while (adds!=adds_max);
return(1); //超出地址范围,错误
}
//编程
bit program_byte(unsigned char cpu) {
unsigned char d,n;
unsigned int adds=0,adds_max=un_adds_max;
do {
d=rec();
if (!b_break) {
out_adds(adds);
P1=d;
n=0;
while (1) {
mode(0x3);
p_we=0;
wait20us();
p_we=1;
mode(0x5);
if (in_data()!=d) n++; else break;
if (n&gt;2) return(1); //编程校验3次失败
}
adds++;
} else return(0); //pc通信超时或编程完成。在此不会区分,但无所谓
} while (adds!=adds_max);
return(1); //地址超出范围
}</P>
<P>bit lock123(void) {
unsigned char i,b_error=0;
unsigned int adds;
unsigned char code lock_bit[]={2,6,14};
wait20us();
for (i=0;i&lt;3;i++) {
mode(0x6);
out_adds(i);
p_we=0;
wait20us();
p_we=1;
mode(0xb);
out_adds(0);
if (in_data()!=lock_bit<i>) {b_error=1;break;}
}
if (!b_error) {
//常规读检查前4kb是否加密成功(为了节省时间,只检查前4kb)
mode(0);
for (adds=0;adds&lt;4096;adds++) {
out_adds(adds);
if (in_data()!=0xff) {b_error=1;break;}
}
}
sen(b_error);
return(b_error);
}</P>
<P>
void main(void) {
unsigned char cpu;
unsigned char i,start;
EA=1;
SCON=0xd8;PCON=0x80;
TMOD=0x21;
TL1=TH1=0xff;TR1=1;
TH0=0;ET0=TR0=1;
while (1) {
REN=1;
start=rec();
if ((!b_break)&amp;&amp;(start==0x0)) {
i=rec();
if (!b_break) {
switch (i) {
case b_cpu:
i=rec();
if (!b_break) cpu=i;
wait20us(); //防止电脑处理不过来
if (un_cpu<i>!=read_id()) sen(1); else sen(0);
break;
case b_init:
if (init(cpu)) wait500ms(); //初始化错误或通信错误等待1秒,让pc程序超时并
报告错误
break;
case b_read:
if (read(cpu)) wait500ms();
break;
case b_program_byte:
if (program_byte(cpu)) wait500ms(); //编程错误或通信错误等待1秒,让pc程序超
时并报告错误
break;
case b_lock123:
if (lock123()) wait500ms(); //加密错误或通信错误等待1秒,让pc程序超时并报
告错误
break;
}
}
}
}
}
</P>
页: [1]
查看完整版本: [转帖]P89CXX 编程器51接受程序(dhd0)