AT89S5X脫機下載器制作
最近因工作需要,準備自已做一個AT89S5X的脫機下載器,初步考慮是用AT89S52做主機,將目標代碼通過串口寫入到AT24C64中(AT24C64有8K空間,剛好夠52用)。到現(xiàn)場后再通過主機將EEPROM中的代碼能過模擬ISP時序?qū)懭氲侥繕藛纹瑱C上,實現(xiàn)脫機下載。
在畫原理圖前,打算先將S5X的ISP時序搞清楚,剛開始啃英文文檔時,內(nèi)牛滿面啊。。。那啥,把高位發(fā)送看成了低位發(fā)選。。。整整搞了兩天都沒發(fā)覺。。因為AT的文檔中關(guān)于ISP說的不清不楚的(至少在我看來是這樣的),后來上網(wǎng)搜了USBASP的源程序,參考了里面的關(guān)于S5X的ISP時序,才終于明白過來。。。下面是關(guān)于S5X的ISP時序編程中一些要點:
1:關(guān)于復位時序
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); //第四個字節(jié)邊寫邊讀出數(shù)據(jù)如果是0X69,則說明進入
到了ISP模式
3:關(guān)于讀識別字,在沒有測試擦除(Erase)命令前,剛讀出來的數(shù)據(jù)是正常的(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:關(guān)于擦除(Erase)命令,網(wǎng)絡上搜到的延時是500MS左右,具體的我還沒測試,等整個程序功能都完善了再測試確定各個延
時參數(shù)。
5:關(guān)于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顯示的數(shù)據(jù)
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;i8;i++)
{
MOSI = DATA 0x80;
DATA= DATA1;
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;itemp;i++)
for(j=0;j30;j++);
}
評論