Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Atmel, assembly:displaying on lcd

Status
Not open for further replies.

Haidy

New Member
Hello
my project is supposed to read temperature,level,pressure so on by ADC and displays the result on lcd
but i didnt use any sensors, i used potenntiometer aas indication on the variation of either level or temp,..so on
also i need to calculate a car's wheel rpm and display on lcd
and as i didnt use a motor at all,i simulated the car wheel rotation by a timer 555, it gives pulses, as if it's pulses from encoder.
anyway,, what i need to know is:

how to convert numbers greater than one byte from binary to decimal ??
also, i need to display time on lcd continously,at the bottom right of lcd,while in the rest of lcd the result of either temp or pressure or speed or level is displayed one at a time.i mean,every time i can display temp & time, or level and time, so on.my problem is that: i need to clear the lcd every time before displaying something new on it,so how can i keep the time displayed always and clear the rest of the lcd??
plz help me with an algorithm this is the only part remaining in my code.

Thanx alot
 
Converting from binary to decimal is accomplished by dividing by successive powers of ten. For sixteen bits start with a divisor of 10,000 and compute quotient and remainder. The use 1000 on the remainder and so forth.

Once the display is clear you only have to update the characters that change. You don't need to clear the display each time you want to write characters to it.
 
Last edited:
Re:

thanx alot sir,i'll try this today.
excuse m to send again if sth stopped with me
i must hand on this project -working - tomorrow
 
RE

Excuse me sir, how can i update characters without sending a clear command?? what instruction or what way?? would u plz tell me???
thank u
 
The usual way is to send a command to position the cursor at a given x and y position. Surprised you didn't notice those commands. You would do well to read datasheets with extreme care.
 
RE

Papabravo said:
The usual way is to send a command to position the cursor at a given x and y position. Surprised you didn't notice those commands. You would do well to read datasheets with extreme care.

I know these commands sir, i just didnt know that they leave text written in a certain position and write my text in the selected position.i thought the original text will vanish
thank u once again
 
URGENT (division in assembly)

Excuse me
i need to ask about something in my code
im working with atmel, assembly language.
my question is:
if i used this instruction DIV AB which keeps the quotient in register A and remainder in register B,,
what if - for example - i used A=137 , B=51

then 137/51=2.68627451

it means accumelator A will contain 2 while B will contain the value 68627451!!???!!!
how come?? the maximum number any register can keep is 255
so where will this number go? or how will it be manipulted with???
please somebody answers me, im finishing my code now & i faced this problem just now

thanx alot
 
Can't help you Atmel stuff, but I can help you with English - I suggest you try finding out what 'remainder' means!.

In your example the remainder is 35.
 
my code

here is my code
i ran it on protus simulator with the hardware but nothing worked at all:

code:

