Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
05/25/05 02:18
Read: times


 
#93854 - movx a,@dptr!
Hi Guys,

I have been trying to figure out a problem with a small program that I am doing. I am fairly new with 8051 so please bear with me. I have built an eeprom I2C programmer using an old Dallas 5000FP that I received in the development kit a few years back.

The program uses any terminal program and runs at 9600 baud. It will read eeproms 24C16 to 24C256 and dump the code to the terminal screen. You can also send a file you want
programmed in the eeprom through the terminal program.

The data to be programmed (sent through the terminal program) is stored in the Dallas's NVRAM temporarily, then it is written to the eeprom afterwards. I have tested the I2C routines, all are working both read and write. The problem I have is that the first byte from every line is being written to the entire line, its as
if the dptr is not being incremented while trying to fetch a byte from the RAM. I tried a debug routine that would print the bytes being written to the terminal and everything is working
perfect. The data to be written is being stored in the NVRAM at addr 4000h (partitioned the chip @4000 while programming). I am sure of this because i read the contents of the DALLAS at addr
4000 and the file being sent from the terminal program is there, every byte, So the problem is when the byte is being fetched from the RAM, it is the first byte of every line continually written 10 times. The next line, same thing. I have been trying everything and the code seems perfect. I simply do not know what is happening (and I think I am tired of pulling my hair out)

Here is an example:
send this file through the terminal:
:10000000800075A800758170787FE4F6D8FD120431
:10001000B71202E39004BD120461790F1202E3D912
:10002000FB120487B43103020071B432030200BE34

will be written like this:
:10000000808080808080808080808080808080808000
:10001000B7B7B7B7B7B7B7B7B7B7B7B7B7B7B700
:10002000FBFBFBFBFBFBFBFBFBFBFBFBFBFB00


I have no idea why this simple thing is giving me trouble. I have attached my source code and would appreciate any help from the pros. This is just a learning thing for me and there is
absolutely no profit involved. As far as I can tell it should work! Maybe I overlooked a something simple.

The problem lies in the Prog_eep routine. The code still needs to be cleaned up a bit but it is fully functional with the exception of the one problem above.
thanks
CT
Here is the source:
;********************************************************************
; 8051 Boot Loader ver 3.0
; Download standard Intel hex format files
; uses DALLAS 5000 NV RAM for temporary storage of file sent through terminal
; @9600 baud.
; when loading set partition at 4000
;********************************************************************
$mod51 ; symbol definitions

DYTA equ 10H ; data byte to be written
filesizeH equ 23h ;to measure length of file being downloaded
filesizeL equ 22h ;so we know how many bytes to write
addrhi equ 21h ;used for writing eeprom
addrlo equ 20h ;used for writing eeprom
CKSUM equ 1Fh ; Intel Hex Checksum Reg
count equ 1Eh ; byte counter
progcntr EQU 1Dh ; progress bar counter to slow down symbols
L_SIZE EQU 1Ch ; eeprom size low byte
H_SIZE EQU 1Bh ; eeprom size high byte
SCL BIT p1.2 ; serial clock
SDA BIT p1.3 ; serial data
LF EQU 0Ah ; Line Feed character.
CR EQU 0Dh ; Carriage Return character.
ESC EQU 1Bh ; Escape character.
StartChar EQU ':' ; Line start character for hex file.
space equ 020h ; ascii space
Ser_RX equ p3.0 ; Serial RX
Ser_TX equ p3.1 ; Serial TX
BITTIM equ 45 ;9600 Baud (@ 11.0592MHZ)
;********************************************************************
; Interrupt vector table
;********************************************************************
org 0 ; System reset RST
sjmp Start
org 3 ; External 0 IE0 not used
reti
org 0bh ; Timer 0 TF0 not used
reti
org 13h ; External 1 IE1 not used
reti
org 1bh ; Timer 1 TF1 not used
reti
org 23h ; Serial port TI or RI not used
reti
org 2bh ; Timer 2 TF2 or EXF2 not used
reti
;********************************************************************
; Main program starts here
;********************************************************************
org 30h
Start:
MOV IE,#0 ; Turn off all interrupts.
MOV SP,#07h ; Start stack near top of '51 RAM.
mov r0,#7fh ; clear RAM
clr a ;
Start1:
mov @r0,a ;
djnz r0,Start1 ;
lcall Delay ;
Main:
lcall ClrScreen
lcall Newline
lcall intro ; print welcome message
mov r1,#00Fh ;
Main2:
lcall newline ;
djnz r1,Main2 ;
Main3:
lcall Inchar ;Get a cmd to work with
cjne a,#031h,Main4 ;
ljmp dump_eep ;user pressed '1' Read Eeprom
Main4:
cjne a,#032h,Main5 ;user pressed '2' Program Eeprom
ljmp Prog_eep
Main5:
sjmp Main3 ;didn't get selection, try again
;***********************************************************
dump_eep:
lcall Chk_Dev ;
MOV DPTR,#0000H
dump:
mov count,#010h
mov R0,#030h
dump1:
LCALL EEPROM_READ
MOV A,DYTA ;read byte in DYTA
mov @R0,a
inc R0
djnz count,dump1
lcall PrintLine

