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.

It's regarding the 8051

Status
Not open for further replies.
Have a look at **broken link removed** especially the Print subroutine.

I'll include the relevant bits here for completeness.
Code:
   lcall   print          ; print welcome message
   db 0ah, 0dh,'TOMS 8051 MONITOR   Jul 13,1997',0ah, 0dh
   db 'press h for help',0ah, 0dh, 0h


;===============================================================
; subroutine print
; print takes the string immediately following the call and
; sends it out the serial port.  the string must be terminated
; with a null. this routine will ret to the instruction
; immediately following the string.
;===============================================================
print:
   pop   dph              ; put return address in dptr
   pop   dpl
prtstr:
   clr  a                 ; set offset = 0
   movc a,  @a+dptr       ; get chr from code memory
   cjne a,  #0h, mchrok   ; if chr = ff then return
   sjmp prtdone
mchrok:
   lcall sndchr           ; send character
   inc   dptr             ; point at next character
   sjmp  prtstr           ; loop till end of string
prtdone:
   mov   a,  #1h          ; point to instruction after string
   jmp   @a+dptr          ; return

Obviously, you will have to change the sndchar so that it writes to the LCD. Can you see from this example why hardware has never been designed to do what you are trying to accomplish?


Mike.
 
DirtyLude said:
I'm thinking you haven't done much programming before.

I have programmed PC's and the AT89C2051 uC.

It goes like this:

You store an address to the start of the string that you want to output to the LCD in a RAM word. Then call the write lcd subroutine.
I understand what you guys mean by storing a word in memory,
it's just like calling the DOS print string interrupt in assembly, and sending the segment:eek:ffset address of the string ending in $ as the parameter.

I still don't think this method uses less bytes.

The subrouting begins:
It checks to see if the byte at the address is a null or not. If it is, it returns.
It outputs the byte located at that address to the LCD.
It increments the address by one.
Operation goes back to the beginning above.
I think you got a point. Now if I can do a direct external memory read to the port, I think I'm all set.

I just didn't realize that the 8051 was so much flexible.

This subroutine will continuously loop through each character in the string and output it to the LCD until it hits a null terminating character.
This is an excellent way to go.

Obviously the routine will be more complex because there's more to writing to an LCD than just writing to the port as fast as you can.
The routine is probably simple enough if I can get a "return" related command. But I just have to watch out for the minimum LCD timing.

I actually got my LCD to display text. This is after I used a 1K pull-down resistor from the Enable line to -ve, and I used port P3.6 and P3.7 as my enable and RS lines.
Before, I used P3.0, and P3.1 without success.
 
Programming them how? cuz at the risk of being condescending, this is extremely basic programming concepts. As for the 8051 being flexible, I'm not certain how it's more flexible than any other uC.

I'm not certain why you don't think it will save bytes, considering you'll only have a single 20 byte or so subroutine that replaces all the that processing you would do for each individual byte you want outputted to the LCD. The code that Pommie posted looks just like what you should be looking for. The top code shows the define in ROM space of the text you want outputed, and the single call to the subroutine outputs the 40 or 50 bytes of data before returning.

I'm surprised you can't find a freely available set of 8051 LCD routines. Usually it's helpful to have a routine that converts binary to ascii for displaying numeric as well, and for code readability it's nice to have seperate routines for specific code tasks, like clearing the display and stuff.
 
I'm sure there are several routines, but a large number of them have more symbolic instructions which I cannot convert directly into machine code using the instruction set.

I program the bytes into the EEPROM directly. I can convert simple instructions into byte-codes using the instruction set.

then I take the EEPROM as the external code memory to the 8051.

When I see instructions like:

MOV P3.0, LCDADDR

I will have to first determine the actual memory location of P3.0, then I have to determine the contents of LCDADDR. and if the code requires a library containing the values, it will take much longer to understand.
 
If you insist on rubbing sticks together while the rest of the world uses matches then you will continue to fail. Personally, I prefer AirCon and Central Heating.

The best low priced component for trouble shooting is the brain.

Mike.
 
Like I already said you have to check the busy flag of the LCD instead of using external "555" based hardware :evil:
RS: low // R/W: high // read port 3 instead of writing to port 3
bit 7 is busy flag 1: Internally operating // 0: can accept instruction

