?? at29c020_card.c
字號(hào):
/*****************************************************************/
/* This program demonstrates how a sector in one of the 512K X 8 */
/* variants can be programmed. The program first determines */
/* exactly which device is available by reading the device ID. */
/* A sector is then programed with data that is copied from an */
/* SRAM buffer. After waiting for the programming cycle to */
/* complete the data is copied back from the 29C040 to the SRAM */
/* buffer. */
/* */
/* The sector size and programming time are determined */
/* by examining the device ID. The different 512K X 8 devices */
/* have either a 256- or 512-byte sector size and a 10 mS or 20 */
/* mS tWC. */
/*****************************************************************/
/***********************/
/* COMPILER DIRECTIVES */
/***********************/
//.asm
//.linklist
//.symbols
//.endasm
#include "c8051sr.h"
/********************/
/* GLOBAL VARIABLES */
/********************/
unsigned char part_id; /* DEVICE ID VALUE */
int sector_size; /* DEVICE SECTOR SIZE */
int twc; /* DEVICE PROGRAMMING TIME REQUIRED */
unsigned char data_buffer[512]; /* SRAM DATA BUFFER */
unsigned char block_number; /* WHICH BLOCK TO PROGRAM */
unsigned int sector_address; /* ADDRESS WITHIN SECTOR TO PROGRAM */
unsigned int address_pointer; /* SCRATCH PAD ADDRESS REGISTER */
unsigned char temp_byte; /* SCRATCH PAD DATA REGISTER */
/***********************/
/* SUPPORT SUBROUTINES */
/***********************/
/********************************************************************/
/* DELAYMS performs a time delay. The variable ticks indicates the */
/* length of the delay in mS. This routine is dependant upon the */
/* clock rate of the 89C51. If a clock rate other than 12 MHz is */
/* used the variable 'count' must be modified. */
/********************************************************************/
void delayms(char ticks)
{
char count;
for(ticks = ticks; ticks >= 0; ticks—)
{
for (count = 0; count <= 13; count++)
{
}
}
}
/*****************************************************************/
/* ENTER_ID_MODE is used to put the 29C040 into Software Product */
/* Identification mode. The three step sequence is performed in */
/* assembly because of tBLC requirements of the 29C040. */
/*****************************************************************/
void enter_id_mode()
{
asm
mov a,#05h
mov p1,a
mov dptr,#4555h
mov a,#aah
movx @dptr,a ;write AAh to address 05555h
mov a,#02h
mov p1,a
mov dptr,#4aaah
mov a,#55h
movx @dptr,a ;write 55h to address 02AAAh
mov a,#05h
mov p1,a
mov dptr,#4555h
mov a,#90h
movx @dptr,a ;write 90h to address 05555h
.endasm
}
/********************************************************************/
/* LEAVE_ID_MODE is used to remove the 29C040 from Software Product */
/* Identification mode. The three step sequence is performed in */
/* assembly because of tBLC requirements of the 29C040. */
/********************************************************************/
void leave_id_mode()
{
.asm
mov a,#05h
mov p1,a
mov dptr,#4555h
mov a,#aah
movx @dptr,a ;write AAh to address 05555h
mov a,#02h
mov p1,a
mov dptr,#4aaah
mov a,#55h
movx @dptr,a ;write 55h to address 02AAAh
mov a,#05h
mov p1,a
mov dptr,#4555h
mov a,#f0h
movx @dptr,a ;write F0h to address 05555h
.endasm
}
/*********************************************************************/
/* GET_ID is used read the value at location 00001 of the 20C040. */
/* The value read from the device is returned to the calling routine */
/*********************************************************************/
unsigned char get_id()
{
P1 = 0x00; /* read from block 00h */
.asm
mov dptr,#4001h ;read from address 00001h
movx a,@dptr ; (flash offset = 4000h)
.endasm
return(A); /* return data value */
}
/******************************************************************/
/* GET_PART_ID determines the device ID of the 29C040 being used. */
/* The ID value is returned to the calling routine */
/******************************************************************/
unsigned char get_part_id()
{
unsigned char part_id;
enter_id_mode(); /* enter Identification mode */
delayms(20); /* delay 20mS */
part_id = get_id(); /* read device ID from address 1 */
leave_id_mode(); /* exit from Identification mode */
delayms(20); /* delay 20mS */
return(part_id); /* return device ID value */
}
/*****************************************************************/
/* SET_PARAMETERS is used to define what sector size and write */
/* cycle is required for the particular 29C040 being used */
/* The sector size is stored in the global variable SECTOR_SIZE, */
/* and the programming time is stored in the global variable TWC.*/
/*****************************************************************/
void set_parameters(unsigned char part_id)
{
switch(part_id)
{
case 0x5b : sector_size = 512; /* is the device a 29C040 */
twc = 10;
break;
case 0xa4 : sector_size = 256; /* is the device a 29C040A */
twc = 10;
break;
case 0x3b : sector_size = 512; /* is the device a 29LV040 */
twc = 20;
break;
case 0xc4 : sector_size = 256; /* is the device a 29LV040A */
twc = 20;
break;
default : sector_size = 0; /* variables default to 0 */
twc = 0;
}
}
/*****************************************************************/
/* DUMMY_BUFFER_LOAD simply loads the SRAM buffer with the value */
/* passed in IN_VALUE. Although the SRAM buffer has 512 bytes, */
/* only the number of bytes required to fill a sector are loaded.*/
/*****************************************************************/
void dummy_buffer_load(char in_value)
{
int count;
for (count = 0; count <= sector_size; count++)
{
data_buffer[count] = in_value;
}
}
/*****************************************************************/
/* WRITE_SECTOR copies data from the SRAM buffer into the sector */
/* specified in the 29C040. After loading the sector the routine*/
/* paused the required tWC for the programming cycle to complete.*/
/*****************************************************************/
void write_sector()
{
.asm
mov a,#05h ;perform 3 step SDP sequence
mov p1,a
mov dptr,#4555h
mov a,#aah
movx @dptr,a ;write AAh to address 05555h
mov a,#02h
mov p1,a
mov dptr,#4aaah
mov a,#55h
movx @dptr,a ;write 55h to address 02AAAh
mov a,#05h
mov p1,a
mov dptr,#4555h
mov a,#A0h
movx @dptr,a ;write A0h to address 05555h
mov dptr,#_block_number
movx a,@dptr
mov P1,a ;set up block address
mov dptr,#_sector_size ;load sector size
movx a,@dptr
mov r0,a
inc dptr
movx a,@dptr
mov r1,a
mov dptr,#_sector_address ;load first sector address to write
movx a,@dptr
add a,#40h
mov r3,a
inc dptr
movx a,@dptr
mov r2,a
mov dptr,#_data_buffer ;load pointer to data_buffer
nextwr: movx a,@dptr ;load data to write to 29C040
inc dptr ;increment data_buffer pointer
push dpl
push dph
mov dpl,r2
mov dph,r3
movx @dptr,a ;write data to 29C040
inc dptr ;increment flash address pointer
mov r2,dpl
mov r3,dph
pop dph
pop dpl
djnz r1,nextwr ;decrement byte counter
djnz r0,nextwr ; loop until sector has been loaded
.endasm
delayms(twc); /* delay for the programming cycle */
}
/********************************************************************/
/* READ_SECTOR copies a sector from the 29C040 into the SRAM buffer */
/* Either 256 or 512 bytes are transfered depending on the size of */
/* the sector. */
/********************************************************************/
void read_sector()
{
unsigned int count;
P1 = block_number; /* initial block # */
address_pointer = sector_address + 0x4000; /*create address pointer*/
for (count = 0; count < sector_size; count++) /*transfer sector to SRAM*/
{
asm
mov dptr,#_address_pointer ;load address pointer's address
movx a,@dptr ;load address pointer high byte
mov b,a
inc dptr
movx a,@dptr ;load address pointer low byte
mov dpl,a
mov dph,b
movx a,@dptr ;read data from 29C040
mov dptr,#_temp_byte
movx @dptr,a ;store data from 29C040 into temp_byte
endasm
data_buffer[count] = temp_byte; /*place data into SRAM*/
address_pointer = address_pointer + 1; /*increment address pointer*/
}
}
/************/
/* MAINLINE */
/************/
main()
{
part_id = get_part_id(); /* GET PART ID */
set_parameters(part_id); /* DETERMINE WRITE PARAMETERS */
dummy_buffer_load(0x55); /* LOAD SRAM BUFFER WITH DUMMY DATA */
block_number = 0x1f; /* SPECIFY BLOCK NUMBER TO WRITE */
sector_address = 0x0400; /* SPECIFY ADDRESS WITHIN BLOCK */
write_sector(); /* COPY SRAM BUFFER TO 29C040 */
read_sector(); /* COPY 29C040 SECTOR TO SRAM */
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -