For the following derivations proofs you may use any valid i
Solution
/* ; Studio vi handles this by default
 ;.nolist
 ;.include \"m328def.inc\"
 ;.list
 */
.equ fclk = 16000000 ; system clock frequency (for delays)
; register usage
 .def temporary worker = R16 ; temporary storage
; LCD interface (should accept as true with the diagram above)
 ; confirm that the LCD RW pin is connected to GND
 .equ LCD_D7_port = PORTD ; lcd D7 association
 .equ lcd_D7_bit = PORTD7
 .equ lcd_D7_ddr = DDRD
.equ LCD_D6_port = PORTD ; lcd D6 association
 .equ lcd_D6_bit = PORTD6
 .equ lcd_D6_ddr = DDRD
.equ LCD_D5_port = PORTD ; lcd D5 association
 .equ lcd_D5_bit = PORTD5
 .equ lcd_D5_ddr = DDRD
.equ LCD_D4_port = PORTD ; lcd D4 association
 .equ lcd_D4_bit = PORTD4
 .equ lcd_D4_ddr = DDRD
.equ LCD_E_port = PORTB ; lcd modify pin
 .equ lcd_E_bit = PORTB1
 .equ lcd_E_ddr = DDRB
.equ LCD_RS_port = PORTB ; lcd Register choose pin
 .equ lcd_RS_bit = PORTB0
 .equ lcd_RS_ddr = DDRB
; LCD module info
 .equ lcd_LineOne = 0x00 ; begin of line one
 .equ lcd_LineTwo = 0x40 ; begin of line a pair of
 ;.equ lcd_LineThree = 0x14 ; begin of line three (20x4)
 ;.equ lcd_lineFour = 0x54 ; begin of line four (20x4)
 ;.equ lcd_LineThree = 0x10 ; begin of line three (16x4)
 ;.equ lcd_lineFour = 0x50 ; begin of line four (16x4)
; LCD directions
 .equ lcd_Clear = 0b00000001 ; replace all characters with computer code \'space\'
 .equ lcd_Home = 0b00000010 ; come back pointer to 1st position on 1st line
 .equ lcd_EntryMode = 0b00000110 ; shift pointer from left to right read/write
 .equ lcd_DisplayOff = 0b00001000 ; flip show off
 .equ lcd_DisplayOn = 0b00001100 ; show on, cursor off, do not blink character
 .equ lcd_FunctionReset = 0b00110000 ; reset the LCD
 .equ lcd_FunctionSet4bit = 0b00101000 ; 4-bit information, 2-line show, 5 x 7 font
 .equ lcd_SetCursor = 0b10000000 ; set pointer position
; ****************************** Reset Vector *******************************
 .org 0x0000
 jmp begin ; miss Interrupt Vectors, Program ID etc.
;******************************* Program ID *********************************
 .org INT_VECTORS_SIZE
program_author:
 .db \"Donald Weiman\",0
program_version:
 .db \"LCD-AVR-4d (asm)\",0,0
program_date:
 .db \"Sep eight, 2013\",0
; ****************************** Main Program Code **************************
 start:
 ; initialize the stack pointer to the very best RAM address
 ldi temporary worker,low(RAMEND)
 out SPL,temp
 ldi temporary worker,high(RAMEND)
 out SPH,temp
; tack the microchip pins for the info lines
 sbi lcd_D7_ddr, lcd_D7_bit ; four information lines - output
 sbi lcd_D6_ddr, lcd_D6_bit
 sbi lcd_D5_ddr, lcd_D5_bit
 sbi lcd_D4_ddr, lcd_D4_bit
; tack the microchip pins for the management lines
 sbi lcd_E_ddr, lcd_E_bit ; E line - output
 sbi lcd_RS_ddr, lcd_RS_bit ; RS line - output
; initialize the LCD controller as determined by the equates (LCD instructions)
 decision lcd_init_4d ; initialize the {lcd|liquid crystal show|LCD|digital display|alphanumeric display} display for a 4-bit interface
; show the primary line of knowledge
 ldi ZH, high(program_author) ; purpose to the data that\'s to be displayed
 ldi ZL, low(program_author)
 ldi temporary worker, lcd_LineOne ; purpose to wherever the data ought to be displayed
 decision lcd_write_string_4d
