AT89C52 SPI编程通过并口噩梦

时间:2017-05-12 16:48:41

标签: c microcontroller spi parallel-port lpt

我试图找出为什么我的芯片无法完全编程。 我试图在芯片中存储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;
}

0 个答案:

没有答案