mov a, dpl ; check low byte
mov b,L_SIZE ;
cjne a,b,dump ;
mov a, dph ; check high byte
mov b,H_SIZE ;
cjne a,b,dump ; jump if not last

DMP_Done:
MOV A,#CR ;
LCALL outchar ; START ON A NEW LINE
MOV A,#LF ;
LCALL outchar ;
MOV DPTR,#ENDREC ; ADDRESS OF INTEL HEX END RECORD
LCALL outstr ; PUT OUT THE STRING

lcall Inchar
ljmp Main
ENDREC:
DB ':00000001FF',CR,LF,0
ret
;***********************************************************
Prog_eep:
mov dptr,#File_str
lcall outstr ;

lcall load1 ; get Chars, convert to hex, store in NVRam
mov dptr,#Prog_str
lcall outstr ;

mov dptr,#4000h
mov addrhi,#0
mov addrlo,#0
Prog_Loop:
movx a,@dptr ;get data byte
mov dyta,a
inc dptr

;we have addrhi, addrlo, & data set up,write it
LCALL EEPROM_WRITE2 ;write one byte

;here we check dptr against last addr previously loaded to NVRAM
;last addr = filesizeH, filesizeL

mov a, dpl ; check low byte
mov b,filesizeL ;
cjne a,b,Prog_Loop1 ; a<>b? keep programming
mov a, dph ; a = b? check high byte
mov b,filesizeH ;
cjne a,b,Prog_Loop1 ; a<>b? keep programming
sjmp Prog_End ; end program
Prog_Loop1:
inc addrlo
mov a,addrlo
jnz Prog_Loop
inc addrhi
sjmp Prog_Loop
Prog_End:
mov dptr,#Success_str
lcall outstr
lcall Inchar ;wait for keypress
ljmp Main
;======================================================================
;get Chars, convert to hex, store in Ram
load1: lcall inchar
cjne a,#1ah,skip1 ; end of file?
sjmp Done

skip1: cjne a,#':',load1 ; each record begins with ':'
mov r1,#0 ; init checksum to zero
lcall gethex ; get byte from serial port
mov b,a ; use b as byte counter
jz done ; if b = 0

load2: inc b
lcall gethex ; get address high byte
mov dph,a
mov a,dph
add a,#040h ;DS5000 partition @4000h
mov dph,a
lcall gethex ; get address low byte
mov dpl,a
lcall gethex ; get record type (ignore this)

load4: acall gethex ; get data byte
movx @dptr,a ; store in ext. ram
inc dptr
dec b ; repeat until count = 0
mov a,b
jnz load4
mov a,r1 ; checksum should be zero
jz load1 ; if so, then get next record
ljmp error ; if not, stop download
Done:
mov filesizeH,dph ;save filesize high byte
mov filesizeL,dpl ;save filesize low byte
ret
;*************************************************************************
Chk_Dev:
lcall ClrScreen
mov dptr,#Device_str ;
lcall outstr ;
ChkInp:
lcall Inchar ;Get a cmd to work with