; show the second line of knowledge
 ldi ZH, high(program_version) ; purpose to the data that\'s to be displayed
 ldi ZL, low(program_version)
 ldi temporary worker, lcd_LineTwo ; purpose to wherever the data ought to be displayed
 decision lcd_write_string_4d
; endless loop
 here:
 rjmp here
; ****************************** finish of Main Program Code *******************
; ============================== 4-bit LCD Subroutines ======================
 ; Name: lcd_init_4d
 ; Purpose: initialize the LCD module for a 4-bit information interface
 ; Entry: equates (LCD instructions) established for the required operation
 ; Exit: no parameters
 ; Notes: uses time delays rather than checking the busy flag
lcd_init_4d:
 ; Power-up delay
 ldi temporary worker, one hundred ; initial forty millisecond delay
 decision delayTx1mS
; necessary - At this time the LCD module is within the 8-bit mode and it\'s expecting to receive
 ; eight bits of information, one bit on every of its eight information lines, when the \'E\' line is periodical.
 ;
 ; Since the LCD module is wired for the 4-bit mode, solely the higher four information lines area unit connected to
 ; the microchip and therefore the lower four information lines area unit usually left open. Therefore, when
 ; the \'E\' line is periodical, the LCD controller can scan no matter information has been established on the higher
 ; four information lines and therefore the lower four information lines are high (due to internal pull-up circuitry).
 ;
 ; as luck would have it the \'FunctionReset\' instruction doesn\'t care regarding what\'s on the lower four bits therefore
 ; this instruction is sent on simply the four out there information lines and it\'ll be taken
 ; properly by the LCD controller. The \'lcd_write_4\' subprogram can accomplish this if the
 ; management lines have antecedently been designed properly.
; established the RS and E lines for the \'lcd_write_4\' subprogram.
 cbi lcd_RS_port, lcd_RS_bit ; choose the Instruction Register (RS low)
 cbi lcd_E_port, lcd_E_bit ; confirm E is at the start low
; Reset the LCD controller.
 ldi temporary worker, lcd_FunctionReset ; 1st a part of reset sequence
 decision lcd_write_4
 ldi temporary worker, ten ; four.1 mS delay (min)
 decision delayTx1mS
ldi temporary worker, lcd_FunctionReset ; second a part of reset sequence
 decision lcd_write_4
 ldi temporary worker, two hundred ; one hundred U.S.A. delay (min)
 decision delayTx1uS
ldi temporary worker, lcd_FunctionReset ; third a part of reset sequence
 decision lcd_write_4
 ldi temporary worker, two hundred ; this delay is omitted within the information sheet
 decision delayTx1uS
; Preliminary operate Set instruction - used solely to line the 4-bit mode.
 ; the quantity of lines or the font can not be set at this point since the controller continues to be within the
 ; 8-bit mode, however the info transfer mode is modified since this parameter is set by one
 ; of the higher four bits of the instruction.
 ldi temporary worker, lcd_FunctionSet4bit ; set 4-bit mode
 decision lcd_write_4
 ldi temporary worker, eighty ; forty U.S.A. delay (min)
 decision delayTx1uS
; operate Set instruction
 ldi temporary worker, lcd_FunctionSet4bit ; set mode, lines, and font
 decision lcd_write_instruction_4d
 ldi temporary worker, eighty ; forty U.S.A. delay (min)
 decision delayTx1uS
; ensuing 3 directions area unit laid out in the info sheet as a part of the data formatting routine,
 ; therefore it\'s a decent plan (but most likely not necessary) to try and do them even as mere so redo them
 ; later if the applying needs a distinct configuration.
; show On/Off management instruction
 ldi temporary worker, lcd_DisplayOff ; flip show OFF
 decision lcd_write_instruction_4d
 ldi temporary worker, eighty ; forty U.S.A. delay (min)
 decision delayTx1uS
; Clear show instruction
 ldi temporary worker, lcd_Clear ; clear show RAM
 decision lcd_write_instruction_4d
 ldi temporary worker, four ; one.64 mS delay (min)
 decision delayTx1mS
