Moving from 8051 to AVR

That's because the 80C51 was DESIGNED as a Single Chip Microcontroller, and the tasks done by small uC, do not really change with time. So it has great features for small, embedded control, data sets.

The AVR actually started life as an ASIC core, where efficent memory access was not really on the radar, but small gate count was.

Its had a number of band-aid fixes as time has gone by; IIRC the latest one is psuedo boolean variables, as it tries to morph into a better Microcontroller.

If you want to see a good example of a register-register Microcontroller design, look at the Zilog Z8. That has real features like direct memory opcodes, and register frame pointer - but of course, this was another whole chip designed as a Microcontroller. Both the Z8 and C51 use variable length opcodes.

-jg

Reply to
Jim Granville
Loading thread data ...

In article , diggerdo writes

Most are now divide by 6, 4 or2 with some on single cycle.

Last time I looked there were about 600 variants from over 40 manufacturers

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
 Click to see the full signature
Reply to
Chris Hills

Arrghhh!

--

John Devereux
Reply to
John Devereux

Here we go again, the tail wagging the dog. A micro 'designed' to use C is not a recommendation its a good reason not to use it.

Ian

Reply to
Ian Bell

Tail wagging the dog again.

Ian

Reply to
Ian Bell

Why do you say that? If you want to complain that C is a badly designed language, that's fair enough - you'll get plenty of agreement there. But generally speaking, being "designed for C" means the cpu must have support for accessing data on a stack through some sort of index, and it should have fast access to data through a pointer or two. Where is the disadvantage in that? Some high level languages could benefit from other features (Forth would benefit from direct stack operations, Pascal would benefit from a frame pointer, etc.). Some types of code cannot be conveniently expressed in C (bit variables, rotation, dsp-type operations), but being designed for C doesn't mean non-C operations not supported. And from experience writing assembly code on "C-friendly" and "non-C-friendly" architectures, I have no doubt that being C-friendly is a big plus.

The AVR is not actually very C-friendly - it is merely somewhat IAR-C-friendly (although far better than the 8051). The msp430 is probably the best example of a C-friendly cpu.

Reply to
David Brown

Another veteran of the page-boundary wars, I presume?

--
Grant Edwards                   grante             Yow!  As a FAD follower,
                                  at               my BEVERAGE choices are
 Click to see the full signature
Reply to
Grant Edwards

If you want/need to use C, it seems like a pretty good recommendation to me.

--
Grant Edwards                   grante             Yow!  I'm rated PG-34!!
                                  at               
 Click to see the full signature
Reply to
Grant Edwards

After hearing about how the AVR was designed as a C target, I was a bit dissappointed at how badly it deals with pointers and stack manipulation.

Agreed. Though it's missing a few key features of the pdp11 (one of the C-friendliest architectures I've seen), it has a very pdp11-like feel to it.

I just did a comparison yesterday between the AVR and the '430 (usign gcc for both). Code size on the AVR is about 50% larger than the '430 for functions with any significant use of pointers or 16-bit integers. For byte-oriented stuff the AVR code size is about 30% larger.

I counted clock cycles for a few of the smaller functions, and in a few cases the '430 is faster, but in general they're pretty comparable. This is due to the fact that a higher percentage of the AVR instructions are single-cycle where the equivalent '430 instruction is 2 cycles -- this is particularly evident for instructions that access RAM. This is probably due to the fact that the AVR is a Harvard architecture and the '430 is von Neumann.

The '430 also seems to be significantly lower power at the same clock rate.

So, if your app's code+data can fit in in the single 16-bit address space of the 430, it seems to be the clear winner, core-wise. For bigger apps, the 128K+64K combined address space of the AVR may trump the 430's better CPU core.

Of course if one has the combination of peripherals that you need and the other doesn't, then that probably decides the issue.

--
Grant Edwards                   grante             Yow!  HELLO, little boys!
                                  at               Gimme a MINT TULIP!! Let's
 Click to see the full signature
Reply to
Grant Edwards

I don't know if C is badly designed - that's not my point. A microcontroller 'designed for C' wrongly encourages people to think that C will produce the most efficient/effective code on that device which is plainly not true.

I disagree on two counts. First I do not think that that is all 'designed for C means, is meant to mean by those saying so and is assumed to mean by those reading the phrase. At a minimum it is a recipe for a whole host of erroneous assumptions. Secondly, the 8051 has the characteristics you mention but noone would say it was 'designed for C'

There is no disadvantage in being able to access data on a stack through a pointer or two. Why not say just that?

Precisely, and because C does not support those operations, suggesting that a microcontroller is 'designed for C' is not a plus because it could mean that the micro does not even support those operations at an assembler level. In my book that makes it a waste of time as a microcontroller.

Depends on the processor and the application. Here we are specifically considering 8 microcontrollers where the emphasis is on control. IME non C friendly microcontrollers make better controllers and are best programmed in assembler.

As I said, to me C friendly is not an asset.

Ian

Reply to
Ian Bell

Oh yes. Add a few NOPs here, take away a NOP there... shuffle and repeat.

--

John Devereux
Reply to
John Devereux

Also the C compilers do not seem to be able to elegantly deal with the separate code and data spaces. So your constant data either eats up RAM, or else you have to wrap everything in unportable compiler extensions. May not matter for small applications, but the larger the application, the more likely you will need to have data driven code with large menu structures, string tables, crc tables etc.

This is the primary reason I am using ARM (instead of atmega128) for new designs. But I would certainly choose AVR over 8051 or PIC. Or

8048 :)
--

John Devereux
Reply to
John Devereux

There are other languages. Intel's PLM-51 (or whatever it was called) seemed like a good compromise.

It is to those of us with C code that we need to run. :)

--
Grant Edwards                   grante             Yow!  Mr and Mrs PED, can
                                  at               I borrow 26.7
 Click to see the full signature
Reply to
Grant Edwards

Depending on what metrics you use for "efficient/effective", that may or may not be true. Ultimately, of course, a good assembler programmer is going to be able to get the highest code density and fastest run speed on any architecture, but the cost (both in terms of time, and programmer ability) of writing the code compared to the gains in code efficiency are going to be different for different sorts of cpu, and different sorts of programming task. On an avr, a C compiler can produce pretty good code - not optimal, but not bad. On an 8051, it's a struggle for a compiler to produce good code because the language is such a bad fit for the cpu architecture. On an msp430 or an ARM, the compiler is going to be able to come much closer to optimal, and probably will produce better code than an assembly programmer would (assuming the programmer is interested in things like maintainability and readability of the code, and in finishing in a sensible amount of time), at least for larger programs. (This is based on having written assembly and C code on a range of micros, from C-unfriendly ones like the COP8 and PIC16, through the AVR, the msp430, and big cpus like the 68k and PPC.)

Of course, there are other language choices than just C or assembly, but the same thing applies - plus you have to take into account availability of good compilers for the language, and possibly training the programmer, which will reduce the real-life practical efficiency.

So as a sweeping generalisation, I'd say that most "designed for C" micros are most efficiently programmed in C.

To be entirely honest, I have never actually used an 8051, and have only briefly looked at the core. But (at least for a standard 8051) AFAIK access to data on the stack is very inefficient - hence 8051 C compilers play all sorts of tricks to implement local variables and parameters as dedicated globally-allocated objects. And I believe different 8051 manufacturers have added different numbers of pointer registers in attempts to make the devices more C friendly. Am I also right in thinking that different parts of memory ("normal" ram, "extended" ram, flash, I/O, etc.) are all accessed in different ways?

As to what "designed for C" means beyond these basics, I'd guess that the other major implication is that there is a C compiler (and debugger) available for it.

I'd also note that except for cases where backwards compatibility with older C-unfriendly cores is vital, or for very specialised cores, probably all modern cpu designs are "designed for C". Like it or not, C is the lowest common denominator of programming languages.

Just because there is no direct C expression for, say, "rotate left through the carry flag", does not mean a "designed for C" micro will not implement it. In fact, you can be very certain that it will, since it is C-friendly - it forms an essential part of a 16-bit left shift (on an

8-bit micro), and such shifts *are* accessible in C. Similarly, a compiler for a DSP with a selection of instructions for complex operations will come with a library of intrinsic functions to give C programmers access to the functionality. Being "designed for C" does not in any way imply "designed *only* for C".

Non C friendly architectures are often best programmed in assembly, it's true. And for many types of programs, assembly is a sensible choice of language. But I really cannot think of any advantage the C-unfriendly micros I have used have over the C-friendly ones (in terms of their cpu core, I mean), for any sort of programming. But I'm happy to hear if you've got some examples of program snippets or tasks that work well on the 8051 but would be poor (either big, slow, or awkward to code) on an AVR or msp430, programmed in either assembly or C.

Reply to
David Brown

... snip ...