cjne a,#031h,ChkInp1 ;if its a 1 select 24C16
mov L_SIZE,#000h
mov H_SIZE,#008h
ret
ChkInp1:
cjne a,#032h,ChkInp2 ;if its a 2 then select 24C32
mov L_SIZE,#000h
mov H_SIZE,#010h
ret
ChkInp2:
cjne a,#033h,ChkInp3 ;if its a 3 then select 24C64
mov L_SIZE,#000h
mov H_SIZE,#020h
ret
ChkInp3:
cjne a,#034h,ChkInp4 ;if its a 4 then select 24C128
mov L_SIZE,#000h
mov H_SIZE,#040h
ret
ChkInp4:
cjne a,#035h,ChkInp5 ;if its a 5 then select 24C256
mov L_SIZE,#000h
mov H_SIZE,#080h
ret
ChkInp5:
ljmp ChkInp ;none of the above, check again
;********************************************************************
; Get two characters from serial port and form a hex byte. Also add
; byte to checksum in r1.
;********************************************************************
gethex: lcall inchar ; get first character
lcall atoh ; convert to hex
swap a ; put in upper nibble
mov r0,a ; save it
lcall inchar ; get second character
lcall atoh ; convert to hex
orl a,r0 ; or with first nibble
mov r2,a ; save byte
add a,r1 ; add byte to checksum
mov r1,a ; restore checkum in r1
mov a,r2 ; retrieve byte
ret
;********************************************************************
; ASCII to hex - enter with ascii code in acc. (assume hex char 0-F)
; exit with hex nibble in A.0-A.3
;********************************************************************
atoh: clr acc.7 ; ensure parity bit is off
cjne a,#3ah,next ; ?? this just sets carry bit ??
next: jc atoh2
add a,#9 ; no, adjust for range A-F
atoh2: anl a,#0fh ; yes, convert directly
ret
;********************************************************************
; Print welcome message
;********************************************************************
intro: mov dptr,#intro_str
lcall outstr
ret
;********************************************************************
; Send a null terminated string out serial port
;********************************************************************
outstr: clr a
movc a,@a+dptr ; get character
jz exit ; stop if char == null
lcall outchar ; else send it
inc dptr ; point to next char
sjmp outstr
exit: ret
;==================================================================
error:
mov dptr,#error_str
lcall outstr
ret
;--------------Clear Terminal Screen----------
ClrScreen:
mov dptr,#cls ;
call outstr ;
ret
;==================================================================
; NewLine - output a carriage return / line feed pair to the serial port.
NewLine:
MOV A,#CR
CALL OutChar
MOV A,#LF
CALL OutChar
RET
;===================================================================
Init_Buffer:
mov R0,#030h
ret
;************************************************************
;reading 8 bits from i2c device
I2C_READ:
MOV R7,#8
GFD:
SETB SDA
SETB SCL
MOV C,SDA
RLC A
CLR SCL
DJNZ R7,GFD
MOV DYTA,A
RET
;************************************************************
;writing 8 bits in to i2c device
I2C_WRITE:
MOV R7,#8
WRITING:
RLC A
MOV SDA,C
LCALL CLOCK
DJNZ R7,WRITING
RET
;************************************************************
;start of i2c routine
I2C_START:
SETB SCL
SETB SDA
CLR SDA
CLR SCL
RET
;************************************************************
;end of i2c routine
I2C_STOP:
SETB SCL
CLR SDA
SETB SDA
CLR SCL
RET
;************************************************************
;synchronizing clock
CLOCK:
SETB SCL
NOP
NOP
CLR SCL
RET
;************************************************************
;acknowledge from transmitter or receiver
ACK:
CLR SDA
SETB SCL
CLR SCL
RET
;************************************************************
;no acknowledge from transmitter or receiver
NO_ACK:
SETB SDA
SETB SCL
CLR SCL
RET
;************************************************************
;SERIAL EEPROM PACKAGE
;write one byte to eeprom
EEPROM_WRITE:
LCALL I2C_START
LCALL EEPROM_WRITE_ADDR
LCALL ACK
MOV A,DPH
LCALL I2C_WRITE
LCALL ACK
MOV A,DPL
LCALL I2C_WRITE
LCALL ACK
MOV A,DYTA
LCALL I2C_WRITE
LCALL ACK
LCALL I2C_STOP
LCALL DELAY_STOP
RET
;************************************************************
EEPROM_WRITE2:
LCALL I2C_START
LCALL EEPROM_WRITE_ADDR
LCALL ACK
;MOV A,DPH
mov a,addrhi
LCALL I2C_WRITE
LCALL ACK
;MOV A,DPL
mov a,addrlo
LCALL I2C_WRITE
LCALL ACK
MOV A,DYTA
LCALL I2C_WRITE
LCALL ACK
LCALL I2C_STOP
LCALL DELAY_STOP
RET
;************************************************************
;read from eeprom
EEPROM_READ:
LCALL I2C_START
LCALL EEPROM_WRITE_ADDR
LCALL ACK
MOV A,DPH
LCALL I2C_WRITE
LCALL ACK
MOV A,DPL
LCALL I2C_WRITE
LCALL ACK
LCALL I2C_START
LCALL EEPROM_READ_ADDR
LCALL ACK
LCALL I2C_READ
LCALL NO_ACK
LCALL I2C_STOP
RET
;************************************************************
EEPROM_READ_ADDR: ;A2,A1,A0 are aero
MOV A,#10100001B
LCALL I2C_WRITE
RET
;************************************************************
EEPROM_WRITE_ADDR: ;A2,A1,A0 are aero
MOV A,#10100000B
LCALL I2C_WRITE
RET
;************************************************************
Delay:
mov r2,#0FFh ;
djnz r2,$ ;
ret ;
;************************************************************
;terminating write process
DELAY_STOP:
MOV R5,#95 ;was 85
DELAY_STOP1:
DJNZ R5,DELAY_STOP1
ret
;***********************************************************
;---- Print out 10h bytes to Terminal in Intel Hex ----
PrintLine:
mov R0,#030h ; point to buffer
DMPHEX:
CLR C ;
DMP_B:
MOV r1,#010H ; LEN := 16
DMP_C:
MOV CKSUM,#0 ; CKSUM := 0
MOV A,#CR ;
LCALL outchar ; START RECORD ON A NEW LINE
MOV A,#LF ;
LCALL outchar ;
MOV A,#':' ;
LCALL outchar ; HEADER CHARACTER
MOV A,r1 ;
LCALL HOUT ; LENGTH

