专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

AT89S5X 脱机下载器制

作者:佚名   来源:互联网   点击数:  更新时间:2010年05月17日   【字体:

  最近因工作需要,准备自已做一个AT89S5X的脱机下载器,初步考虑是用AT89S52做主机,将目标代码通过串口写入到AT24C64中(AT24C64有8K空间,刚好够52用)。到现场后再通过主机将EEPROM中的代码能过模拟ISP时序写入到目标单片机上,实现脱机下载。

  在画原理图前,打算先将S5X的ISP时序搞清楚,刚开始啃英文文档时,内牛满面啊。。。那啥,把高位发送看成了低位发选。。。整整搞了两天都没发觉。。因为AT的文档中关于ISP说的不清不楚的(至少在我看来是这样的),后来上网搜了USBASP的源程序,参考了里面的关于S5X的ISP时序,才终于明白过来。。。下面是关于S5X的ISP时序编程中一些要点:

1:关于复位时序

RST = 1;
SCK = 0;
DELAY(1);
RST = 0;    //这里要注意,有一个拉低过程
DELAY(1);
RST = 1;
DELAY(1);

2:连机检测,判断是否进入到ISP编程模式

ISP_WR(0XAC);
ISP_WR(0X53);
ISP_WR(0X00);
TempData[3]=ISP_WR(0X00);    //第四个字节边写边读出数据如果是0X69,则说明进入

          到了ISP模式

3:关于读识别字,在没有测试擦除(Erase)命令前,刚读出来的数据是正常的(1E 52 06),后来在测试擦除命令时,怀疑
擦除延时时间太短,杯具了。。。读出来的值一直是1F 7F 1F。。。

ISP_WR(0X28);
ISP_WR(0X00);
ISP_WR(0X00);
TempData[0] = ISP_WR(0X00);    //1E

ISP_WR(0X28);
ISP_WR(0X01);
ISP_WR(0X00);
TempData[1] = ISP_WR(0X00);    //52

ISP_WR(0X28);
ISP_WR(0X02);
ISP_WR(0X00);
TempData[2] = ISP_WR(0X00);    //06

4:关于擦除(Erase)命令,网络上搜到的延时是500MS左右,具体的我还没测试,等整个程序功能都完善了再测试确定各个延
时参数。

5:关于ISP各个引脚连接:

MOSI:主机出 从机入

MISO:主机入 从机出

SCK/RST:这个应该就不用说了
======================================================
下面的是我的测试程序。
======================================================
/**********************************************************************
S5X ISP测试程序
***********************************************************************/
#include <at89x52.h>
#include "1602.h"

sbit RST  =   P2^3;
sbit MISO  =  P2^2;
sbit MOSI  =  P2^1;
sbit SCK  =  P2^0;

ISP_WR(uchar command);
ISP_RD();
void DELAY(uint temp);


void main()
{
  uchar TempData[4];

  P0 = 0XFF;
  P1 = 0XFF;
  P2 = 0XFE;
  P3 = 0XFF;

  Lcd_Init();

  MOSI = 1;
  MISO = 1;
  RST = 1;
  SCK = 0;
  DELAY(1);
  RST = 0;   //这里注意
  DELAY(1);
  RST = 1;
  DELAY(1);


  ISP_WR(0XAC);
  ISP_WR(0X53);
  ISP_WR(0X00);
  TempData[3]=ISP_WR(0X00);   //连机测试

/*            //写入测试
  ISP_WR(0X40);
  ISP_WR(0X00);
  ISP_WR(0X00);
  ISP_WR(0XA5);
  DELAY(5000);
*/
/* 
  ISP_WR(0XAC);      //擦除测试
  ISP_WR(0X80);
  ISP_WR(0X00);
  ISP_WR(0X00);
  DELAY(5000);
*/ 

  ISP_WR(0X28);
  ISP_WR(0X00);
  ISP_WR(0X00);
  TempData[0] = ISP_WR(0X00);   //1E
 
  ISP_WR(0X28);
  ISP_WR(0X01);
  ISP_WR(0X00);
  TempData[1] = ISP_WR(0X00);   //52

  ISP_WR(0X28);
  ISP_WR(0X02);
  ISP_WR(0X00);
  TempData[2] = ISP_WR(0X00);     //06
/*
  ISP_WR(0X20);      //读测试
  ISP_WR(0X00);
  ISP_WR(0X00);
  TempData[3] = ISP_WR(0X00);
*/
//**********************************************************************以下是送LCD1602显示的数据
  if((TempData[0] >>4) >9) Lcd_Out(Data,(TempData[0]>>4)+0x37);
  else Lcd_Out(Data,(TempData[0]>>4)+0x30);
  if((TempData[0] & 0x0f) >9) Lcd_Out(Data,(TempData[0] & 0x0f)+0x37);
  else Lcd_Out(Data,(TempData[0] &0x0f)+0x30);

  if((TempData[1] >>4) >9) Lcd_Out(Data,(TempData[1]>>4)+0x37);
  else Lcd_Out(Data,(TempData[1]>>4)+0x30);
  if((TempData[1] & 0x0f) >9) Lcd_Out(Data,(TempData[1] & 0x0f)+0x37);
  else Lcd_Out(Data,(TempData[1] &0x0f)+0x30);

  if((TempData[2] >>4) >9) Lcd_Out(Data,(TempData[2]>>4)+0x37);
  else Lcd_Out(Data,(TempData[2]>>4)+0x30);
  if((TempData[2] & 0x0f) >9) Lcd_Out(Data,(TempData[2] & 0x0f)+0x37);
  else Lcd_Out(Data,(TempData[2] &0x0f)+0x30);

  if((TempData[3] >>4) >9) Lcd_Out(Data,(TempData[3]>>4)+0x37);
  else Lcd_Out(Data,(TempData[3]>>4)+0x30);
  if((TempData[3] & 0x0f) >9) Lcd_Out(Data,(TempData[3] & 0x0f)+0x37);
  else Lcd_Out(Data,(TempData[3] &0x0f)+0x30);
  while(1);
}


ISP_WR(uchar DATA)
{
  uchar i,Rec_Data;
 
  for(i=0;i<8;i++)
  {
   MOSI = DATA& 0x80;
   DATA= DATA<<1; 

   Rec_Data = Rec_Data << 1;
   if(MISO == 1) Rec_Data |= 0x01;

   SCK = 1;
   DELAY(1);
   SCK = 0;
   DELAY(1);
  } 
  return(Rec_Data);
}


void DELAY(uint temp)
{
  uint i,j;
  for(i=0;i<temp;i++)
   for(j=0;j<30;j++);
}

关闭窗口

相关文章