I am not sufficiently conversant with Forth to be sure, but I believe it does have direct stack operations available. You may not recognize them. However Pascal most definitely does have frame pointers. They are embodied in nested procedures, and suitable local declarations, not to mention the use of the WITH statement. Again, you may not recognize them.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 Click to see the full signature
Reply to
CBFalconer

I'll vouch for that last statement. After profiling an application running on an ARM platform, I found that the IP checksum routine from the BSD TCP/IP stack was by far the largest sink of CPU time. In order to try to squeeze more performance out of the platform, I decided to re-write the C-language IP checksum routine in assembly language.

The first couple versions of the assembly language version were slower than the C version. After three or so re-writes of the assembly language routine, I had one that was a little bit faster than the C function. I didn't seem to be making much headway, so I turned to Google and Usenet and found pointers to a couple very obscure tricks (in both the math and the ARM instruction set). After a couple more days of hard work, I had an IP checksum routine that was about 40% faster than the C version.

Beating GCC on the ARM wasn't easy, and at the time GCC's ARM back end was reputed to be only mediocre compared to a couple other compilers.

--
Grant Edwards                   grante             Yow!  I wonder if I ought
                                  at               to tell them about my
 Click to see the full signature
Reply to
Grant Edwards

That's actually quite easy, because the 80C51 has opcodes the AVR simply lacks ( the AVR is closer to the 8048, than the 8051 ) :

Any code that is BOOLEAN in nature flys on an 80c51 ( and is fully atomic ) - but the C radar, back when the AVR was designed, did not include BOOLEAN types, plus the AVRs target was as a small ASIC core. In the 80C51 you can also map BITs onto BYTES in the BIT ADDRESSABLE space, for very efficent code. The 80C51 also has Direct Memory opcodes: Go outside the registers, and the AVR suddenly suffers from 'pointer thrashing', and is NOT interrupt friendly - so any code that is not large arrays, but has a smattering of named variables ( gee, most embedded code, actually ) has the 80C51 well in front. Most 80C51's have 4 priority levels on interrupts, and all have register bank switching - even the lowly 8048 had register bank switching, something else the AVR lacks.

Some AVR devices do appeal, but it is more in spite of the core, than because of it. The new Tiny2313 and Tiny25/45/85 features like Wide Vcc, on chip OSC, and reasonable peripherals with on chip debug, all make for nice little devices.

Of course, the new LP213/214/216 devices from Atmel, have 1 cycle

80C51 cores, and tiny packages, nearly as Wide Vcc, and on chip debug - so you get a good core _and_ good peripherals :)

Philips, STC, Coreriver, SiLabs also have small package 80C51's

-jg

Reply to
Jim Granville

The AVR can do atomic bit manipulation on a useful segment of its IO space, and on half its registers. So if you want very fast access flags, you can reserve a register and use that. Normal booleans in C are implemented as an int or a byte (you'd use a byte on an AVR). With a few macros, you can get reasonably convenient bit access, although it's not atomic (which can be a disadvantage).

I can't think off hand of any advantage of bit addressability like this unless you are dealing with an array of bits, or pointers to bits, except perhaps for atomic access.

I'm not sure why you would want to access your named variables through pointers, except for arrays, or very occasionally when passing pointers to functions. Unless, of course, you are using an architecture which does not have direct access to more than a small part of its memory space, and is forced to use pointers to access fixed-position global data. Perhaps you haven't looked at the details of the AVR (I had not looked at the details of the 8051 until this evening).

The AVR can directly read or write to any fixed address in its RAM or IO space, without going through pointers. It has no way to do read-modify-write atomically to memory. I'd happily agree that the AVR should have had four full pointers, instead of two and a half (one of the pointers does not support all addressing modes), and the separate flash and data memory spaces is a pain, but it's a world ahead of the

8051 with convenient access to a grand total of 128 bytes data, two different sorts of pointers to access different parts of ram (no doubt causing great programmer joy when re-arranging the placement of variables in data sections), and a third type for flash access.

The DPTR arrangement for access to XDATA is, I'm sure you'll agree, awkward, slow and inefficient for anything but the most simple access, and much less efficient than the AVR's memory access. Even for 8051 variants with more than one DPTR, it's still poor - a simple block copy routine needs seven instructions within the loop, while an AVR would need 4.

When it comes to indexed addressing, which is essential for use of structures and data stacks (used in high-level languages, but less used in assembly), the 8051 is a non-starter.

The 8051 has better atomic access to memory than the AVR, which could be useful in some applications - I'm not claiming the AVR could not be improved upon.

Yes, the 8051 has 4 banks of 8 registers, whereas the AVR has 1 bank of

32 registers. When writing assembly for the AVR, I generally dedicate a group of registers to the interrupt routines, so that there is no bank switching or register saving needed at all.

And yes, the 8051 has interrupt priorities, allowing low-priority interrupts to be pre-empted by high-priority interrupts. Personally, if I have a low-priority interrupt routine that I know may take significant time, I simply re-enable the interrupt flag so that it may be pre-empted. There's not a lot of difference for real applications.

And do these small 8051 chips still have the "wonderful" system of I/O pins that can't drive high? I know that is not part of the 8051 cpu core, but it's part of the baggage that backwards compatibility brings.

I suppose the 8051 is a reasonable enough core for very small micros and simple tasks, but I would not like to have to use it for anything sizeable (unless combining a C compiler, a fast clock speed, and plenty of memory, and just try to forget the architecture inefficiencies). It's perhaps not the worst choice (the COP8 and PIC16 vie for that position, out of the micros I've used). But I'm still left with the very clear position that the AVR can do almost anything the 8051 can do, and can do much more besides.