mov a,dph
LCALL HOUT ; ADDRESS (HI BYTE)
mov a,dpl
LCALL HOUT ; ADDRESS (LOW BYTE)

NoBump:
CLR A ;
LCALL HOUT ;RECORD TYPE
DMP_D:
MOV A,@R0 ;REPEAT A := MEM[DPTR]
INC R0
LCALL HOUT ;WRITE IT OUT
INC DPTR ;++INDEX
DJNZ r1,DMP_D ;UNTIL (LEN = 0);

MOV A,CKSUM ;DO A TWO'S COMPLEMENT OF CKSUM BY
CPL A ;COMPLEMENTING
INC A ;AND ADDING ONE
LCALL HOUT ;CKSUM
ret
;**************************************************************
;calculate the checksum, convert to ascii and print to screen
HOUT:
PUSH ACC
ADD A,CKSUM
MOV CKSUM,A
POP ACC
PUSH ACC
SWAP A
LCALL PHEX1
POP ACC
LCALL PHEX1
RET
;**********************************************************
;same as the hex2ascii routine (HexAsc)
PHEX1:
ANL A,#0FH
ADD A,#4
MOVC A,@A+PC
LCALL outchar
RET
DB '0123456789ABCDEF'
;---------------- PC SIO Subroutines ---------------------
; Receive a character from the PC RXD line and return in A
InChar:
getc:
JB Ser_RX,$ ;Wait for start bit
MOV R2,#BITTIM/2 ;Wait 1/2 bit-time
DJNZ R2,$ ;To sample in middle
JB Ser_RX,getc ;Insure valid
MOV R3,#8 ;Read 8 bits
getc1:
MOV R2,#BITTIM ;Wait full bit-time
DJNZ R2,$ ;For DATA bit
MOV C,Ser_RX ;Read bit
RRC A ;Shift it into ACC
DJNZ R3,getc1 ;read 8 bits
CLR C ;
RET ;go home
;---------------------------------------------------------;
;Transmit character in A via PC TXD line
OutChar:
putc: CLR Ser_TX ;Drop line for start bit
MOV R2,#BITTIM ;Wait full bit-time
DJNZ R2,$ ;For START bit
MOV R3,#8 ;Send 8 bits
putc1:
RRC A ;Move next bit into carry
MOV Ser_TX,C ;Write next bit
MOV R2,#BITTIM ;Wait full bit-time
DJNZ R2,$ ;For DATA bit
DJNZ R3,putc1 ;write 8 bits
SETB Ser_TX ;Set line high
RRC A ;Restore ACC contents
MOV R2,#BITTIM ;Wait full bit-time
DJNZ R2,$ ;For STOP bit
RET ;
;---------------------------------------------------------;
;data tables and strings ;
;---------------------------------------------------------;
intro_str:
db ' 24CXX Programmer ',cr,lf,
db 'Select: (1) Read Eeprom',cr,lf,
db ' (2) Program Eeprom',cr,lf,0
File_str:
db 'Send File Now',cr,lf,0

Prog_str:
db 'Programming Eeprom, PLEASE WAIT...',cr,lf,0

Done_str:
db cr,'Programming Success!',cr,lf,0

Cls:
db esc,'[','H',esc,'[','J',0
;----------------------------------------------------------------
device_str:
db ' Select Device ',cr,lf,
db ' (1) 24C16',cr,lf,
db ' (2) 24C32',cr,lf,
db ' (3) 24C64',cr,lf,
db ' (4) 24C128',cr,lf,
db ' (5) 24C256',cr,lf,cr,lf,lf,lf,lf,lf,0
;----------------------------------------------------------------
error_str:
db 'Download Failed',cr,lf,0

Success_str:
db 'Upload Success!',cr,lf,0

end





List of 9 messages in thread
TopicAuthorDate
movx a,@dptr!            01/01/70 00:00      
   I think your problem is...            01/01/70 00:00      
   No Michael            01/01/70 00:00      
   DYTA EQU 10H?            01/01/70 00:00      
   movx a,@dptr            01/01/70 00:00      
      code format            01/01/70 00:00      
      WHICH EEPROM            01/01/70 00:00      
      the error...            01/01/70 00:00      
         movx a,@dptr            01/01/70 00:00      

Back to Subject List