; Entry Mode Set instruction
 ldi temporary worker, lcd_EntryMode ; set desired shift characteristics
 decision lcd_write_instruction_4d
 ldi temporary worker, eighty ; forty U.S.A. delay (min)
 decision delayTx1uS
; this is often the tip of the LCD controller data formatting as laid out in the info sheet, however the show
 ; has been left within the OFF condition. this is often a decent time to show the show back ON.
; show On/Off management instruction
 ldi temporary worker, lcd_DisplayOn ; flip the show ON
 decision lcd_write_instruction_4d
 ldi temporary worker, eighty ; forty U.S.A. delay (min)
 decision delayTx1uS
 ret
; ---------------------------------------------------------------------------
  ; Name: lcd_write_string_4d
 ; Purpose: show a string of characters on the LCD
 ; Entry: ZH and ZL inform to the beginning of the string
 ; (temp) contains the required DDRAM address at that to start out the show
 ; Exit: no parameters
 ; Notes: the string should finish with a null (0)
 ; uses time delays rather than checking the busy flag
lcd_write_string_4d:
 ; preserve registers
 push ZH ; preserve pointer registers
 push ZL
; fix up the pointers to be used with the \'lpm\' instruction
 lsl ZL ; shift the pointer one bit left for the lpm instruction
 rol ZH
; established the initial DDRAM address
 ori temporary worker, lcd_SetCursor ; convert the plain address to a collection pointer instruction
 decision lcd_write_instruction_4d ; established the primary DDRAM address
 ldi temporary worker, eighty ; forty U.S.A. delay (min)
 decision delayTx1uS
; write the string of characters
 lcd_write_string_4d_01:
 lpm temporary worker, Z+ ; get a personality
 cpi temporary worker, zero ; check for finish of string
 breq lcd_write_string_4d_02 ; done
; arrive here if this is often a sound character
 decision lcd_write_character_4d ; show the character
 ldi temporary worker, eighty ; forty U.S.A. delay (min)
 decision delayTx1uS
 rjmp lcd_write_string_4d_01 ; not done, send another character
; arrive here once all characters within the message are sent to the LCD module
 lcd_write_string_4d_02:
 pop ZL ; restore pointer registers
 pop ZH
 ret
; ---------------------------------------------------------------------------
  ; Name: lcd_write_character_4d
 ; Purpose: send a computer memory unit {of information|of information|of knowledge} to the LCD data register
 ; Entry: (temp) contains the info computer memory unit
 ; Exit: no parameters
 ; Notes: doesn\'t cope with RW (busy flag isn\'t implemented)
lcd_write_character_4d:
 sbi lcd_RS_port, lcd_RS_bit ; choose the info Register (RS high)
 cbi lcd_E_port, lcd_E_bit ; confirm E is at the start low
 decision lcd_write_4 ; write the higher 4-bits of the info
 swap temporary worker ; swap high and low nibbles
 decision lcd_write_4 ; write the lower 4-bits of the info
 ret
; ---------------------------------------------------------------------------
  ; Name: lcd_write_instruction_4d
 ; Purpose: send a computer memory unit of knowledge to the LCD instruction register
 ; Entry: (temp) contains the info computer memory unit
 ; Exit: no parameters
 ; Notes: doesn\'t cope with RW (busy flag isn\'t implemented)
lcd_write_instruction_4d:
 cbi lcd_RS_port, lcd_RS_bit ; choose the Instruction Register (RS low)
 cbi lcd_E_port, lcd_E_bit ; confirm E is at the start low
 decision lcd_write_4 ; write the higher 4-bits of the instruction
 swap temporary worker ; swap high and low nibbles
 decision lcd_write_4 ; write the lower 4-bits of the instruction
 ret
; ---------------------------------------------------------------------------
  ; Name: lcd_write_4
 ; Purpose: send a nibble (4-bits) of knowledge to the LCD module
 ; Entry: (temp) contains a computer memory unit of information with the required 4-bits within the higher nibble
 ; (RS) is designed for the required LCD register
 ; (E) is low
 ; (RW) is low
 ; Exit: no parameters
 ; Notes: use either time delays or the busy flag
lcd_write_4:
 ; established D7
 sbi lcd_D7_port, lcd_D7_bit ; assume that the D7 information is \'1\'
 sbrs temporary worker, seven ; check the particular information worth
 cbi lcd_D7_port, lcd_D7_bit ; arrive here as long as the info was truly \'0\'
