我试图找出为什么我的芯片无法完全编程。 我试图在芯片中存储1.7 KB的代码。我成功地编写了前256个字节,并且能够验证每个字节(即使有时会出现打嗝),但是,第257个字节无法验证。
我使用的芯片是AT89S52,它接受至少4KB的代码。此外,我找到了作为参数输入程序的文件并存储在x051 char数组中。
我使用的硬件是我自己构建的电路,其中通过PC并行端口到微控制器的缓冲区进行以下连接:
Pin 1 (strobe) to SCK
Pin 2 (data bit 0) to enable all buffers
Pin 4 (data bit 2) to MOSI
MISO to Pin 11 (busy)
微控制器上的每条线由10K外部上拉电阻拉高。
微控制器上的EA / VPP线设置为高电平以允许编程。
微控制器连接到20Mhz晶体。
我只想弄明白。有没有办法可以改变我的代码,使得时序更加坚持AT89S52芯片,因为在它所处的状态下,我只能编程芯片的前256个字节。该微控制器的数据表在时间上并不清楚。
我尝试过网页模式写作,结果差得多。
这是我的代码,正如它所示,如果它在某个字节上挣扎,它会在每100次验证尝试时被重写,直到它被验证为存储:
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/io.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int fm=0;
void lag(){if (fm!=1){usleep(1500);}else{usleep(500);}} //lag routine
void _sclk(unsigned char n){if (n != 0){n=1;};outb(n,0x37A);lag();} //set value for SCK
void _touc(unsigned char n){if (n != 0){n=4;};n++;outb(n,0x378);lag();} //set value for MOSI and set reset low
unsigned char _fromuc(){unsigned char n=inb(0x379);if ((n & 0x80)!= 0){n=1;}else{n=0;};return n;} //get MISO value
void bo(unsigned char byt){
//byte out to uC
int bit,bn;
for (bit=0;bit<8;bit++){
bn=(byt & 0x80);
if (bn != 0){bn=1;}
_touc(bn);_sclk(1);_sclk(0);byt=byt<<1;
}
}
unsigned char bi(){
//byte in from uC
int bit,bn;unsigned char outbyte;
for (bit=0;bit<8;bit++){
_sclk(1);
bn=_fromuc();
outbyte=outbyte<<1;
if (bn!=0){outbyte++;}
_sclk(0);
}
outbyte=255-outbyte;
return outbyte;
}
int main(int argc,char* argv[]){
char x051[10000]; //buffer for file data
setbuf(stdout,NULL);
if (argc < 2){
printf("binary filename required as argument.\n");
return -1;
}
struct stat info;stat(argv[1],&info); //get file size
if (info.st_size > 32767){
printf("FILE SIZE TOO LARGE\n"); //my chip can't handle 32kb
return -1;
}
int fs=info.st_size;
if (fs < 1){
printf("File non-existant.\n");
return -1;
}
printf("File size for %s is %d bytes\n",argv[1],fs);
memset(x051,0,4999); //clear just enough data memory. we only use 4K max.
FILE* fh=fopen(argv[1],"r");
if (fh){ //don't crash if computer disk breaks during program
fread(x051,fs,1,fh);
};
fclose(fh);
//LPT address definitions
//378: bit 0: 1=SPI MODE,0=RUN
// bit 2: uC recv (MOSI P1.5)
//379: bit 7: uC send (MISO P1.6)
//37A: bit 0: sclk (SCK P1.7)
if (ioperm(0x378,3,1) ==-1){ //get permission to use port
printf("ERROR: Access to port hardware denied by PC.\n");
return -1;
}
printf("AT89S5x burner starting\n");
outb(0x0,0x378); //set reset on micro to
_touc(0); //RESET=high + MOSI = 0
_sclk(0); //SCK = 0
usleep(1000000); //wait 1 second for chip to catch up
printf("Identifying chip...");
//enable SPI
bo(0xAC);bo(0x53);bo(0x00);bo(0x69); //send code AC,53,00,69 to chip
usleep(100000); //wait for chip to catch up
//get sig (this part works 50% of the time)
bo(0x28);bo(0x0);bo(0x0);int bin=bi(); //send code 28,0,0 and read last byte
if (bin != 0x1E){
printf("Bad signature on micro\n");
outb(0x0,0x378); //reset=low for bin != 1Eh
return -1;
}
printf("OK\n");
//erase
printf("Erasing old data on chip...");
bo(0xAC);bo(0x80);bo(0x0);bo(0x0);usleep(100); //send AC,80,0,0 and wait 100uS
//This part works 50% of the time
//(check memory address 0000h, and FFFFh, but highest 3 bits are ignored by microcontroller
// but I don't care. Returning FFh means byte is erased)
printf("validate 1...");do{usleep(100);bo(0x20);bo(0);bo(0);}while(bi() != 0xFF);
printf("validate 2...");do{usleep(100);bo(0x20);bo(0xFF);bo(0xFF);}while(bi() != 0xFF);
printf("OK\n");
printf("Writing %d bytes of data.",fs);
int an;fm=1; //fm=fast mode=1 (less sleep time between port instructions)
for (an=0;an<fs;an++){ //loop through all bytes
unsigned char rb,byt=(unsigned char)x051[an]; //convert each into unsigned char
bo(0x40);bo(an/256);bo(an%256);bo(byt); //write value of byt to counter value address
printf("%d/%d bytes written. ",an,fs); //and show progress
int sv=0; //set sleep value (sv) and receive byte (rb) to zero
do{
//loop is always stuck at 256th byte
if (sv==1){fm=0;printf("Chip catching up...");};
usleep(sv*1000); //wait longer each time verification fails
bo(0x20);bo(an/256);bo(an%256);rb=bi(); Read byte at same location byte was written to. Value returned in rb
sv++; //increment sleep value for each verification failure
if (sv > 101){
printf("retrying...");bo(0x40);bo(an/256);bo(an%256);bo(byt);sv=0; //write byte to same location once more to wake up chip
}
}while(rb != byt);
fm=1;
printf("\n");
}
//we never get here
printf("** write done\n");
outb(0x0,0x378);
printf("** ALL DONE and program running**\n\n");
return 0;
}