;$MOD52
TCOUNT EQU 20
LST_DIG EQU 00H
SEC_DIG EQU 00H
THIRD_DIG EQU 00H
FOURTH_DIG EQU 00H
FIFTH_DIG EQU 00H
ADC_VALUE EQU 00H
DEC_POINT EQU 00H
ADC1 EQU 00H
ADC2 EQU 00H
T_1 EQU 00H
T_2 EQU 00H
T_3 EQU 00H
ORG 00H
MAIN:
MOV TMOD,#61H ;Timer0 16 bit&Counter1 8bit auto reload
MOV TL0,#0B0H
MOV TH0,#3CH
MOV IE,#8FH ;Enable timer&external interrupts
MOV IP,#0AH ;Highest priority to timer,counter,door then adc conversion
MOV TCON,#54H ;Start timer as soon as system is powered on&Start counter (but it willl found no pulses until we operate the 555 circuit) .Interrupt1 falling edge triggered & Interrupt0 low level triggered
MOV TH1,#0BFH ;Adjust the auto reload value of counter to be 191 in decimal,so that it overflows after each 64 counTS
MOV A,#1FH
MOV P0,A
MOV A,#0FFH
MOV P2,A ;PROGRAMING I/O
MOV A,#5EH
MOV P3,A
MOV A,#0F0H
MOV P1,A
MOV A,#00H
MOV P0,A
MOV A,#00H
MOV P2,A
MOV A,#00H
MOV P3,A
MOV A,#00H
MOV P1,A
LCALL INTIT
MOV A,#'S'
LCALL DATAWRT
LCALL DELAY
MOV A,#'Y'
LCALL DATAWRT
LCALL DELAY
MOV A,#'S'
LCALL DATAWRT
LCALL DELAY
MOV A,#'T'
LCALL DATAWRT
LCALL DELAY
MOV A,#'E'
LCALL DATAWRT
LCALL DELAY
MOV A,#'M'
LCALL DATAWRT
LCALL DELAY
MOV A,#' '
LCALL DATAWRT
LCALL DELAY
MOV A,#'O'
LCALL DATAWRT
LCALL DELAY
MOV A,#'N'
LCALL DATAWRT
LCALL DELAY2
;-----------------
LCALL INTIT_
MOV A,#'1'
LCALL DATAWRT
LCALL DELAY
MOV A,#':'
LCALL DATAWRT
LCALL DELAY
MOV A,#'T'
LCALL DATAWRT
LCALL DELAY
MOV A,#' '
LCALL DATAWRT
LCALL DELAY
MOV A,#'2'
LCALL DATAWRT
LCALL DELAY
MOV A,#':'
LCALL DATAWRT
LCALL DELAY
MOV A,#'P'
LCALL DATAWRT
LCALL DELAY
MOV A,#' '
LCALL DATAWRT
LCALL DELAY
MOV A,#'3'
LCALL DATAWRT
LCALL DELAY
MOV A,#':'
LCALL DATAWRT
LCALL DELAY
MOV A,#'L'
LCALL DATAWRT
LCALL DELAY
MOV A,#' '
LCALL DATAWRT
LCALL DELAY
MOV A,#'4'
LCALL DATAWRT
LCALL DELAY
MOV A,#':'
LCALL DATAWRT
LCALL DELAY
MOV A,#'B'
LCALL DATAWRT
LCALL DELAY
MOV A,#0C0H
MOV A,#'5'
LCALL DATAWRT
LCALL DELAY
MOV A,#'S'
LCALL DATAWRT
LCALL DELAY
MOV A,#'P'
LCALL DATAWRT
LCALL DELAY
MOV A,#'E'
LCALL DATAWRT
LCALL DELAY
MOV A,#'E'
LCALL DATAWRT
LCALL DELAY
MOV A,#'D'
LCALL DATAWRT
LOOP:JB P0.0,TEMP
JB P0.1,PRESSURE
JB P0.2,LEVEL
JB P0.3,BATTERY
JB P0.4,SPEED
JB P3.1,FLASHER
LJMP LOOP
TEMP: CLR P1.1 ;channel 0
CLR P1.2
CLR P1.3
LCALL ADC ;Interrupt1 supposed to happen during this
LCALL LEV_TEMP
LCALL T_LCD
RET
PRESSURE:
SETB P1.1 ;channel 1
CLR P1.2
CLR P1.3
LCALL ADC ;Interrupt1 supposed to happen during this
MOV A,ADC_VALUE
MOV B,#51
DIV AB ;QUOTIENT IN A, remainder in B
ORL A,#30H
MOV ADC1,A ;ASCII of the only integer digit
LCALL INTIT_
LCALL P_LCD
RET
LEVEL: CLR P1.1 ;channel 2
SETB P1.2
CLR P1.3
LCALL ADC ;Interrupt1 supposed to happen after this
LCALL LEV_TEMP
LCALL L_LCD
RET
BATTERY:
SETB P1.1 ;channel 3
SETB P1.2
CLR P1.3
LCALL ADC ;Interrupt1 supposed to happen after this
MOV A,ADC_VALUE
MOV B,#51
DIV AB ;QUOTIENT IN A, remainder in B
ORL A,#30H
MOV ADC1,A ;ASCII of the only integer digit
LCALL INTIT_
LCALL B_LCD
RET
SPEED: MOV A,77H ; NO. OF REVOLUTIONS
MOV B,#60 ;60 SECONDS
MUL AB ; TO GET RPM ;LSB IN A & MSB IN B
MOV R1,B
MOV R0,A
LCALL CONVERT
LCALL INTIT_
LCALL S_LCD
RET
FLASHER:
AGAIN:SETB P0.7 ;LIGHT UP FLASHER LED
LCALL DELAY3
CLR P0.7
LCALL DELAY3
JB P0.7,AGAIN
RET

