Hi, i'm trying to learn some assembly, ive got a assignment from school to control a lcd screen. I've got some sample code that i mostly understand but i can't figure out what the SBI command does.
Using atmega32, with avr studio 4

sbi	PortD, LCD_E

At this point PortD = 32, and LCD_E = 0 (decimal)
After the sbi line PortD = 36

I don't see how he changes from 32 to 36.

Atmega instruction info:http://iranmicro.ir/Online/Help/avrasm/index.html?html_sbi.htm
Example i've got from school:

; Some notes on the hardware:
;ATmega8 (clock frequency doesn't matter, tested with 1 MHz to 8 MHz)
; PortD.1 -> LCD RS (register select)
; PortD.2 -> LCD RW (read/write) -enable
; PortD.3 -> LCd E (Enable) -RS
; PortD.4 ... PortD.7 -> LCD data.4 ... data.7
; the other LCd data lines can be left open or tied to ground.
 
.include "m32def.inc"
 
.equ	LCD_RS	= 3
.equ	LCD_RW	= 0
.equ	LCD_E	= 2
 
.def	temp	= r16
.def	argument= r17		;argument for calling subroutines
.def	return	= r18		;return value from subroutines
 
.org 0
rjmp reset
 
reset:
	ldi	temp, low(RAMEND)
	out	SPL, temp
	ldi	temp, high(RAMEND)
	out	SPH, temp
	;ser R19
	;out DDRA, R19
 
;LCD after power-up: ("*" means black bar)
;|****************|
;|		  |
 
	rcall	LCD_init
 
;LCD now:
;|&		  | (&: cursor, blinking)
;|		  |
 
	rcall	LCD_delay
	ldi	argument, 'A'	;write 'A' to the LCD char data RAM
	rcall	LCD_putchar

 
;|A&		  |
;|		  |
 
	rcall	LCD_delay
	ldi	argument, 0x80
	;out	PORTA, argument
	;rcall LCD_putchar	;now let the cursor go to line 0, col 0 (address 0)
	rcall	LCD_command	;for setting a cursor address, bit 7 of the commands has to be set
 
;|A		  | (cursor and A are at the same position!)
;|		  |
 
;	rcall	LCD_delay
;	pop	argument	;restore the character
;	rcall	LCD_putchar	;and print it again
	;	rcall	LCD_delay
	;pop	argument	;restore the character
	;rcall	LCD_putchar	;and print it again
	;	rcall	LCD_delay
	;pop	argument	;restore the character
	;rcall	LCD_putchar	;and print it again
 
 
 
;|AA&		  | (A has been read from position 0 and has then been written to the next pos.)
;|		  |
 
loop:	rjmp loop	
 
lcd_command8:	;used for init (we need some 8-bit commands to switch to 4-bit mode!)
	in	temp, DDRD		;we need to set the high nibble of DDRD while leaving
					;the other bits untouched. Using temp for that.
	sbr	temp, 0b11110000	;set high nibble in temp
	out	DDRD, temp		;write value to DDRD again
	in	temp, PortD		;then get the port value
	cbr	temp, 0b11110000	;and clear the data bits
	cbr	argument, 0b00001111	;then clear the low nibble of the argument
					;so that no control line bits are overwritten
	or	temp, argument		;then set the data bits (from the argument) in the
					;Port value
	out	PortD, temp		;and write the port value.
	sbi	PortD, LCD_E		;now strobe E
	nop
	nop
	nop
	cbi	PortD, LCD_E
	in	temp, DDRD		;get DDRD to make the data lines input again
	cbr	temp, 0b11110000	;clear data line direction bits
	out	DDRD, temp		;and write to DDRD
ret
 
lcd_putchar:
	push	argument		;save the argmuent (it's destroyed in between)
	in	temp, DDRD		;get data direction bits
	sbr	temp, 0b11110000	;set the data lines to output
	out	DDRD, temp		;write value to DDRD
	in	temp, PortD		;then get the data from PortD
	cbr	temp, 0b11111110	;clear ALL LCD lines (data and control!)
	cbr	argument, 0b00001111	;we have to write the high nibble of our argument first
					;so mask off the low nibble
	or	temp, argument		;now set the argument bits in the Port value
	out	PortD, temp		;and write the port value
	sbi	PortD, LCD_RS		;now take RS high for LCD char data register access
	sbi	PortD, LCD_E		;strobe Enable
	nop
	nop
	nop
	cbi	PortD, LCD_E
	pop	argument		;restore the argument, we need the low nibble now...
	cbr	temp, 0b11110000	;clear the data bits of our port value
	swap	argument		;we want to write the LOW nibble of the argument to
					;the LCD data lines, which are the HIGH port nibble!
	cbr	argument, 0b00001111	;clear unused bits in argument
	or	temp, argument		;and set the required argument bits in the port value
	out	PortD, temp		;write data to port
	sbi	PortD, LCD_RS		;again, set RS
	sbi	PortD, LCD_E		;strobe Enable
	nop
	nop
	nop
	cbi	PortD, LCD_E
	cbi	PortD, LCD_RS
	in	temp, DDRD
	cbr	temp, 0b11110000	;data lines are input again
	out	DDRD, temp
ret
 
lcd_command:	;same as LCD_putchar, but with RS low!
	push	argument
	in	temp, DDRD
	sbr	temp, 0b11110000
	out	DDRD, temp
	in	temp, PortD
	cbr	temp, 0b11111110
	cbr	argument, 0b00001111
	or	temp, argument
 
	out	PortD, temp
	sbi	PortD, LCD_E
	nop
	nop
	nop
	cbi	PortD, LCD_E
	pop	argument
	cbr	temp, 0b11110000
	swap	argument
	cbr	argument, 0b00001111
	or	temp, argument
	out	PortD, temp
	sbi	PortD, LCD_E
	nop
	nop
	nop
	cbi	PortD, LCD_E
	in	temp, DDRD
	cbr	temp, 0b11110000
	out	DDRD, temp
ret
 
LCD_delay:
	clr	r2
	LCD_delay_outer:
	clr	r3
		LCD_delay_inner:
		dec	r3
		brne	LCD_delay_inner
	dec	r2
	brne	LCD_delay_outer
ret
 
LCD_init:
 
	ldi	temp, 0b00001110	;control lines are output, rest is input
	out	DDRD, temp
 
	rcall	LCD_delay		;first, we'll tell the LCD that we want to use it
	ldi	argument, 0x20		;in 4-bit mode.
	rcall	LCD_command8		;LCD is still in 8-BIT MODE while writing this command!!!
 
	rcall	LCD_delay
	ldi	argument, 0x28		;NOW: 2 lines, 5*7 font, 4-BIT MODE!
	rcall	LCD_command		;
 
	rcall	LCD_delay
	ldi	argument, 0x0F		;now proceed as usual: Display on, cursor on, blinking
	rcall	LCD_command
 
	rcall	LCD_delay
	ldi	argument, 0x01		;clear display, cursor -> home
	rcall	LCD_command
 
	rcall	LCD_delay
	ldi	argument, 0x06		;auto-inc cursor
	rcall	LCD_command
ret

Recommended Answers

All 2 Replies

Hi, i'm trying to learn some assembly, ive got a assignment from school to control a lcd screen. I've got some sample code that i mostly understand but i can't figure out what the SBI command does.
Using atmega32, with avr studio 4

sbi	PortD, LCD_E

At this point PortD = 32, and LCD_E = 0 (decimal)
After the sbi line PortD = 36

I don't see how he changes from 32 to 36.

.equ	LCD_E	= 2

Do you see now?

commented: Very nice - +20

Woa, emmmhh that makes sense. Thank you, think i was looking at it so closely i lost the overview. Thanks! for awsering this silly question then. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.