Of course, if you look at the msp430, you see a cpu that's even better to work with.

Reply to
David Brown

Forth does everything on the stack. An ideal Forth machine would not have any registers at all, other than two stack pointers (a data stack and a return stack). For example, the "add instruction" in Forth pops the top two items from the data stack, adds them, and pushes the result. An efficient cpu for Forth therefore needs good stack manipulation instructions (although Forth compilers typically emulate the top few stack positions in registers).

Pascal does indeed need frame pointers for local procedures (though not, I believe, for WITH statements - a "WITH" is a syntactic abbreviation). The AVR can emulate a frame pointer, but really it would need a couple more pointer registers to do so efficiently.

This is why I said that while being "designed for C" is a help in implementing other languages, it's not enough to be ideal for all languages.

Reply to
David Brown

I agree there are cases where C is the best language of choice even on an 8 bit microcontroller - for example where resources are not scarce or unit cost is not paramount or high performance is not required. I have no problem with using C in the right circumstances. My objection is the implication that 'designed for C' means C is always best when clearly it is not.

Agreed.

I'll not comment on the maintainability or readability of code - that's a separate debate ;-) , but I concur that C on an ARM is generally a better choice than assembler - if someone said the ARM was 'designed for C' I would have no objection. I am not familiar with the MPS340 so cannot comment.

Good lord, I remember the COP8 and I also remember writing 6K of code for the 1802 using a line based editor - I don't think C had been invented then.

I am happy to agree with that statement for processors like the ARM but not for ones like the AVR.

Pretty much spot on. It also has a Harvard architecture which is 'less C friendly' per se than a von neuman one. That's the thing with 8 bit microcontrollers - they are designed to do a specific job not suit a particular high level language.

I think it is important to differentiate between 8 bit microcontrollers and everything else. It is only the former where I object to the 'C friendly' label for the reasons given earlier. 8+ bit microprocessors and16+ bit microcontrollers I have no problem with as far as labeling them 'C friendly' is concerned.

Try an atomic byte increment or decrement.

Personally I don't think we are a million miles apart. 'C friendly' applied to anything other than an 8 bit microcontroller is OK by me.

One last point. When using C you are at the mercy of the compiler and the C programmer. There is little you can do about the former and my experience of the latter, where C was the primary language of the programmer, has been that extremely inefficient code is produced. My first embedded C project (about 15 years ago) fell into this category. The microcontroller, an Hitachi H8 was certainly what you would describe as 'C friendly' but the combination of a poor compiler and C language programmers meant the code was 50% too large and 500% too slow. I spent a lot of time educating the C programmers how to write efficient/effective C code and just as long tweaking it to circumvent the idiosyncracies of the compiler.

We reused this code in a scaled down version of the product using the same H8 core quite successfully but we did have to tweak the code again to cope with the latest version of the compiler. Later, a third version was created using third party programmers (there were good reasons for this) but once again the resultant code was bloated and slow. This time we had to modify the code ourselves as by now the third party had disappeared from the scene.

I admit, C compilers are (hopefully) better today, but C programmers still do not migrate to 8 bit microcontrollers with any degree of ease. Give me an assembler coder who has learned C any day.

Ian

Reply to
Ian Bell

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.