LEV_TEMP:MOV A,ADC_VALUE
MOV B,#5
DIV AB ;QUOTIENT IN A, remainder in B
MOV 38H,B ;decimal point digit
MOV B,#10
DIV AB ;Quotient in A & Remainder in B
MOV 39H,B ;1st digit
MOV B,#10
DIV AB
MOV 3AH,B ;2nd digit
MOV A,38H
ORL A,#30H
MOV DEC_POINT,A
MOV A,39H
ORL A,#30H ;ascii of 1st digit
MOV ADC1,A
MOV A,3AH
ORL A,#30H ;ascii of 2nd digit
MOV ADC2,A
LCALL INTIT_
T_LCD: MOV A,#'T'
LCALL DATAWRT
LCALL DELAY
MOV A,#'='
LCALL DATAWRT
LCALL DELAY
MOV A,ADC2
LCALL DATAWRT
LCALL DELAY
MOV A,ADC1
LCALL DATAWRT
LCALL DELAY
MOV A,#'.'
LCALL DATAWRT
LCALL DELAY
MOV A,DEC_POINT
LCALL DATAWRT
MOV A,#'C'
LCALL DATAWRT
RET
P_LCD: MOV A,#'P'
LCALL DATAWRT
LCALL DELAY
MOV A,#'='
LCALL DATAWRT
LCALL DELAY
MOV A,ADC1
LCALL DATAWRT
LCALL DELAY
MOV A,#'P'
LCALL DATAWRT
LCALL DELAY
MOV A,#'a'
LCALL DATAWRT
RET
L_LCD: MOV A,#'L'
LCALL DATAWRT
LCALL DELAY
MOV A,#'='
LCALL DATAWRT
LCALL DELAY
MOV A,ADC2
LCALL DATAWRT
LCALL DELAY
MOV A,ADC1
LCALL DATAWRT
LCALL DELAY
MOV A,#'.'
LCALL DATAWRT
LCALL DELAY
MOV A,DEC_POINT
LCALL DATAWRT
MOV A,#'c'
LCALL DATAWRT
MOV A,#'m'
LCALL DATAWRT
LCALL DELAY
RET
B_LCD: MOV A,#'B'
LCALL DATAWRT
LCALL DELAY
MOV A,#'='
LCALL DATAWRT
LCALL DELAY
MOV A,ADC1
LCALL DATAWRT
LCALL DELAY
MOV A,#'V'
LCALL DATAWRT
LCALL DELAY
RET
S_LCD: MOV A,#'S'
LCALL DATAWRT
LCALL DELAY
MOV A,#'p'
LCALL DATAWRT
LCALL DELAY
MOV A,#'e'
LCALL DATAWRT
LCALL DELAY
MOV A,#'e'
LCALL DATAWRT
LCALL DELAY
MOV A,#'d'
LCALL DATAWRT
LCALL DELAY
MOV A,#'='
LCALL DATAWRT
MOV A,FIFTH_DIG
ORL A,#30H
LCALL DATAWRT
LCALL DELAY
MOV A,FOURTH_DIG
ORL A,#30H
LCALL DATAWRT
LCALL DELAY
MOV A,THIRD_DIG
ORL A,#30H
LCALL DATAWRT
LCALL DELAY
MOV A,SEC_DIG
ORL A,#30H
LCALL DATAWRT
LCALL DELAY
MOV A,LST_DIG
ORL A,#30H
LCALL DATAWRT
LCALL DELAY
MOV A,#'R'
LCALL DATAWRT
LCALL DELAY
MOV A,#'P'
LCALL DATAWRT
LCALL DELAY
MOV A,#'M'
LCALL DATAWRT
RET

DELAY4: ;nearly 1 sec
MOV R0,#15
HERE9: MOV R1,#255
HERE10: MOV R2,#255
HERE11: DJNZ R2,HERE11
DJNZ R1,HERE10
DJNZ R0,HERE9
RET

DELAY3: ;nearly 0.45 sec
MOV R6,#7
HERE8: MOV R7,#255
HERE7: MOV 7FH,#255
HERE6: DJNZ 7FH,HERE6
DJNZ R7,HERE7
DJNZ R6,HERE8
RET



