;================================================================= ; lpc9107 SFR equates ;================================================================= P0 equ 80h; P0M1x equ 84h; P0M2x equ 85h; P1 equ 90h; P1M1x equ 91h; P1M2x equ 92h; ;------------------ PSW equ 0D0h; ACC equ 0E0h; B equ 0F0h; SP equ 81h; DPL equ 82h; DPH equ 83h; ;------------------ AUXR1 equ 0A2h; CMP1 equ 0ACh; DIVM equ 95h; FMADRH equ 0E7h; FMADRL equ 0E6h; FMCON equ 0E4h; FMDATA equ 0E5h; IEN0 equ 0A8h; IEN1 equ 0E8h; IP0 equ 0B8h; IP0H equ 0B7h; IP1 equ 0F8h; IP1H equ 0F7h; KBCON equ 94h; KBMASK equ 86h; KBPATN equ 93h; PCON equ 87h; PCONA equ 0B5h; PCONB equ 0B6h; PT0AD equ 0F6h; RSTSRC equ 0DFh; RTCCON equ 0D1h; RTCH equ 0D2h; RTCL equ 0D3h; SADDR equ 0A9h SADEN equ 0B9h SBUF equ 99h SCON equ 98h SSTAT equ 0BAh TCON equ 88h; TH0 equ 8Ch; TH1 equ 8Dh; TL0 equ 8Ah; TL1 equ 8Bh; TMOD equ 89h; TRIM equ 96h; WDCON equ 0A7h; WDL equ 0C1h; WFEED1 equ 0C2h; WFEED2 equ 0C3h; ADCON1 equ 97h ADINS equ 0A3h ADMODA equ 0C0h ADMODB equ 0A1h AD1BH equ 0C4h AD1BL equ 0BCh AD1DAT0 equ 0D5h AD1DAT1 equ 0D6h AD1DAT2 equ 0D7h AD1DAT3 equ 0F5h ;================================================================= ; lpc9107 Internal RAM equates ;================================================================= LCD equ 20h ;byte address of first addressable location LCD_RS bit 00h ;LCD Register Select LCD_RW bit 01h ;LCD Read/Write LCD_EN bit 02h ;LCD Enable LCD_D7 bit 07h ;LCD Data port LCD_D6 bit 06h ;LCD Data port LCD_D5 bit 05h ;LCD Data port LCD_D4 bit 04h ;LCD Data port dataflag equ 08h wordflag equ 09h ;================================================================= ; IIC Definitions ;================================================================= SCL equ P0.3 ;I2C serial clock line. SDA equ P0.4 ;I2C serial data line. ;================================================================= ; lpc9107 hardware vectors ;================================================================= org 0000h ; power up and reset vector ajmp init org 000Bh ; timer 0 interrupt vector ajmp init org 001Bh ; timer 1 interrupt vector ajmp init org 0023h ; serial port interrupt vector ajmp init org 002Bh ; brown out interrupt vector ajmp init org 003Bh ; KB interrupt vector ajmp init org 0043h ; comparator interrupt vector ajmp init org 0053h ; watchdog/rtc interrupt vector ajmp init org 006Bh ; TI interrupt vector ajmp init org 0073h ; ADC interrupt vector ajmp init ORG 0080H init: ;programme all lpc9107 pins for quasi bidirectional mov P0M1x, #00000000b mov P0M2x, #00000000b mov P1M1x, #00000000b mov P1M2x, #00000000b mov DIVM, #00h mov ien0, #00h ;turn off all interrupts mov ip0, #0 ;set interrupt priorities (all low) mov SP, #2Fh ;Set stack to start at 30h. clr dataflag clr wordflag ;wait for power-on reset sequence lcall long_delay lcall LCD_init LCD_sendstring: jb wordflag, nextptr mov dptr, #string1 ;string1 is the label where the string is stored sjmp skip1 nextptr: mov dptr, #string2 ;string2 is the label where the string is stored skip1: cpl wordflag clr dataflag mov A, #80H ;Display on, Curson blinking command acall send_byte mov r0, #16d ;sets end of first line loop1: mov a, r0 jz nextadr dec a mov r0, a clr a ;clear Accumulator for any previous data movc a,@a+dptr ;load the character in accumulator jz here ;go to exit if zero setb dataflag ;set flag to show that this is data acall send_byte ;send char inc dptr ;increment data pointer sjmp loop1 ;jump back to send the next character nextadr: mov A, #0C0H ;Display on, Curson blinking command clr dataflag acall send_byte loop2: clr a ;clear Accumulator for any previous data movc a,@a+dptr ;load the character in accumulator jz here ;go to exit if zero setb dataflag ;set flag to show that this is data acall send_byte ;send char inc dptr ;increment data pointer sjmp loop2 ;jump back to send the next character here: acall long_delay ljmp LCD_sendstring string1: DB '0123456789abcdef',0h string2: DB ' Sally Test LCD ',0h LCD_init: acall long_delay setb LCD_D4 setb LCD_D5 setb LCD_D6 setb LCD_D7 setb LCD_RS clr LCD_RW setb LCD_EN mov A, LCD acall write_iic acall long_delay clr LCD_RS ;Selected command register clr LCD_EN ;Enable H->L mov A, LCD acall write_iic acall long_delay mov A, #20H ;Set 4-bit mode clr dataflag ;set flag for control reg acall send_nibble acall long_delay mov A, #28H ;Set 4-bit mode clr dataflag ;set flag for control reg acall send_byte acall long_delay mov A, #28H ;Set 4-bit mode clr dataflag ;set flag for control reg acall send_byte acall delay mov A, #0CH ;Display on, Curson + blinking off clr dataflag ;set flag for control reg acall send_byte ret send_byte: ;assumes the data to be sent is in the accumulator push acc clr LCD_D4 clr LCD_D5 clr LCD_D6 clr LCD_D7 clr LCD_EN mov C, dataflag mov LCD_RS, C mov A, LCD acall write_iic acall delay pop acc ;Write the data (high nibble) rlc A mov LCD_D7, C rlc A mov LCD_D6, C rlc A mov LCD_D5, C rlc A mov LCD_D4, C setb LCD_EN push acc mov A, LCD acall write_iic acall delay clr LCD_EN mov A, LCD acall write_iic acall delay pop acc send_nibble: push acc clr LCD_D4 clr LCD_D5 clr LCD_D6 clr LCD_D7 clr LCD_EN mov C, dataflag mov LCD_RS, C mov A, LCD acall write_iic acall delay pop acc ;Write the data (low nibble) rlc A mov LCD_D7, C rlc A mov LCD_D6, C rlc A mov LCD_D5, C rlc A mov LCD_D4, C setb LCD_EN mov A, LCD acall write_iic acall delay clr LCD_EN mov A, LCD acall write_iic acall delay ret write_iic: ;Initial IIC bus state setb SDA ;If no one else is driving the bus, setb SCL ;it is now idle. jnb SDA, $ ;wait until bus is idle. jnb SCL, $ ;Generate start signal clr SDA ACALL wait_halfbit clr SCL push acc ;store original acc - we need it later - after sending the iic address mov A, #4Eh ;address of IIC expander acall write_byte ;send IIC address ;receiver should respond with ACK. ;this code does not verify that the ACK has been received acall wait_halfbit ; skip ACK setb SCL ; idle the clock line (pretend to read ack) acall wait_halfbit clr SCL ;start databyte ;this is the actual byte to be sent (held in LCD) pop acc ;restore the contents of the acc acall write_byte ;send IIC databyte ;receiver should respond with ACK. ;this code does not verify that the ACK has been received acall wait_halfbit ;skip ACK setb SCL acall wait_halfbit ;send stop bit to end transaction clr SCL ;start sending stop bit clr SDA ;stop bit acall wait_halfbit setb SCL ;drop clock. signals receiver to sample data acall wait_halfbit setb SDA ;drop data. bus is now idle. acall wait_halfbit acall wait_halfbit ret write_byte: ;send an 8 bit word to IIC bus mov r6, #08h ;setup count next_bit: ACALL wait_halfbit rlc A ;rotate next bit into carry mov SDA, C ;set IIC data to carry value setb SCL ;set IIC clock acall wait_halfbit ;wait clr SCL ;drop clock. signals receiver to sample data djnz r6, next_bit ;do next bit setb SDA ;idle the data line ret wait_halfbit: ;wait for one half IIC bit period mov r7, #05d djnz r7, $ ret delay: mov r2, #03h wait_0: mov r3, #0FFh ;reg2 and reg3 wait_1: djnz r3, wait_1 djnz r2, wait_0 ret long_delay: mov r2, #3Fh ;initialise counters wait_2: mov r3, #0FFh ;reg2 and reg3 wait_3: mov r4, #0FFh ;reg2 and reg3 wait_4: djnz r4, wait_4 djnz r3, wait_3 djnz r2, wait_2 ret END