As long as you go with your machine code thing no one here can help you out. Try the Keil site and download a free evaluation of the 8051 compiler (limited to 2K of programm).

This routine writes one character to the LCD.
Code:
WriteCharacter: mov  dptr,#LCD_DataRegister   ;chracter to LCD
                        mov  a,LCD_3
                        call LCD_Ready
                        movx @dptr,a


This routines check if the LCD is ready to receive an instruction
Code:
LCD_Ready:  push acc	;save registers
                    push dph
                    push dpl
LBL_001:       mov  dptr,#LCD_StatusRegister
                    movx a,@dptr
                    jb   LCD_Busy,LBL_001	;Still busy ??
                    pop  dpl		;restore registers
                    pop  dph
                    pop  acc
                    RET			;END LCD_Ready
As long as the LCD is busy the program loops here.


Of course you have to define some things
Code:
LCD_Busy	                                bit    ACC.7
LCD_InstructionRegister	equ  8000h
LCD_DataRegister	                equ  8001h
LCD_StatusRegister	                equ  8002h
LCD_ReadDataRegister	equ  8003h
 
Like I already said you have to check the busy flag of the LCD instead of using external "555" based hardware

I understand you completely, BUT I could just ground the write pin. I want to use the 555 timer, so that it can determine when I can send the next character. I will set the 555 timer to a fixed frequency that is known to work with the LCD, then I will have the 555's output trigger the timer input so that the internal timer can increment, and eventually, I can halt the code until a timer overflow occurs. The wait code is basically 2 bytes!

I can't remember the exact name of the timer 0 overflow tag, but I will use T0F to indicate it.

Here is the code:

Code:
JNB TOF, FEh

This code means that the processor (according to a user's standpoint) will do absolutely nothing until the timer is overflowed. When it is overflowed, code continues.

Another thing that needs to be considered is that I don't have too many bytes to play with from the microprocessor. I'm lucky I can use 10, 8 of them being Port 1, and the other 2 are P3.6 and P3.7. I can use P3.6, and P3.7, just because I am not dealing with external RAM.

Now if I encountered an application where the processing functions are much more important than what is displayed on an LCD (like if the processor was part of a PC modem for example), I should then be able to remove the LCD from the circuit, and the circuit should still run. My code shall allow that. If I were to depend on the "busy" flag, then the code will halt forever.

I'm sorry if I am leaning in my own direction on this, but I like code that is optimal, and that doesn't 100% on other things, especially if they are unimportant. Perhaps this is the idea Microsoft had when developing Windows.

By the way, It is called "Multitasking".
Thank god interrupts exist.
 
Honestly, I find mixing a 555 timer with a microcontroller very weird.

Once you take the micrcontroller path, there is no need for an external timer to generate delays because all microcontrollers (8051 included) have them built-in.

I can easily find ways of doing what you described without the 555 timer.

Adding the 555 timer costs money too!
 
You keep trying to simplify things and all you are doing is making it harder on yourself.

Put a pull down on the busy flag. When the LCD is not connected Write operations will still occur.

If you insist on doing it using this delay method, use an internal 8051 timer. That's the kind of thing the internal timers are there for, or just make a simple delay routine and place it in your lcd_display subroutine.

BTW, in no way can what you are doing be considered "Multitasking".
 
DirtyLude said:
If you insist on doing it using this delay method, use an internal 8051 timer
Now that I think about it (between my last visit and now), I think that idea will actually work.

BTW, in no way can what you are doing be considered "Multitasking".
It is kind-of multitasking because the timer is only dependant on the 8051's external clock. It has nothing to do with the code except for raising the overflow flag when the timer exceeds the maximum value.

While the character is written to the LCD, the timer is incremented at the same time. This is where multitasking occurs.

Multitasking doesn't occur when the code is stuck in the loop where it waits for the overflow bit.
 
mstechca said:
DirtyLude said:
If you insist on doing it using this delay method, use an internal 8051 timer
Now that I think about it (between my last visit and now), I think that idea will actually work.

Of course it will work, it's one of the two methods LCD's are driven, the other (far better) one is to read the busy flag, this provides maximum speed, using a delay means it has to delay LONGER than the longest possible delay - different LCD functions take different amounts of time, so the delay method is considerably slower.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top