INTIT_:MOV A,#38H ;We must be sure that this command suits the 16*2 LCD
LCALL COMNWRT
LCALL DELAY
MOV A,#0EH ;display on,cursor on (blinking)
LCALL COMNWRT
LCALL DELAY
MOV A,#80H ;cursor at line 1 position 0
LCALL COMNWRT
LCALL DELAY
H1: JB P1.7,H1 ;loop till lcd is ready to receive data
RET

DATAWRT:
MOV P1,A
SETB P3.4
CLR P3.6
SETB P3.7
CLR P3.7
RET

DELAY:
MOV R0,#50
HERE: MOV R1,#255
HERE1:DJNZ R1,HERE1
DJNZ R0,HERE
RET

DELAY2:
MOV R3,#75
HERE4: MOV R4,#255
HERE3: MOV R5,#255
HERE2: DJNZ R5,HERE2
DJNZ R4,HERE3
DJNZ R3,HERE4
RET
COMNWRT:
MOV P1,A
CLR P3.4 ;CLR RS
CLR P3.6 ;CLR R/W
SETB P3.7
CLR P3.7
RET
ADC: SETB P3.3 ;MAKE EOC HIGH
CLR P0.5
SETB P0.5 ;L-H PULSE FOR ALE
SETB P3.0
CLR P3.0 ;L-H PULSE TO START CONVERSION
LCALL DELAY3
RET
ConV_DEC: ;The value to be converted is intially stored in A
MOV B,#10
DIV AB ;Quotient in A & Remainder in B
MOV T_1,B ;SAVE LOWEST DIGIT OF TIME
MOV B,#10
DIV AB
MOV T_2,B ;SAVE MIDDLE DIGIT OF TIME
MOV B,#10
DIV AB
MOV T_3,B ;SAVE HIGHEST DIGIT OF TIME
RET
INTERRUPT0:
ORG 0003H
SETB P0.6 ;LIGHT UP DOOR LED
LCALL INTIT_
MOV A,#'D'
LCALL DATAWRT
LCALL DELAY
MOV A,#'o'
LCALL DATAWRT
LCALL DELAY
MOV A,#'o'
LCALL DATAWRT
LCALL DELAY
MOV A,#'r'
LCALL DATAWRT
LCALL DELAY
MOV A,#' '
LCALL DATAWRT
LCALL DELAY
MOV A,#'O'
LCALL DATAWRT
LCALL DELAY
MOV A,#'P'
LCALL DATAWRT
LCALL DELAY
MOV A,#'E'
LCALL DATAWRT
LCALL DELAY
MOV A,#'N'
LCALL DATAWRT
LCALL DELAY
STILL:JB P0.6,STILL
RETI
TIMER0_INTERRUPT:
ORG 00BH
MOV TL0,#0B0H
MOV TH0,#3CH ;Intialize TH1&TL1 so that timer resets every 0.05sec
DJNZ TCOUNT,EXIT
INC 079H
MOV A,79H
LCALL CONV_DEC
LCALL DISP_time
EXIT:RETI
INTERRUPT1:
ORG 013H
SETB P1.0
CLR P1.0 ;Enable o/p
MOV A,P2
MOV ADC_VALUE,A
RETI
COUNTER1_INTERRUPT:
ORG 001BH
CLR TR1
INC 77H
MOV A,77H
CJNE A,#0FFH,GO
Mov 77H,#00H
INC 078H
GO:SETB TR1
RETI
INTIT:MOV A,#38H ;We must be sure that this command suits the 16*2 LCD
LCALL COMNWRT
LCALL DELAY
MOV A,#0EH ;display on,cursor on (blinking)
LCALL COMNWRT
LCALL DELAY
MOV A,#01H ;clear LCD
LCALL COMNWRT
LCALL DELAY
MOV A,#80H ;cursor at line 1 position 0
LCALL COMNWRT
LCALL DELAY
H: JB P1.7,H ;loop till lcd is ready to receive data
RET
DISP_time:
MOV A,#0EH ;display on,cursor on (blinking)
LCALL COMNWRT
MOV A,#0C0H ;FORCE cursor to beginning of line2
LCALL COMNWRT
MOV A,#06H ;shift cursor to right
LCALL COMNWRT
MOV A,#0CAH ;start writing from 11th position,line 2
LCALL COMNWRT
STAY:JB P1.7,STAY ;Wait till lcd ready to receive data
MOV A,#'t'
LCALL DATAWRT
LCALL DELAY
MOV A,#'='
LCALL DATAWRT
MOV A,T_3
ORL A,#30H
LCALL DATAWRT
LCALL DELAY
MOV A,T_2
ORL A,#30H
LCALL DATAWRT
LCALL DELAY
MOV A,T_1
ORL A,#30H
LCALL DATAWRT
LCALL DELAY
MOV A,#'s'
LCALL DATAWRT
RET
CONVERT:
;this piece of code converts a 2 bytes binary number to decimal