; established D6
 sbi lcd_D6_port, lcd_D6_bit ; repeat for every information bit
 sbrs temporary worker, 6
 cbi lcd_D6_port, lcd_D6_bit
; established D5
 sbi lcd_D5_port, lcd_D5_bit
 sbrs temporary worker, 5
 cbi lcd_D5_port, lcd_D5_bit
; established D4
 sbi lcd_D4_port, lcd_D4_bit
 sbrs temporary worker, 4
 cbi lcd_D4_port, lcd_D4_bit
; write the info
 ; \'Address set-up time\' (40 nS)
 sbi lcd_E_port, lcd_E_bit ; modify pin high
 decision delay1uS ; implement \'Data set-up time\' (80 nS) and \'Enable pulse width\' (230 nS)
 cbi lcd_E_port, lcd_E_bit ; modify pin low
 decision delay1uS ; implement \'Data hold time\' (10 nS) and \'Enable cycle time\' (500 nS)
 ret
; ============================== finish of 4-bit LCD Subroutines ===============
; ============================== Time Delay Subroutines =====================
 ; Name: delayYx1mS
 ; Purpose: give a delay of (YH:YL) x one mS
 ; Entry: (YH:YL) = delay information
 ; Exit: no parameters
 ; Notes: the 16-bit register provides for a delay of up to sixty five.535 Seconds
 ; needs delay1mS
delayYx1mS:
 decision delay1mS ; delay for one mS
 sbiw YH:YL, one ; update the the delay counter
 brne delayYx1mS ; counter isn\'t zero
; arrive here once delay counter is zero (total delay amount is finished)
 ret
; ---------------------------------------------------------------------------
  ; Name: delayTx1mS
 ; Purpose: give a delay of (temp) x one mS
 ; Entry: (temp) = delay information
 ; Exit: no parameters
 ; Notes: the 8-bit register provides for a delay of up to 255 mS
 ; needs delay1mS
delayTx1mS:
 decision delay1mS ; delay for one mS
 dec temporary worker ; update the delay counter
 brne delayTx1mS ; counter isn\'t zero
; arrive here once delay counter is zero (total delay amount is finished)
 ret
; ---------------------------------------------------------------------------
  ; Name: delay1mS
 ; Purpose: give a delay of one mS
 ; Entry: no parameters
 ; Exit: no parameters
 ; Notes: chews up fclk/1000 clock cycles (including the \'call\')
delay1mS:
 push YL ; [2] preserve registers
 push YH ; [2]
 ldi YL, low (((fclk/1000)-18)/4) ; [1] delay counter
 ldi YH, high(((fclk/1000)-18)/4) ; [1]
delay1mS_01:
 sbiw YH:YL, one ; [2] update the the delay counter
 brne delay1mS_01 ; [2] delay counter isn\'t zero
; arrive here once delay counter is zero
 pop YH ; [2] restore registers
 pop YL ; [2]
 dowse ; [4]
; ---------------------------------------------------------------------------
  ; Name: delayTx1uS
 ; Purpose: give a delay of (temp) x one U.S.A. with a sixteen megahertz clock frequency
 ; Entry: (temp) = delay information
 ; Exit: no parameters
 ; Notes: the 8-bit register provides for a delay of up to 255 U.S.A.
 ; needs delay1uS
delayTx1uS:
 decision delay1uS ; delay for one U.S.A.
 dec temporary worker ; decrement the delay counter
 brne delayTx1uS ; counter isn\'t zero
; arrive here once delay counter is zero (total delay amount is finished)
 ret
; ---------------------------------------------------------------------------
  ; Name: delay1uS
 ; Purpose: give a delay of one U.S.A. with a sixteen megahertz clock frequency
 ; Entry: no parameters
 ; Exit: no parameters
 ; Notes: add another push/pop for twenty megahertz clock frequency
delay1uS:
 push temporary worker ; [2] these directions do nothing except consume clock cycles
 pop temporary worker ; [2]
 push temporary worker ; [2]
 pop temporary worker ; [2]
 dowse ; [4]
; ============================== finish of your time Delay Subroutines ==============







