Could anyone help me ? Below "case1" function works well in 8051 based. Because this function uses under 0x7F sram address. But, in "case2", cause short of memory, I have to change registers to upper 0x80 address. Currently, "case 2" is not working, because it coded like direct coding. In this case, I heard that indirect address method. I strongly want to know this indirect coding method. ;case 1: =============================================== rd_i2c_buf0 equ 50h rd_i2c_buf1 equ 51h rd_i2c_buf2 equ 52h rd_i2c_buf3 equ 53h fncI2C_write_Nbyte: mov rd_i2c_buf0,#0d0h ;dir mov rd_i2c_buf1,#00h ;dir mov rd_i2c_buf2,#01h ;dir mov rd_i2c_byte_cnt,#03h ACALL ifncI2C_start_Condition ; mov a, #rd_i2c_buf2 ;dir mov R0,a ;dir i2c_Nbyte_loop: mov a,@R0 ACALL ifncI2C_write_8bit ; ACALL ifncI2C_wait_ack ; CJNE A,#0,i2c_Nbyte_error mov a,R0 inc a mov R0,a djnz rd_i2c_byte_cnt,i2c_Nbyte_loop i2c_Nbyte_error: ACALL ifncI2C_stop_Condition ; RET ;case 2: ========= for change to indirect sram ========== ri_i2c_tmp_buf0 equ 80h ri_i2c_tmp_buf1 equ 81h ri_i2c_tmp_buf2 equ 82h ri_i2c_tmp_buf3 equ 83h ri_i2c_tmp_buf4 equ 84h fncI2C_write_Nbyte: mov ri_i2c_tmp_buf0,#0d0h ;indir? mov ri_i2c_tmp_buf1,#00h ;indir? mov ri_i2c_tmp_buf2,#01h ;indir? mov rd_i2c_byte_cnt,#03h ACALL ifncI2C_start_Condition ; mov a, #ri_i2c_tmp_buf0 ;indir? mov R0,a ;indir? i2c_Nbyte_loop: mov a,@R0 ACALL ifncI2C_write_8bit ; ACALL ifncI2C_wait_ack ; CJNE A,#0,i2c_Nbyte_error mov a,R0 inc a mov R0,a djnz rd_i2c_byte_cnt,i2c_Nbyte_loop i2c_Nbyte_error: ACALL ifncI2C_stop_Condition ; RET ;=========================================================
Thanks very much, this bibles are what I needed.
;case 2: ========= for change to indirect sram ========== ri_i2c_tmp_buf0 equ 80h ri_i2c_tmp_buf1 equ 81h ri_i2c_tmp_buf2 equ 82h ri_i2c_tmp_buf3 equ 83h ri_i2c_tmp_buf4 equ 84h fncI2C_write_Nbyte: mov r0,#ri_i2c_tmp_buf0 mov @r0,#0d0h inc r0 mov @r0,#00h inc r0 mov @r0,#01h mov rd_i2c_byte_cnt,#03h ACALL ifncI2C_start_Condition ; mov R0,#ri_i2c_tmp_buf0 ;ok i2c_Nbyte_loop: mov a,@R0 ACALL ifncI2C_write_8bit ; ACALL ifncI2C_wait_ack ; CJNE A,#0,i2c_Nbyte_error inc R0 mov R0,a djnz rd_i2c_byte_cnt,i2c_Nbyte_loop i2c_Nbyte_error: ACALL ifncI2C_stop_Condition ; RET ;=========================================================
There exists at least three issues here. 1. Your last post did not ask a question. You just dumped code into a post. 2. None of your code has been posted properly using the pre tags to preserve formatting. 3. You are corrupting your data pointer (R0) the first pass through i2c_Nbyte_loop.
;========================================================= This should be the right change ! It works on my controller now. ;=========================================================
ri_i2c_tmp_buf0 equ 80h ; buf_0 ri_i2c_tmp_buf1 equ 81h ; buf_1 ri_i2c_tmp_buf2 equ 82h ; buf_2 ri_i2c_tmp_buf3 equ 83h ; buf_3 ri_i2c_tmp_buf4 equ 84h ; buf_4 fncI2C_write_Nbyte: mov r0,#ri_i2c_tmp_buf0 ; r0 <- buf0 address mov @r0,#0d0h ; buf_0 <- 0xD0 inc r0 ; increase buf address mov @r0,#00h ; buf_1 <- 0x00 inc r0 mov @r0,#01h ; buf_2 <- 0x01 mov rd_i2c_byte_cnt,#03h ; total bytes to send ACALL ifncI2C_start_Condition ; mov R0,#ri_i2c_tmp_buf0 ; r0 <- buf0 address i2c_Nbyte_loop: mov a,@R0 ; a <- buf_0 data ACALL ifncI2C_write_8bit ; ACALL ifncI2C_wait_ack ; CJNE A,#0,i2c_Nbyte_error ; ack is not 0, then error exit inc R0 ; increase address buf_n to next address. djnz rd_i2c_byte_cnt,i2c_Nbyte_loop ; check total bytes to send. i2c_Nbyte_error: ACALL ifncI2C_stop_Condition ; RET
That should do it. Good job!