📄 i2c.asm
字号:
lcall Inc_dptr1Write_EEProm mov R0, #0x01 ; Write 01h (1 byte to be loaded) lcall Inc_dptr1Write_EEProm mov R0, #0x7F ; Write 7Fh (Load to the CPUCS register) ; The CPUCS register is located at 7F92h lcall Inc_dptr1Write_EEProm mov R0, #0x92 ; Write 92h lcall Inc_dptr1Write_EEProm mov R0, #0x00 ; Write 00h (Take the 8051 out of reset) lcall Inc_dptr1Write_EEProm ;; That's all folks! ret ;+--------------------------------------------------------+;| dptr1 switchover and increment plus writing the EEProm |;| |;| dptr1 is used and modified | ;+--------------------------------------------------------+; This is a code-size reducing sub-routine for the SelfLoader routine.; It is pretty useless outside that context.; Inc_dptr1Write_EEProm: mov R1, DPH1 mov R2, DPL1 inc DPS inc dptr inc DPS lcall EEProm_write ret ; These I2C routines are based upon the Cypress application note: ; "Programming a 24L00 EEPROM using the EZ-USB I睠 Port".;; These routines assume an EEProm wired with A0=1, A1=0, and A2=0. ; For different setups, modify the nessesary EEProm address fields in these; routines. (The affected bytes are 10100010 (write) and 10100011 (read)) ;+--------------------------------------+;| High-level I2C EEProm Write routines |;| |;| R0, R1, and R2 are used and modified | ;+--------------------------------------+; R0 contains the source data word. ; R1 (MSB) and R2 (LSB) the destination addresses;EEProm_write: push acc ; Save the accumulator on the stack mov a, dph ; Save the dptr on the stack push acc mov a, dpl push acc lcall stop_check ; Make sure stop is not in progress mov dptr, #I2CS ; Set the start bit mov a, #10000000b ; B7 = start bit movx @dptr, a mov dptr, #I2DAT ; Write the EEProm address 10100010 and mov a, #10100010b ; indicate write operation (B0=0) movx @dptr, a lcall wait_done mov dptr, #I2DAT ; Send the EEProm "MSB word address" mov a, R1 movx @dptr, a lcall wait_done mov dptr, #I2DAT ; Send the EEProm "LSB word address" mov a, R2 movx @dptr, a lcall wait_done mov dptr, #I2DAT ; Send the actual data mov a, R0 movx @dptr, a lcall wait_done mov dptr, #I2CS ; Send stop. This initiates the internal mov a, #01000000b ; write cycle movx @dptr, a lcall stop_check ; Wait for completion of stop;Wait for the erase/write cycle to complete. This is done by sending;a write command byte and checking the ACK bit. The EEProm will not respond; (ACK) while a write cycle is in progress.;write_wait: mov dptr, #I2CS ; Send start mov a, #10000000b ; B7 = start bit movx @dptr, a mov dptr, #I2DAT ; Write a command byte mov a, #10100010b ; EEProm write movx @dptr, a lcall wait_done mov dptr, #I2CS ; Send stop mov a, #01000000b movx @dptr, a lcall stop_check ; Wait for completion of stop mov dptr, #I2CS ; Check the ACK bit movx a,@dptr jnb acc.1, write_wait ; Keep trying until ACK=1 pop acc ; Restore the dptr and accumulator mov dpl, a pop acc mov dph, a pop acc ret;+--------------------------------------+;| Low-level I2C supportive routines |;| |;| R0, A and DPTR are used and modified | ;+--------------------------------------+; stop_check: mov dptr, #I2CS ; Check the stop bit in I2CSstck: movx a, @dptr jb acc.6, stck ret wait_done: mov dptr, #I2CS ; Check the done bit in I2CSwado: movx a,@dptr jnb acc.0,wado ret ;+------------------------------------+;| High-level LCD routines |;| |;| R0 and DPTR are used and modified. |;+------------------------------------+; Store the LCD DD-RAM starting address for the line on which to write in R0.; Store the begin address of the string in the DPTR; The string must terminate with a '0'.;write_string: push acc ; Move the accumulator on the stack mov a, r0 ; Build the correct comand to write the string orl a, #10000000b ; starting address for the LCD DD-RAM mov r0, a lcall send_command loop_write_string: mov a, #0x00 ; Read the string from the code memory and movc a, @a+dptr ; write to the display until a terminating mov r0, a ; 0x00 is found jz end_write_string lcall send_data inc dptr sjmp loop_write_string end_write_string: pop acc ; Retrieve the accumulator from the stack ret;+--------------------------+;| Low-level LCD routines |;| |;| R0 is used and modified. |;+--------------------------+; R0 carries the byte to be written to the display for both "send" routines;send_command: push acc ; Move the accumulator on the stack mov a, dpl ; Move the dptr on the stack push acc mov a, dph push acc mov dptr, #OUTA ; Set RS low mov a, #00000000b movx @dptr, a mov dptr, #OUTC ; Write data to PC mov a, r0 movx @dptr, a mov dptr, #OUTA ; Set EN high mov a, #00100000b movx @dptr, a mov r0, #0 ; Kludge to fix R0 dependency in the delay lcall Wait10usec ; routines mov dptr, #OUTA ; Set EN low mov a, #00000000b movx @dptr, a pop acc ; Retrieve datapointer form the stack mov dph, a ; This and the RET give sufficient delay pop acc ; to allow the display to process the data mov dpl, a pop acc ; Retrieve the accumulator from the stack ret send_data: push acc ; Move the accumulator on the stack mov a, dpl ; Move the dptr on the stack push acc mov a, dph push acc mov dptr, #OUTA ; Set RS high mov a, #00010000b movx @dptr, a mov dptr, #OUTC ; Write data to PC mov a, r0 movx @dptr, a mov dptr, #OUTA ; Set EN high mov a, #00110000b movx @dptr, a mov r0, #0 ; Kludge to fix R0 dependency in the delay lcall Wait10usec ; routines mov dptr, #OUTA ; Set EN low mov a, #00010000b movx @dptr, a pop acc ; Retrieve datapointer form the stack mov dph, a ; This and the RET give sufficient delay pop acc ; to allow the display to process the data mov dpl, a pop acc ; Retrieve the accumulator from the stack ret init_LCD: lcall Wait100msec ; Power-up reset delay safety mov r0, #00110000b ; Function set (8-bit interface) lcall send_command mov r0, #0 ; Kludge to fix R0 dependency in the delay routines lcall Wait1msec ; Wait for at least 4.1 ms (already 2 in the lcall Wait1msec ; send_command routine) mov r0, #00110000b ; Function set (8-bit interface) lcall send_command mov r0, #00110000b ; Function set (8-bit interface) lcall send_command mov r0, #00111000b ; Function set (8-bit interface, Dual(4) line, lcall send_command ; Display font) mov r0, #00001000b ; Display off lcall send_command mov r0, #00000001b ; Display clear lcall send_command mov r0, #00000110b ; Entry mode set lcall send_command mov r0, #10000000b ; Line one, position one lcall send_command mov r0, #00001100b ; Display on lcall send_command ret ;+----------------------------------------------------------------------+;| Timing loops taken from the buttons and lights example in USB Design |;| by Example. These are needed by the LCD routines. |;| |;| A, DPTR and R0 are used and modified. |;+----------------------------------------------------------------------+; Wait100msec: mov r0, #100Wait1msec: ; A delay loop mov dptr,#-1200More: inc dptr ; 3 cycles mov a,dpl ; + 2 orl a,dph ; + 2 jnz More ; + 3 = 10 cycles x 1200 = 1msec djnz r0, Wait1msec ; retWait50usec: mov r0, #5Wait10usec: mov dptr, #-12More2: inc dptr mov a, dpl orl a, dph jnz More2 ; 10 cycles x 12 = 10usec djnz r0, Wait10usec ret.org 0x1000;+-------------------------------+;| Some text-strings for the LCD |;+-------------------------------+; .db "EZ-USB I2C test ",0x00.db " With an 24C64 ",0x00.db " Serial EEPROM ",0x00.db "Wolf Engineering",0x00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -