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.

mstechca

New Member
I was wondering, if I executed the following instruction:

MOV <port address>, <data>

and if I used a 555 to generate the clock pulses to the microcontroller,
How many complete cycles (on and off's) must the timer produce before the instruction above is processed?

I'm asking this because I want to eventually save some bytes in my code when displaying text on an LCD.

For now, when I want to write to the LCD, I have to always set and clear a bit that is tied to the enable line. This setting and clearing wastes 2 bytes per character.

What I intend to do is make a counter whose clock pin is tied to the 555's output and when the counter reaches the correct number (which is what I need to know), the "enable" pin of the LCD will then be pulsed and the counter is reset.
 
mstechca said:
I was wondering, if I executed the following instruction:

MOV <port address>, <data>

and if I used a 555 to generate the clock pulses to the microcontroller,
How many complete cycles (on and off's) must the timer produce before the instruction above is processed?
for 8051 one instruction cycle is 12 clock cycle
 
akg said:
for 8051 one instruction cycle is 12 clock cycle

Does this also apply to every single instruction even though some instructions require more bytes than others?

Also, are pull-up or pull-down resistors required to make an LCD work properly with an 8051?
 
Better check the data sheets for at least two reasons.

1) Different instructions take different number of i-cycles to complete.

2) There are 8051s that follow the original Intel 12-clocks per i-cycle, and there are 8051s that use 4-clocks per i-cycle timing.
 
mstechca said:
For now, when I want to write to the LCD, I have to always set and clear a bit that is tied to the enable line. This setting and clearing wastes 2 bytes per character.

You should google "subroutine" as at the moment you appear to be wasting lots of bytes per character.

Mike.
 
I find it amusing and quaint in these days of abundant cheap memory, that anybody would waste ther precious time worrying about such things. For pity's sake, just write the application and get on with it. Picking bytes and nanoseconds is so last century.
 
and if I used a 555 to generate the clock pulses to the microcontroller

Is this on the Intel 8051? AFAIK, the 8051 (MCS-51) or even the i80C51 are not designed for static operation. I.E., they can only operate above a minimum frequency. I think it's about 500Khz-3.5Mhz depending upon the clock speed rating. A 555 timer cannot operate reliably at even these minimum speeds.
 
Motion,

You let the cat out of the bag. He was supposed to discover this on his own.
 
Papabravo said:
I find it amusing and quaint in these days of abundant cheap memory, that anybody would waste ther precious time worrying about such things. For pity's sake, just write the application and get on with it. Picking bytes and nanoseconds is so last century.

NOT on micro-controllers, where you might only have 1024 words of program memory, or even 512 words, and a couple of dozen bytes of RAM.

It's that attitude that has led to such poorly written programming, where you need massively fast machines to make it even useable - where if it's written correctly a machine of 1/10th the speed could easily be faster!.
 
Ever heard of the BUSY flag?

You have to read the busy flag to know if you'r LCD is ready to receive the next character.

Did you check the µC board I posted in the thread "80C51 code not working" started by ....... yes you know him :lol: :?:
Do you see any pull-up or pull-down resistors around connector X1 (the LCD connector)?

An LCD in not only datalines, you have to enable the chip and select read or write function. That isn't working by itself, you have to write code to set and reset these lines.
If you're clever enough you write a subroutine for writing one character to the LCD so you write only once set/reset enable at the beginning of the routine and reset/set just before leaving the routine. Call that subroutine for each character you want to write to the LCD. That isn't byte consuming.
Reusable small subroutines, that's the clue to good µC programming.
 
Nigel,

Once upon a time I would have agreed with you. In those days there were only a few alternatives for embedded design. Picking bytes and nanoseconds was an imperative. The number of choices has exploded to the point where drop in replacements with more resources are available in abundance with little or no increase in cost. There is just so little return on investment to save a trivial number of bytes or cycles. In the 1970's silicon was expensive and people were very very cheap. A company could afford to pay a programmer to spend large numbers of hours optimizing assembly code. There were no stinking compilers in those days. In the 21st century silicon is so cheap and prorammers are so expensive that time to market is the imperative and not necessarily the use of a minimal amount of resources. Time to market rules, everything else is flyspecks in the pepper.
 
Papabravo said:
Nigel,

Once upon a time I would have agreed with you. In those days there were only a few alternatives for embedded design. Picking bytes and nanoseconds was an imperative. The number of choices has exploded to the point where drop in replacements with more resources are available in abundance with little or no increase in cost. There is just so little return on investment to save a trivial number of bytes or cycles. In the 1970's silicon was expensive and people were very very cheap. A company could afford to pay a programmer to spend large numbers of hours optimizing assembly code. There were no stinking compilers in those days. In the 21st century silicon is so cheap and prorammers are so expensive that time to market is the imperative and not necessarily the use of a minimal amount of resources. Time to market rules, everything else is flyspecks in the pepper.

In what way does that apply to micro-controllers? -, perhaps:

"lets scrap our $1.50 PIC design, I can't make my LED flasher program fit, we'll go for a Pentium 4 instead with 512Mb of RAM - only $400" :lol:

You only pay the programmer ONCE (hopefully!), but for every unit you produce you pay the increased hardware costs EVERY TIME.
 
Nigel,

You know perfectly well we are not talking PICs versus pentiums here. We are talking about a PIC16F628 vs a PIC16F648. When you cross the codes space boundry you have some choices to make. If you run out of cycles you have some choices to make. Until you reach those points it just doesnt matter.

Are you not fond of pointing out to all who want to use the PIC16F84 that they should scrap those entirely useful parts and adapt their designs to the PIC16F628. You may be entirely correct for lots of reasons. If however success means making use of what you have, your advice fallls flat on its face. I think your attitude and your comments abuse hyperbole for effect and are borderline hypcritical. In most PIC sockets there are choices for different memory sizes. In most cases the cost difference is insignificant. In addition the trend is for time and technology to always produce more resources at the same or lower cost.
 
Papabravo said:
Nigel,

You know perfectly well we are not talking PICs versus pentiums here. We are talking about a PIC16F628 vs a PIC16F648. When you cross the codes space boundry you have some choices to make. If you run out of cycles you have some choices to make. Until you reach those points it just doesnt matter.

Actually the thread is about 8051's, NOT PIC's.

And your comment earlier "these days of abundant cheap memory" can hardly apply to any PIC - which, by no stretch of the imagination, can be considered to have "abundant memory". While sloppy programming can reasonably be applied to PC's, there's rarely a decent reason to apply it to PIC's, where resources are so limited to begin with.

Are you not fond of pointing out to all who want to use the PIC16F84 that they should scrap those entirely useful parts and adapt their designs to the PIC16F628.

I've never suggested that people should SCRAP their 16F84's, just that they shouldn't BUY them any more, and shouldn't have done since well back in the last century. Personally I've still got a number of 16C84 sat at home, which I occasionally use in projects (I was given a fair few a number of years ago, along with hundreds of OTP PIC's, which I gave away - actually on these forums) - but I'd never publish a design suggesting using one.
 
Nigel,

I take your point about the 16F84, and your recomendations with respect to that part.

Rather than continuing on this thread, I've started a new one in ****-Chat where we can continue this discussion. I think these issues are important and worthy of broader exposure. I await the replies from you and hopefully others as well.

PB
 
Haha. It's like hate on Nigel day today. I think it's karma, because he wanted to see that guys PCB's break. Sorry for the off topic.

I thought the whole reason the 8051 was being used in this project was so that you could have 128k of program ROM. LCD routines should take less than 1/2 a K, if that. Despite Nigels rant on coding effeciency, implementing a 555 timer and supporting hardware seems like alot of work to save even a few byte of code. It certainly doesn't fall under the 'effecient code saves hardware cost' argument.
 
I have thought about subroutines, but I think it requires more bytes.

This is what I do now to send data to an LCD:

Code:
mov <port 1 address>, <8-bit data>
clr P3.0
setb P3.0

clr = clear bit, and setb = set bit. P3.0 is connected to the "enable" pin of the LCD. Port 1 is connected to the LCD data pins.

This is what I would have done, had I used subroutines:

Code:
mov <port 1 address>, <8-bit data>
<code to jump to the subroutine>

The jumping code could be as simple as a jump statement, but it would save me only 50% of code.

If I timed the "enable" pin with an external timer, my code will be like this:
(port 3.0 determines whether the external timer is enabled or not. 1 = yes.)
Code:
setb P3.0
mov <port 1 address>, <8-bit data>
mov <port 1 address>, <8-bit data>
mov <port 1 address>, <8-bit data>
....
mov <port 1 address>, <8-bit data>
mov <port 1 address>, <8-bit data>
mov <port 1 address>, <8-bit data>
clr P3.0
This way is much better! I save at least 2 - 4 bytes of code per character. Multiply that by a 2x16 character display, I would save 64 - 128 bytes.
So instead of using 5 - 7 bytes of code, I use 3 bytes (just for a MOV instruction) per letter.

But the only problem that I might have is with the timing. If I can get the enable pin to go low, then high, the moment the MOV instruction is complete, and have the same happen for every MOV instruction thereafter, I will be happy. Also, if P3.0 is cleared, the external timing doesn't count, and the LCD is then not written to. So I treat P3.0 as the "write enable" byte.

Actually I'm using the 7555 right now. I'm just saying "555" because it is easier to type in.

Also, I notice that my rom and the 8051 works well with each other but the output of the ports either produce a strong logic high, or in between high, and low. In other words, if I tied an LED with a resistor between a port pin and ground, the light goes bright, or dim, but never off.

This makes me think that I need pull-down resistors.

my 8051 is the intel 80C51BH.
 
I'm only taking a stab at this, but it looks like your thinking the subroutine can only work on a character at a time when the subroutine should be created to output a string of data. Pass a pointer to a null terminated string of data in ROM or RAM and let the subroutine output the full string, rather than create a subrouting that just outputs individual characters.
 
DirtyLude said:
I'm only taking a stab at this, but it looks like your thinking the subroutine can only work on a character at a time when the subroutine should be created to output a string of data. Pass a pointer to a null terminated string of data in ROM or RAM and let the subroutine output the full string, rather than create a subrouting that just outputs individual characters.

I like your idea, but I think it isn't just "that" easy.

I don't think there is a single op code for the 8051 chip that can transfer more than one byte at a time to an output port.

Remember, that I am directly programming the ROM with the opcodes, so my instructions are limited to whatever is in the 8051 instruction set.
 
I'm thinking you haven't done much programming before. 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.

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.

This subroutine will continuously loop through each character in the string and output it to the LCD until it hits a null terminating character. 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. I'm assuming the 8051 has a Jump SubRoutine and RETurn from subroutine instruction like every other uC and uP I've seen.

If you want to be fancy you can set a timer with an interrupt service routine (ISR) to continously look to see if LCD data is available and output it in the background.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top