;let higher byte be R1 & lower byte be R0
;Convert lower byte
MOV A,R0
MOV B,#10
DIV AB ;Quotient in A & Remainder in B
MOV 31H,B ;lowest digit in lower byte
MOV B,#10
DIV AB
MOV 32H,B ;2nd digit in lower byte
MOV B,#10
DIV AB
MOV 33H,B ;highest digit in lower byte
;Convert higher byte
Mov A,R1
MOV B,#10
DIV AB ;Quotient in A & Remainder in B
MOV 34H,B ;lowest digit in higher byte
MOV B,#10
DIV AB
MOV 35H,B ;2nd digit in higher byte
MOV B,#10
DIV AB
MOV 36H,B ;3rd digit in higher byte
MOV B,#10
DIV AB
MOV 37H,B ;4th digit in higher byte
MOV B,#10
DIV AB
MOV FIFTH_DIG,B ;5th digit in higher byte & highest digit in the number
MOV A,31H
ADD A,34H
MOV B,#10
DIV AB
MOV LST_DIG,B ;lowest digit in the number
ADD A,32H
ADD A,35H
MOV B,#10
DIV AB
MOV SEC_DIG,B ;2nd digit in the number
ADD A,33H
ADD A,36
MOV B,#10
DIV AB
MOV THIRD_DIG,B ;third digit in number
ADD A,37H
MOV FOURTH_DIG,A ;fourth digit in number
RET
END


----------------------------------------------------------------------------
another request plz
if u have working value for timer555 resistors and capacitors plz send it to me,as i used values calculated by special programs but the led was lighting up all the time (not pulsing)
 
Salgat said:
Reading that code is extremely hard on the eyes. Upload it as an attachment with all the correct formatting so its easier to follow the flow of the program.
Or use the code tags to maintain formatting, like this:
bleh.JPG

Either click on the # in the menu just before pasting your code, or type the tags in yourself manually.
Then your posted code will look like this:
Code:
	.org	$0046 
main:	ldi	temp,low(ramend) 	;setup the stack pointer 
	out	spl,temp 
	ldi	temp,high(ramend)
	out	sph,temp 
	ldi	mp,0b11111111		;set PORTB to all outputs 
	out	DDRB,mp 
	ldi	mp,0xff			;turn off all LEDs 
	out	PORTB,mp 
loop:	ldi	mp,0b01111111 
	out	PORTB,mp 
	ldi	temp,5
	rcall	delay
Instead of like this:

.org $0046
main: ldi temp,low(ramend) ;setup the stack pointer
out spl,temp
ldi temp,high(ramend)
out sph,temp
ldi mp,0b11111111 ;set PORTB to all outputs
out DDRB,mp
ldi mp,0xff ;turn off all LEDs
out PORTB,mp
loop: ldi mp,0b01111111
out PORTB,mp
ldi temp,5
rcall delay
 
Last edited:
Haidy said:
...
what if - for example - i used A=137 , B=51

then 137/51=2.68627451

it means accumelator A will contain 2 while B will contain the value 68627451!!???!!!
how come?? ...
No the quotient will be equal to 2 as you have surmised. The remainder will be
Code:
137 - (2 * 51) = 35
What does the remainder represent? Why it is the fraction of the divisor that is left over, and as you have already noted
Code:
35 / 51 = 0.686274509
I guess my calculator has more digits. You might also notice that 35/51 is an exact result, while the decimal expression is approximate.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top