PIC and AVR thinking of a switch but need more info - Page 1
Forum section: electronics / general

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 18, 2013, 09:27:35 pm
content: I have been working with pic chips now for about a month using assembly and really learning some cool stuff about how uC's work. I have been in the process of designing my own little project and the 8 bit pic architecture is driving me nuts. It just seems like all of its nuances step on my toes. I am sure I can work around them but can't help but think about maybe avr is better for me. I do have an arduino I could use as the base for getting started with the transition.Just a few of my issues with pic include the single accumulator, the annoyance of constant paging, I also find the 4 cycle per instruction very odd.Does anyone on the avr side of thing have any input?I do not want this pic vs avr I am already somewhat un happy with my pic experience so far. I am just looking for some outside input on my concerns. If my question are unclear just say so I can clarify better when not typing on a phone.

author: ve7xen
author_rank: Super Contributor
timestamp: March 18, 2013, 10:35:25 pm
content: 1. Accumulator - AVRs have 32 general purpose registers, and most instructions can use any of them as target (and source). Some are fixed though.2. Paging - AVR has flat address space3. Instruction execution time - AVR has variable instruction cycle count

author: AlfBaz
author_rank: Super Contributor
timestamp: March 18, 2013, 10:38:58 pm
content: Quote from: ve7xen on March 18, 2013, 10:35:25 pmIs that for an 8bit mcu?. If the OP is struggling with asm on an 8 bit micro surely a 32 bit arm isn't going to be any easier

author: ve7xen
author_rank: Super Contributor
timestamp: March 18, 2013, 10:43:17 pm
content: Yes, AVR is an 8-bit arch.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 18, 2013, 11:14:37 pm
content: Quote from: AlfBaz on March 18, 2013, 10:38:58 pmNote I never stated I was struggling with ASM. Learning the ASM is not the issue in the least. The issues I am having revolve around the way the PIC MCU is structured. It is simple only 35 instructions or so on a PIC16 but because of the way they architect the chip to get to that point it makes it incredibly difficult and tedious to do a lot of things because your are constantly doing stupid little stuff like having to change banks constantly to get at the right registers. Everytime you have to do this it costs 1 instruction cycle which is 4 cpu cycles. You also only have the 1 accumulator which causes you to have to for instance use 2 instruction cycles to set a user file register instead of just 1 instruction cycle. It is not the asm I have issues with most of the time my issues revolve around understanding the formulas behind certain tasks for instance cycle time which I now understand. My issues are revolving around the actual PIC architecture being rather crappy which makes it more difficult to do the kinds of things I want to do.Quote from: ve7xen on March 18, 2013, 10:35:25 pmRight pic has variable instruction cycle counts as well but at a 1:4 so 1 instruction cycle takes 4 cpu cycles to complete. Is AVR a 1:1?Also how is the AVR ASM? Or rather maybe I mean to say how does the AVR ASM flow? What I noticed from the PIC architecture through the asm is that you need to often do unnecessary steps for instance...movlw 0xA1movwf Foo2 instruction cycles instead of a simplemov Foo, 0xA1which would be 1 instruction cycle and makes more logical sense at least to me. This is what I mean by flow.I like to think in steps and when saying move value to w then move it to the memory address seems awkward compared to move value to memory address

author: Psi
author_rank: Super Contributor
timestamp: March 18, 2013, 11:31:57 pm
content: Yep, AVR is a 1:1 for most instructions.Some instructions take 2 and a few take 3-5. But yeah, most are 1:1For a real world app the average is around 1.5 clocks per instruction.You will find ASM on AVRs easier.ASM on PIC has been described as akin to stabbing yourself in the face.http://www.ladyada.net/library/picvsavr.htmlHowever, both AVR and PIC are getting a bit old now.You might be better to forget AVRs and move to a 32bit ARM micro.The price just keeps falling and they've got much more power and features.I've never done any ARM ASM but i would imagine its pretty nice.

author: ve7xen
author_rank: Super Contributor
timestamp: March 18, 2013, 11:46:53 pm
content: AVR assembly is quite sane IMO, but I haven't done all that much with it.The reference manual is here and is generally pretty clear about the specific questions you've asked so far:http://www.atmel.com/images/doc0856.pdf

author: AlfBaz
author_rank: Super Contributor
timestamp: March 18, 2013, 11:51:24 pm
content: Quote from: ve7xen on March 18, 2013, 10:43:17 pmAnd only one clock cycle for ALU operations and 4 for peripheral access, very nice

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 18, 2013, 11:54:33 pm
content: While learning assembler is a good way to understand how things work, once you have a basic grasp of it, it's probably time to move to using C and let the compiler worry about all the quirks of the architecture until you hit something that really needs the speed of assembler.AVR assember is certainly nicer than PIC, but has its own challenges, like keeping track of register usage and branch range limits, plus a lot more instructions to remember.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 19, 2013, 12:30:22 am
content: Quote from: mikeselectricstuff on March 18, 2013, 11:54:33 pmYes I do have every intention of moving to C. C is actually my favorite programming language out of the many I can use fluently. To not know the asm would really limit me in the long run. I did not know that ARM make uC's I thought they make microprocessors/full CPU's. Despite not knowing that I would be under the assumption that a 32 bit ARM from the assembly level would be quite complex none the less. I chose 8 bit because it would give me a solid base to work off of. From the information I have gathered so far in this thread AVR 8 bit is quite nice. Yes I understand it has it's own quirks everything does but from my 1 month experience with PIC abouts the ASM I agree is like poking your eyes with a stick. The architecture is quite awkward. Now that I know what I know which is much more then when I started + the clarifications given here AVR or ARM would be the way to go for my embedded programming/electronics hobby.I should have listed to what the other people said when I was first investigating the hobby a month ago. I was told on StackOverflow to go ARM and I was told on the Microchip forums to actually go AVR ironically. So lesson learned.Thanks for all the help and thanks for not starting a uC war. If I think of anymore questions I will ask away. Feel free to keep this awesome discussion going I will keep checking back.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 19, 2013, 12:53:08 am
content: Actually ARM is one of the nicest architectures to write assembler on, but you rarely need to as it is very compiler-friendly. ARM based MCUs do tend to have rather more complex peripherals though.

author: nctnico
author_rank: Super Contributor
timestamp: March 19, 2013, 01:24:55 am
content: There is always TI's MSP430. I think it sits nicely between 8 bit and 32 bit controllers. And some are really ultra low power.

author: BravoV
author_rank: Super Contributor
timestamp: March 19, 2013, 01:49:23 am
content: Quote from: mikeselectricstuff on March 19, 2013, 12:53:08 amJust sharing my experience as enthusiast that used AVR in the past, in ARM mcu, C is enough that the need of hand writing an assembly is not a really a high priority since its really fast.But even you decided to jump into ARM assembly for hardcore fine tuned performance, its still tons-tons better than old mcu architecture, personally when I ventured into ARM world, I was so damn impressed with NVIC feature when I learned it for the 1st time, and my favorite part is when writing an ISR, the nightmare in the ISR routine in the old time like those pesky push..push..push ..<isr body>.. pop...pop...pop is all handled by hardware and its damn efficient & fast.Price wise, today's ARM mcu is so cheap that its not an excuse anymore.Edit : Attached below the excellent illustration on how ARM cpu handles an ISR.

author: westfw
author_rank: Super Contributor
timestamp: March 19, 2013, 02:59:12 am
content: QuoteYes. This is usually an excuse to switch to a high-level language. If you program in C, any ugliness of the underlying architecture is hidden and largely irrelevant. As long as it's "fast enough."That said, AVRs are much more pleasant to program in assembler than the 8-bit PICs (you didn't say which PIC you're using. I'll assume, based on your comments, that you have a PIC16fxxx of some kind. The PIC18s are better, and the PIC24s, PIC30s, and PIC32s are all considerably better.The AVR does in 1 clock cycle what PICs generally do in 4 cycles, so they tend to be faster.On AVRs in ASM, you'll find yourself frustrated by needing to move everything to a register before you do anything with it. While the PIC is Accumulator/memory for most operations, the AVR is pretty much register to register for everything. Also, the AVR will bite you by having various registers and IO locations inaccessible from certain instructions (direct bit testing works on a small set of IO registers. IN and OUT work on a somewhat larger set. The reset have to be accessed like memory, which is bigger and slower.) So they're not without quirks of their own.

author: Psi
author_rank: Super Contributor
timestamp: March 19, 2013, 04:05:24 am
content: Quote from: blewisjr on March 19, 2013, 12:30:22 amARM license their instruction set and provide generic cpu core implementations of it.Other companies buy those licenses and build actual chips.Some of the companies make cpus for phones others make microcontrollers etc..So if you decide to use an ARM microcontroller you have lots of choices.NXP, TI, ST, Atmel etc..

author: Unknown
author_rank: Unknown
timestamp: March 19, 2013, 10:28:38 am
content: Quote from: blewisjr on March 18, 2013, 09:27:35 pmAlthough an appreciation of asm is certainly a good skill to have I'm not sure why you'd want to use it in your projects unless you had specific reason to do so.Ok, suppose you spend some time writing some i2c code in asm, can you port that code easily to another chip architecture? Also if you had to come back to an asm code project you wrote a good while ago could you easily get up to speed with the code without spending a bit of time on it? Now would the same be true if you had written the code in C?To me the portability and maintainability of code is far more important than the chip architecture and instruction set peculiarities across devices and device manufacturers.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 19, 2013, 12:51:09 pm
content: Quote from: jucole on March 19, 2013, 10:28:38 amYes I know C is more portable if done right that is. I have stated multiple times that C is my language of choice and I have every intention of using it. The thing is that one of my main goals when starting this hobby is to not only learn circuits but to do something different and learn assembly to improve my high level programming skills. It is well known that learning asm will improve your capabilities in C even if you do not use inline asm.On another note I have been looking into ARM and the cortex M0+ looks awesome and can come in dip. The issue is I already have a Arduino which I can use for AVR so I might end up going that route anyway otherwise I have a useless piece of $35 hardware just laying around.

author: bingo600
author_rank: Super Contributor
timestamp: March 19, 2013, 03:00:59 pm
content: I'm using AVR and ARM , and selects by target use.There's no need to use an ARM to blink a led , when a single input is toggled.Or to display the temperature from a ds18b20 on a LCD (witch often is 5v anyway)I'm trying to get my hands on some of the NCP Cortex M0 1114 DIP's now but i cant seem to find anywhere in EU , where i don't have to pay either $6 a piece , or $40 in shipping.I need the 32bit timers thats available in the ARM , for precision counting (waveform gen)So i chose the "Hammer" depending on the size of the "Nail".Ohh. I have never programmed a pic , and would probably only consider a DsPIC (MIPS) if i had to chose one.I have not done much with the new Atmel Xmega's , as i tend to see ARM's as a better choice if i have to go TQFP & 3v3 anyway. Besides a lot of the ARM's have 5v tolerant inputs (most of the pins) , witch the Xmega doesn't.If you're going ARM , i suggest the Cortex'es ... At least the NVIC is standard there.A STM32xx-Discovery board @ 10..15$ will be a nice beginning , and it includes the debugger./Bingo

author: olsenn
author_rank: Frequent Contributor
timestamp: March 19, 2013, 03:12:01 pm
content: QuoteDON'T!!!!!!!!!!!!!!!!!!I tried for 3 straight days to get that damn MCU to blink an LED and I couldn't. The datasheet/manual is the worst piece of tripe ever written... I'm pretty sure it was written in Korean or Cantonese and translated to English with Google translate. Register contents/locations are missing, and some things were flat out wrong; even self-contradictory.If you are designing something that can be programmed with an 8-bit micro, program it with an 8-bit micro... if you're designing something that needs to be programmed with a 32-bit ARM-M0, give up and design something with an 8-bit micro instead! Or hire a slave laborer in Guatamala to program the ARM chip for you.

author: AlfBaz
author_rank: Super Contributor
timestamp: March 19, 2013, 03:20:20 pm
content: Quote from: blewisjr on March 19, 2013, 12:51:09 pmLOLSome could argue...

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 19, 2013, 03:36:07 pm
content: Quote from: olsenn on March 19, 2013, 03:12:01 pmI've not looked at that particular part but NXP's documentation is usually very good. Errors in docs are aways a risk on very new parts from any maker though. Another real headache can be errors in supplied header file definitions for IO registers etc.

author: c4757p
author_rank: Super Contributor
timestamp: March 19, 2013, 03:37:54 pm
content: Quote from: mikeselectricstuff on March 19, 2013, 03:36:07 pmI don't get this. I can see documentation being wrong, since the people testing the chip would know it well enough not to need thorough documentation, but the headers? Don't they at least compile some code for the chips and make sure it runs?

author: bingo600
author_rank: Super Contributor
timestamp: March 19, 2013, 03:40:54 pm
content: Quote from: olsenn on March 19, 2013, 03:12:01 pmCould this helphttp://www.microbuilder.eu/Forums/Thread/e6d805d6-b4d3-4118-9d06-e86671686c63.aspxhttp://www.meatandnetworking.com/tutorials/lpc1114fn28-with-open-source-tools/https://github.com/Zuph/lpc1114-blinkOr the attached oneI'll give the 1114's a go if i can get my hands on a few ...Maybe you're willing to part with yoursEdit: There might be a clock-tip here if not using an xtalhttp://forums.arm.com/index.php?/topic/16502-cortex-m0-operation-without-crystal/page__p__40452#entry40452/Bingo

author: AlfBaz
author_rank: Super Contributor
timestamp: March 19, 2013, 03:43:53 pm
content: Quote from: c4757p on March 19, 2013, 03:37:54 pmThey should... I remember microchip making a lot of people angry when they altered their headers for some of the 18F pics. Cant remember the specifics but they issued a work around (edit the header) and subsequently fixed it.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 19, 2013, 04:08:09 pm
content: May I ask what is wrong with the ARM Cortex M0/M0+ I have heard nothing but awesome about them. People say it gives 8 bit uC's a run for its money.Also I should say it would make the Arduino useless for me as I want to focus on one uC at a time to avoid confusing myself.

author: croberts
author_rank: Regular Contributor
timestamp: March 19, 2013, 04:18:47 pm
content: I've been doing a lot of projects and assembly language programming with the PIC16F690. Please check out my posthttps://www.eevblog.com/forum/microcontrollers/a-simple-state-machine/for an example of the coding template I use.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 19, 2013, 04:28:12 pm
content: Quote from: croberts on March 19, 2013, 04:18:47 pmI am looking for a pic alternative sorry I just do not like the architecture but I will still check out your post later on tonight when I have time to read it.

author: Unknown
author_rank: Unknown
timestamp: March 19, 2013, 05:13:42 pm
content: Here's a couple of useful application notes from Microchip with some handy conditional assembler macros for doing some the tedious stuff, like bank switching.http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011030But as I've always found with doing asm stuff - you'll need to go tell your mom you'll be late for supper! ;-)

author: mrflibble
author_rank: Super Contributor
timestamp: March 19, 2013, 05:54:28 pm
content: Quote from: blewisjr on March 19, 2013, 04:08:09 pmNothing wrong with it. I think that Olsenn's"DON'T!!!!!!!!!!!!!!!!!!"was related specifically to the NXP Cortex M0 1114 DIP, which may still have some documentation issues due to being fairly new.Quote from: jucole on March 19, 2013, 05:13:42 pmAnd late for breakfast the next morning as well. XD

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 19, 2013, 06:26:25 pm
content: This is a very interesting discussion. I got people pushing just about every chip out there just insane.So I am starting to look from a different perspective I guess it comes down to what I like better and there is only one way to figure that out.I am sure I can learn around PIC quirks. So here is what I will do. I will build a project with my PIC and then rebuild it with my Arduino AVR chip both in asm and see which one I like better. I was thinking of something simple like a 4 bit led binary counter.

author: Len
author_rank: Frequent Contributor
timestamp: March 19, 2013, 06:29:35 pm
content: Quote from: jucole on March 19, 2013, 05:13:42 pmThat brings back memories!My advice: Assembly programming for AVR would be a bit less annoying than PIC. But when you feel you've pretty much got the hang of it, you might as well switch to C.Assembly language for programmers is like calculus for engineers - helpful to know, but hopefully you won't have to use it.At least it gives you experience mucking around with control registers and such, which comes in handy when you want to do something "unusual" like change the PWM frequency in an Arduino program.Addendum:Building a simple project with both chips - good idea!

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 19, 2013, 06:44:43 pm
content: Quote from: Len on March 19, 2013, 06:29:35 pmYes I think it will be a good idea too many solid arguments to sort lol. My biggest fear with PIC is when I need to implement division because although division not too difficult to implement the cycle setup of the pic would take close to 4 times as long to process which would suck.

author: AlfBaz
author_rank: Super Contributor
timestamp: March 19, 2013, 10:15:33 pm
content: Quote from: blewisjr on March 19, 2013, 06:44:43 pmWell, you are doing this to learn asm aren't you?What better platform than a crippled one. You'll learn a lot more shifting and rotating bits and creating macro's than simply jumping to a platform with an increased instruction set and in the future you'll be better equipped to scrutinise C/C++ compiler output

author: westfw
author_rank: Super Contributor
timestamp: March 20, 2013, 01:28:07 am
content: Quote from: originalPosterSo what are you waiting for? Get reading, get programming. Some things will be great, some not so great. And you'll be in a much better position to evaluate your THIRD architecture (ARM, MSP430, MIPS, whatever.)A person's second assembly language is usually the most educational. Or it should be!Quote from: ve7xenHmm. Marketing talk. AVRs have 16 general purpose registers, and an additional 16 less-general-purpose registers. And a few (different numbers on different chips) that combine into 16-bit pointers. And no paging until you exceed 64kB of RAM or 128kB of instructions.Quote from: blewisjrStill two instructions on an AVR.Code:ldi r16, 0xA1sts Foo, r16Assuming Foo is in RAM. The first instruction is one of the ones where only 16 registers can be used. The second instruction takes two words and two cycles, so IIRC the sequence is bigger than on a PIC (not counting banking.) OTOH, since the AVR has at least 16 registers to hold the A1, you might never need the memory location Foo...This is an architecture issue rather than an assembler issue; stuff pretty much has to move through registers on both PIC and AVR. The PIC only has the accumulator, the AVR has more.I think the MSP430 can do this in a single instruction. But the instruction will be three words long and take "many" (4+?) cycles. Aren't there common macros for doing this sort of thing on PIC? ("movlf" was apparently standard in the Parallax PIC assembler, and widely implemented elsewhere.)

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 20, 2013, 09:29:55 am
content: Quote from: westfw on March 20, 2013, 01:28:07 amI do understand what you are saying westfw. Sure it is possible to macro it but the point remains that it is possible under a lot of circumstances on the AVR with those 16 registers to avoid having to grab a file register from ram which reduces it to 1 inst. cycle instead of 2.Like I stated above I think it will be best at this point to do a project with both even tho I never used AVR ASM before I should be able to easily find the registers and opcodes I need to match the pic project and then I can compare the flow I was talking about myself. There is so much info in this thread and I do greatly appreciate it marketing pitches and all.Ultimately chip really won't matter too much when I move to C but I want to at least learn the ASM side first. Worst case I find I can deal with the major PIC quirks and after a few projects and after I get more comfortable with the chip I can switch to AVR and learn that and then I have 2 chips under my belt.

author: poorchava
author_rank: Super Contributor
timestamp: March 20, 2013, 09:37:26 am
content: Go for ARM. Same or lower price and an order of magnitude (no overexaggeration here) jump in performance. And all necessary development tools can be had for free without restrictions and other shit like that.Here are some prices from a microcontroller shop where i usually buy.mcu usd price@1 usd price @10atmega8 $1.81 $1.69atmega16 $4.41 $4.13pic16f628 $2.14 $2.14pic18f4550 $7.83 $7.34msp430f2011 $3.31 $3.04lcp1111 $2.06 $1.83stm32f100c4t6b $2.83 $2.59lpc1113fbd $3.24 $2.88

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 20, 2013, 10:35:17 am
content: Quote from: poorchava on March 20, 2013, 09:37:26 amDo those prices include shipping they seem over inflated from microchip you can get most chips for less then $2 usd bulk or single. Do not know of the others.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 20, 2013, 10:56:49 am
content: For small quantities, differences in part prices are insignificant compared to differences in development effort. e.g. using what you know, quicker learning curve etc.Also bear in mind that costs of things like voltage regulators, xtals,eeproms etc. can add to the parts cost difference.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 20, 2013, 11:16:10 am
content: Well right now PIC has the leg up on learning speed because I have been tinkering with it for about a month.As a side track what is a good place to buy uC's and other components? I know of digikey but heard some people had issues with them. Then there is sparkfun/adafruit but inventory at these places has limited selection.

author: deephaven
author_rank: Frequent Contributor
timestamp: March 20, 2013, 11:18:22 am
content: Quote from: blewisjr on March 20, 2013, 11:16:10 amWhich country are you in?

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 20, 2013, 11:24:45 am
content: USA

author: deephaven
author_rank: Frequent Contributor
timestamp: March 20, 2013, 11:31:19 am
content: Quote from: blewisjr on March 20, 2013, 11:24:45 amAh OK, I'll leave it for the USA guys to give you some answers. I have a good UK source, but shipping would put them out of the running.By the way, you probably already do this, but always make sure you read any errata sheets from the manufacturer. That can stop a lot of heartache sometimes!

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 20, 2013, 11:33:21 am
content: Quote from: deephaven on March 20, 2013, 11:31:19 amI agree! I hate when there is no errata especially books.

author: BravoV
author_rank: Super Contributor
timestamp: March 20, 2013, 11:43:49 am
content: Quote from: bingo600 on March 19, 2013, 03:00:59 pmIf you're a pro, I'm wholeheartedly agree, hell, you even have to get your hand dirty into clock by clock optimization at assembly say to do the DSP processing using the ancient 8051 if needed.But in this topic, especially in the context that the OP is at early stage of learning period, and in the middle of taking important decision to invest his time & energy & money and prolly tears, c'mon, currently choosing ARM platform is one of the best choice.

author: MikeK
author_rank: Super Contributor
timestamp: March 20, 2013, 12:11:32 pm
content: Quote from: blewisjr on March 20, 2013, 11:16:10 amIn the U.S.? I mostly buy from Mouser. Sometimes Jameco.

author: mariush
author_rank: Super Contributor
timestamp: March 20, 2013, 01:17:22 pm
content: I prefer Farnell, mainly due to low shipping fees to my country. For larger orders, Digikey works fine with the minor annoyance of having to pay customs taxes and VAT when I get the package.I've tried RS-components as well, but the shipping fees are slightly bigger than Farnell and they don't ship straight to me, they ship it to a company in the capital of the country, which then couriers packages to me, so it's just an unnecessary delay.

author: AlfBaz
author_rank: Super Contributor
timestamp: March 20, 2013, 01:24:30 pm
content: This thread got me looking at some of my PIC asm code. Haven't looked at it for years and years... gotta tell you, got a bit of a stiffy

author: ve7xen
author_rank: Super Contributor
timestamp: March 20, 2013, 06:38:53 pm
content: Quote from: BravoV on March 20, 2013, 11:43:49 amI'd agree, ARM is great value for money and seems to be the future. However for beginners I'm not sure it's quite there yet as far as (free) development tools are concerned. I've had a lot of difficulty figuring out how to set up linker scripts, startup code, linking a libc and other annoying and unproductive minutiae. Also the whole CMSIS library architecture is a bit over-engineered and is kind of an awkward pain to properly link and include in an IDE like Eclipse. Once working it's pretty nice to use though.MSP430 and AVR, while perhaps less flexible, mostly handle this for you and you can go from C/ASM source -> compiler -> uC without any other scaffolding.As far as buying chips, I find DigiKey has the best selection of ICs, but the worst prices. Mouser's prices tend to be a little better, but their selection of ICs is not as good. Future Electronics has very good prices, especially passives, but their selection is pretty slim, especially for DIP (if you're into that). For larger projects I often find it is worthwhile, even with shipping costs, to order passives, connectors and available ICs from Future and everything else at DigiKey or Mouser.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 21, 2013, 11:06:35 am
content: Quote from: AcHmed99 on March 21, 2013, 10:58:39 amThe quirks do exist in the enhanced PIC16 I am using a PIC16F1829 which is the enhanced mid-range. The enhanced mid-range architecture is just like the standard PIC10-PIC16. I also have a PIC18F14K22 which I did not tinker around with yet but I do know it solves the screwed up banking and paging as far as I know the PIC18 still only has 1 accumulator but configuring your fuses is much easier and has hardware multiply. Over all a better chip.

author: westfw
author_rank: Super Contributor
timestamp: March 21, 2013, 03:48:00 pm
content: QuoteScenix/Ubicom tried this. With some relative brief success, even. But not MUCH success. (I guess "propeller" is still moving along those lines.)I think the problem boils down to the fact that the number of engineers you can find who can implement ethernet given a shift-register and a bitslice is pretty vanishingly small. And when you step up from 3 MHz Ethernet to 100MHz Ethernet, you can't afford the delay involved in having part of your peripheral be off-chip.I used to work for a company that implemented a bunch of things in bitslices. But the bitslices didn't keep up with the mainstream CPUs in terms of clock rate, and bitslice programmers were ... difficult to find.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 21, 2013, 03:58:08 pm
content: Well here is a small update.I implemented a little project using the PIC16F1829 (The one that has banks unlike the PIC18 series). The project was an 8 bit number counter which displays over 8 LED's. Really fun little project and as my first solo project on the PIC it was really easy to do. As far as I can see through a quick analysis it took about 7 extra instructions to implement due to having to pass through the single accumulator and switching banks. So in all honesty it was not bad and I felt very comfortable implementing the project.Next I will have to convert the project over to the Arduino's AVR chip to see how the ASM is with that. This will take tons of setup due to the fact that I do not have a AVR programmer so I would need to configure Atmel Studio to upload via the Arduino bootloader with avrdude.If anyone is interested here is the PIC code.Code:; =============================================================================; Project: Binary Counter; File: binary_counter.asm; Date: 3/21/2013;; This project is a 8 bit binary counter. The number of the current count; is displayed on a set of 8 LED's hooked to pins RC0 - RC7 on the uC.; There is about a 1 second delay between each number increment.; =============================================================================; =============================================================================; PIC: 16F1829; Board: Breadboard; IDE: MPLABX v1.70; Compiler: MPASM v5.49; =============================================================================#include <p16f1829.inc>; Fuse Configuration#define CFGW1A (_FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF)#define CFGW1B (_CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF)__CONFIG _CONFIG1, (CFGW1A & CFGW1B)__CONFIG _CONFIG2, (_WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _LVP_OFF); supress not in bank0 warningerrorlevel -302; create file registers in bank shared memorycblock 0x70Dly1 ; Dly1 is a file register for the delayDly2 ; Dly2 is a file register for the delayCnt ; Cnt is a file register for our countendcorg 0 ; Start program at 0x00Start:; Initialization codemovlw 0x00 ; Move 0 to W registermovwf Dly2 ; Move W register to Dly2movlw 0x00 ; Move 0 to W registermovwf Cnt ; Move W register to Cntbanksel OSCCON ; select bank1movlw b'00111000' ; We want a clock of 500kHZ giving us (1/(500k/4)) per instructionmovwf OSCCON ; Move W register into OSCCONclrf TRISC ; Make RC0 - RC7 and outputbanksel LATC ; select bank2clrf LATC ; clear the latchMain:; Main code blockincf Cnt, 1 ; Increment count and store back in Cntmovf Cnt, 0 ; Move Cnt into the W registermovwf LATC ; Move W register into the latchcall Delay ; Exectute the Delay routinebra Main ; Repeat processDelay:; Delay Routine uses formula {[(Dly1 * 3) + 4] * Dly2 + 1} * 8uSmovlw 0xA1 ; Move 161 into W registermovwf Dly1 ; Move W register into Dly1decfsz Dly1, 1 ; Decrement Dly1 skip next instruction if 0bra $-1 ; Re run previous instruction gives us 487 instructionsdecfsz Dly2, 1 ; Decrement Dly2 skip next instruction if 0bra Delay ; Re run whole loop gives us an additional 256 instructions; the return will give us + 1 to the delayreturn ; so our (476 * 256 + 1) * 8uS gives us 0.997384 seconds.end ; end of code

author: AlfBaz
author_rank: Super Contributor
timestamp: March 21, 2013, 04:29:15 pm
content: Quote from: blewisjr on March 21, 2013, 11:06:35 amHow many accumulators do you actually need when the instruction set allows you to do a lot of stuff directly on ram? Its a bit like having an entire ram's worth of accumulators. Granted they are 4 clock cycle instructions, but how many does it take to fetch, store, operate and possibly write back?

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 21, 2013, 04:47:59 pm
content: Quote from: AlfBaz on March 21, 2013, 04:29:15 pmIt is more of a efficiency and read ability thing.say you need to store the value 0xA1.On 8 bit PIC you only have 1 general purpose register W. So instead you need to first Allocate a piece of memory so you can access it across banks.cblock 0x70Reg1endcThen you need tomovlw 0xA1movwf Reg1AVR comes with 16 general purpose registers you can use so unless you need more then 16 self defined variables you can just use those ie.ldi r16, 0xA1So 5 lines becomes 1 line.With PIC it is possible to remove the cblock and replace it with a 1 liner which gives 3 lines to 1 line. The 16 registers will be more then enough for all but the most complex projects. You can achieve the same concept with PIC as the Common Ram is indeed 16 bytes on my PIC16F1829 which is 16 registers you just have to go through the process of defining them, and moving data to them which could be shortened with a macro I guess.It really comes down to personal preference I just don't see why they could not give the 8 bit pics a load immediate opcode and 16 pre defined registers in that common ram saves typing which saves making mistakes.The more I look into it and learn more it is very possible for me to create some convenience code in an include file to deal with a majority of these issues I have.

author: ecat
author_rank: Frequent Contributor
timestamp: March 21, 2013, 05:20:32 pm
content: Quote from: blewisjr on March 21, 2013, 04:47:59 pmBecause they are maintaining backward compatibility with a 1970s architecture, this compatibility is the hallmark of the pic16 devices. If you're after a pic with a more up to date design then use a more up to date pic (18, 24, 32).The AVR is a 1990s design, so naturally it makes the pic16 look old fashioned.

author: ve7xen
author_rank: Super Contributor
timestamp: March 21, 2013, 11:55:31 pm
content: Quote from: AcHmed99 on March 21, 2013, 10:58:39 amFuture is similar to the rest. I think it's $8 FedEx Economy (2-3 day). They charge the GST/HST directly, and there are no brokerage fees.

author: AlfBaz
author_rank: Super Contributor
timestamp: March 22, 2013, 01:47:53 am
content: Quote from: blewisjr on March 21, 2013, 11:06:35 amJust to be clear, I thought we were talking about PIC18's now...Quote from: blewisjr on March 21, 2013, 04:47:59 pmIn your example movlw 0XA1 is identical to ldi r16, 0xA1 and loading more literals into accumulators for further processing is a little futile as you can have the compiler pre-process these literals to give you a result that doesn't need to be calculated at run time.As a possible game leveller PIC's have a lot of instructions that allow you to operate on the memory directly, where as it appears that the AVR's require you to load them into one of the regs first. If you combine this with overlay memory you can create a volatile memory buffer that is accessible across all banksQuoteI don't remember the compiler directive but have a look for overlay in the asm manual as I mentioned above. You don't have to define each and every slot just create a block and index into it.QuoteMacro's play a massive part of your assembly development environment. Unfortunately as time progresses and you invest more time and energy into this you run the risk of not wanting to dump your setup in favour of higher level languagesThe pic16's where not designed as "C compiler friendly" and thus are more suited to asm whilst the AVR's with their registers and hardware stack manipulation commands are ideally suited for C compiler constructs.As you start moving to more complex architectures you start seeing more and more features aimed squarely at supporting compilers. With this in mind the architecture designers start taking advantage of the fact that the assembly will be generated by algorithms in compilers and it becomes difficult to keep these "rules" in your head as you hand assemble.For example a different set of assembly instructions sequences may seem to do the same thing but due to the pipelined nature of command processing one sequence may create a stall in the pipeline because the following instruction has to wait for the previous one to complete its operation before it can continue.I guess the crux of what I am trying to get at here is that you are learning asm on an architecture that was "designed" for it. If you are going to move to an architecture that's been designed for programming with a more advanced tool then take advantage of it and use it (ie C/C++)

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 22, 2013, 02:45:15 am
content: Yes the cblock directive is for that in my above code you define the block and it works from that memory address up auto placing each register in the appropriate address.I do agree with you that AVR, PIC18, 16 bit PIC, and 32 bit PIC are designed with C in mind. Actually the enhancements to the Enhanced mid range PIC16's was designed to make it more C friendly as well as it states directly in the Power Point and the Data Sheet for the Enhanced Mid-Range 8 bit PICs.I love C and I can't wait to start using it. I actually built the same binary number counter on my Arduino using C in the Arduino IDE and it was very nice and quick. Much less typing for sure. The reason I am dealing with ASM is to get a feel and better understand it at that level incase I need to use it to optimize my code. I am not planning on learning everything there is about PIC or AVR ASM or any chips ASM for that matter I just want to know enough to be comfortable with the basics so that if I do need to inline some ASM I can do it just by looking up the instructions I need in the datasheet and doing it.I feel I will indeed be moving to C very soon as I am becoming somewhat comfortable I wrote the PIC binary number counter without looking anything up at all.In all honesty I think I was over reacting when I said pic is a mess I should have said pic is very different then what I would expect from an architecture in 2013. Like you said it is a very old architecture and they improved in the PIC18 + chips which I agree.The only issue with PIC at the moment for me from the C perspective is the compiler price. This is rather steep $450 + a yearly subscription seems a bit steep but for a while I should be able to just use the free compiler. If it does become a sever problem it is probably time to shell out the cash anyway.Thanks for all the help everyone much appreciated. For now I am going to stick with PIC I don't see why not I am becoming comfortable with working with the chips. I will also start dabbling more with my Arduino as well it was really quite interesting with how easy it was to just move the jumpers from my PIC plug it into the header and write the code and boom just works.No matter what I am having tons of fun working with these chips and I am learning quite a bit about circuits in the process too. I am so glad I picked this up for my hobby. So much to learn and the possibilities for projects go as far as the imagination can dream.

author: ptricks
author_rank: Frequent Contributor
timestamp: March 22, 2013, 03:46:13 am
content: I mainly use PIC based chips and the first tip I can give beginners is learn some basic asm and then start using c and most of your frustration with PIC will go away. You need asm for understanding debugging if something goes really wrong but otherwise don't spend a lot of time with it.The PIC chips have been around for a long time, I have chips from the 1990's. Microchip doesn't make things easier either , where most chips are released with the numbers incremental , like 8051,8052 , etc. Microchip jumps all over the place with creations like 16F917 released in 2007 and the 16f887 released 2012. I stay with PIC for a lot of reasons but the main ones are price and availability . If you need a chip for a certain project chances are they have one with the on board peripherals to match. Sometimes I think the engineers at Microchip write down features on slips of paper , toss them all in a hat and draw out what mix of features will be the next chip.They have some interesting features like the 16f1783 chips I am currently experimenting with, has internal opamps ,every pin can do interrupt on change, and a programmable switch mode power controller with 16bit PWM channelsIf you really want to go modern with asm and C look at the Pic32 line, they are mips cores , designed with c in mind and really have nothing in common with the 16f/18f line.

author: poorchava
author_rank: Super Contributor
timestamp: March 22, 2013, 09:57:07 am
content: In Europe it's kinda harder than in US. Digikey, Mouser, Future, Newark are almost non-existant for hobbyists. RS-components in my country refuses to sell to people who don't run their own business. Out of large suppliers (in Poland) we have only Farnell (where lots of interesting stuff has to be shipped fromNewark adding $35 shipping charge to the bill - unacceptable), TME and a few smaller ones.Booooy, would I be happy if we had Digikey with cheap shipping locally.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 22, 2013, 12:52:02 pm
content: Quote from: ptricks on March 22, 2013, 03:46:13 amYes I do agree that they have amazingly priced chips if only there compilers were amazingly priced. I decided to experiment and covert the PIC 16F1829 ASM binary counter code to C so that I can see the difference between the PIC C code and the Arduino C code. Arduino is a little odd but it can probably be cleaned up more as I am not sure if I can get direct PIN access using the Arduino libraries or not. I will say I think the C is much nicer then ASM but I already knew that because I love C.Here is the PIC code followed by the Arduino code if anyone cares to compare.Code:/******************************************************************************* Program: BinaryCounter* File: binary_counter.c* Date: 3/22/2013** This program is an 8 bit binary counter. The program loops through the* the numbers 0 - 255 in binary and displays each number on a line of 8 LED's.* There is a 1 second delay between each number change to make the count* visible to the human eye.** PIC: 16F1829* Compiler: XC8 v1.12* IDE: MPLABX v1.70*****************************************************************************/#include <xc.h>#define _XTAL_FREQ 500000 // 500kHz frequency for __delay_ms()// Config Word 1#pragma config FOSC = INTOSC#pragma config WDTE = OFF#pragma config MCLRE = OFF#pragma config CP = OFF#pragma config CPD = OFF#pragma config BOREN = ON#pragma config CLKOUTEN = OFF#pragma config IESO = OFF#pragma config FCMEN = OFF// Config Word 2#pragma config WRT = OFF#pragma config PLLEN = OFF#pragma config STVREN = OFF#pragma config LVP = OFFvoid main(void){// 8 bit number (1 byte)unsigned char cnt = 0;// set internal oscillator to 500kHZOSCCON = 0b00111000;// make all of PORTC (RC0 - RC7) and outputTRISC = 0;while (1) {LATC = cnt;// 1 second delay__delay_ms(1000);// increment count by 1// when it overflows passed 255 it will reset to 0cnt++;}}Code:byte cnt = B00000000;void setup(){for (int i = 0; i <= 7; i++) {pinMode(i, OUTPUT);}}void loop(){for (int i = 0; i <= 7; i++) {digitalWrite(i, bitRead(cnt, i));}cnt += 1;delay(1000);}

author: Slothie
author_rank: Regular Contributor
timestamp: March 22, 2013, 02:17:57 pm
content: Quote from: blewisjr on March 22, 2013, 12:52:02 pmYes, you can access all the AVR ports & registers from an Arduino sketch;http://tronixstuff.wordpress.com/2011/10/22/tutorial-arduino-port-manipulation/

author: AlfBaz
author_rank: Super Contributor
timestamp: March 22, 2013, 02:33:44 pm
content: Quote from: Slothie on March 22, 2013, 02:17:57 pmCode:void loop(){PORTD = B11111111;PORTD = B00000000;PORTD = B11111111;PORTD = B00000000;PORTD = B11111111;PORTD = B00000000;PORTD = B11111111;PORTD = B00000000;PORTD = B11111111;PORTD = B00000000;}

author: AlfBaz
author_rank: Super Contributor
timestamp: March 22, 2013, 02:53:16 pm
content: Quote from: blewisjr on March 22, 2013, 12:52:02 pmI don't know about yourself or others but I had a hard time digging through all the documentation to get the appropriate config pragma'sMPLAB IDE had a dialog box that allowed you to select them which was handy but you would be crazy not to put them in one of your source files. Myself and others ask MC to have this IDE function generate an include file from this selection dialog but it never eventuated.What I did was copy the config text from the help file and created a header file that contained all the possible config permutations.and then you simply included it in your c file.At the start of the project you would go through and uncomment the configs you wanted and you could be sure you hadn't forgotten any or rely on the programmer setting all the ones you don't use to defaults.Ive attached an example one I created for the 18f4550

author: westfw
author_rank: Super Contributor
timestamp: March 22, 2013, 04:08:30 pm
content: Note that it seems to be "standard practice" NOT to include fuse settings in AVR C source code...(For something like Arduino, the fuses are "set" during the bootloader burn, and not changeable anyway.)

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 22, 2013, 04:35:59 pm
content: Quote from: AlfBaz on March 22, 2013, 02:53:16 pmI just grab the config pragmas from the data sheet config section all the bits are listed with their possible values.

author: Unknown
author_rank: Unknown
timestamp: March 22, 2013, 04:42:47 pm
content: very neat and tidy code! ;-)

author: AlfBaz
author_rank: Super Contributor
timestamp: March 22, 2013, 04:52:17 pm
content: Quote from: westfw on March 22, 2013, 04:08:30 pmThat seems like a strange practice. Saving fuse settings in a proprietary project file isn't a very good idea, especially if they change its format.

author: ve7xen
author_rank: Super Contributor
timestamp: March 22, 2013, 06:20:04 pm
content: Quote from: AlfBaz on March 22, 2013, 04:52:17 pmYeah it's pretty common, and pretty stupid. avr-libc even supports setting the fuses in the source file, and saving them in ELF output, which avrdude can burn for you. Seehttp://www.nongnu.org/avr-libc/user-manual/group__avr__fuse.htmlBe careful though, the fuses are inverted logic; 1 is clear and 0 is set. In avr-libc this is reflected in the macro definitions.Not sure why nobody does this...

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 22, 2013, 06:36:56 pm
content: Quote from: AlfBaz on March 22, 2013, 02:33:44 pmI agree with aand raise you oneThen again it could be worse.... But could be much much better.Would much rather see this which makes much more sense since he is just flip flopping the whole port high low.Code:void setup(){PORTD = B00000000;}void loop(){for (int i = 0; i <= 9; i++) {PORTD ^= B11111111;}}Also thanks for the tip on writing directly to the port here is the updated arduino code to be more efficient with less loops.Code:/******************************************************************************* Program: BinaryCounter* File: binary_counter.ino* Date: 3/22/2013** This program is an 8 bit binary counter. The program loops through the* the numbers 0 - 255 in binary and displays each number on a line of 8 LED's.* There is a 1 second delay between each number change to make the count* visible to the human eye.** uC: Arduino Uno Rev3 ATmega328P-PU* Compiler: AVR-GCC* IDE: Arduino 1.0.3*****************************************************************************/unsigned char cnt = 0;void setup(){DDRD = B11111111;}void loop(){PORTD = cnt;delay(1000);cnt++;}

author: mrflibble
author_rank: Super Contributor
timestamp: March 22, 2013, 08:09:09 pm
content: And 100% guessing, just going by name of function ... you can probably get away with:Code:void loop(){PORTD ^= B11111111;}Because we all know how this sort of code grows historically.Some monkey does this, some other monkey copies that, etc. Isuspectthat loop() is getting called from somewhere else already in an infinite loop. Unless there is a very specific reason why you toggle the port 10 times, which I doubt.But asgoes ... this isn't so bad. I've seen worse. Much much worse.This just looks like My First Attempt At Code, so as long as people learn from that and get better at it, who cares if it's suboptimal.

author: ve7xen
author_rank: Super Contributor
timestamp: March 22, 2013, 08:25:38 pm
content: Unrolling loops is pretty common. I wouldn't quite call it a, though I'm not sure I see the point for an infinite loop, it will bring down the average loop iteration time slightly (though for an infinite loop, probably only the one jump instruction...), but introduce inconsistency after each iteration.Also it's ugly if you don't need the tighter timing...

author: andersm
author_rank: Super Contributor
timestamp: March 22, 2013, 08:36:38 pm
content: Quote from: AlfBaz on March 22, 2013, 02:53:16 pmIn MPLAB X you open the config bits memory view, edit them as you see fit, click the "Generate Source Code to Output" button and the #pragma statements will be generated into the IDE message area from where you can copy them into your source code.Quote from: mrflibble on March 22, 2013, 08:09:09 pmIf you want to flip bits on an AVR, use the PINx registers, none of this read-modify-write nonsense.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 22, 2013, 10:01:12 pm
content: Quote from: mrflibble on March 22, 2013, 08:09:09 pmIt is a Arduino required function a hidden main calls it from a while(1) infi loop. As far as my for loop goes the original link used 10 port modifications so I did the same thing because I believe the original author was using it to generate something to demonstrate what is happening on the oscilloscope.

author: westfw
author_rank: Super Contributor
timestamp: March 23, 2013, 01:34:55 am
content: QuoteApparently, this is a relatively recent "feature." Sort-of an avr-gcc problem; the output format of the compiler doesn't really include the idea of fuses, so everyone has to agree on some "section" that is going to contain the fuse data, and what it looks like, and etc.Including fuse data in the source code is pretty ambiguous. Fine for reproducing exactly the original firmware configuration, but wrong for so many other applications. For example, when using a bootloader, fuse values would have to be ignored because bootloaders can't burn fuses. Also, incorrect fuse values for the actual hardware can "brick" AVRs in various ways.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 23, 2013, 02:05:43 am
content: Quote from: westfw on March 23, 2013, 01:34:55 amYes I have heard that about AVR's many people have bricked their Arduino's by screwing up the fuses when using Atmel Studio when using a programmer instead of the bootloader. Some people could not even recover the chips. I can see the advantage of the bootloader forcing fusing settings so you can't muck them up.

author: hans
author_rank: Super Contributor
timestamp: March 24, 2013, 12:47:28 pm
content: Just throwing in my 2 cents in here, because I see many old comparisons to classic 'avr vs pic' battles.The assembler of PIC 8-bit devices is horrible. End of it. Not much registers, banks, slow instruction speed. Ugh.The assembler of AVR seems nicer, and because of the much higher instruction speed it's much faster. Flat memory, nice!The C/C++ compiler of AVR 8-bit is good, because you have support for full CandC++, which I really lack even on 8-bit. I agree, you wouldn't write C++ on a PIC16 device, but on a PIC18 that carries either on-board USB plus ethernet and a bunch of sensors, it can be useful to program in objects.The C compiler for PIC16/18 is a pain. The free XC8 is obviously bloating NOP's and BRA's all over the place to make the commercial version look worthwhile. If possible, only use these devices for non-timing-critical projects.Packaging/pricing/availability: unless it's really hard for you to access a certain device, then pick what you can do, otherwise get breakout SMT boards and there basically is no limits for most QFP parts.I work with SMD components all the time on breadboards with the use of some simple breakout boards etched on college. If required, get some wire wrap and prototype that way.Like here with a ENC28j60, and bodge 0402 50R termination resistors between the pins of an ethernet transformer.Selecting chips for 'DIP only' is a pain for yourself, because the more popular and common chips are going towards SMT today.I've never written ASM on ARM (only C and looking at the produced ASM), but I do know the architecture of ARM is very nice , with DATA and CODE in 1 space, instruction sets like Thumb to reduce code space, better interrupt vectors, etc.I'm writing some inline-ASM on PIC24/dsPIC33 and it seems OK. It has 16 work registers, stack pointers and seems like a performance-orientated instruction set.Code:MOV W0, [W8++] ; move value W0 to address pointed by W8, move W8 pointer 1 furtherSUB W0, #10h, [W8++] ; subtract 10h from W0, store result in address pointed by W8, move W8 pointer 1 furtherMOV W0, [W8+1FAh]These operations are 1 instruction word (which is actually 24-bits, or 3 bytes) and take 1 cycle.However, moving a literal to a RAM byte, is still:Code:MOV #24h, W0MOV W0, 0xCAFE ; CAFE = your RAM addressAtleast it also has some software traps and interrupt vectors, so the hardware pre-sorts interrupt sources to your handlers.Unfortunately, you have to maintain the stack in software, which can cost some cycles. But if your ISR is really that time critical; write it in ASM so it doesn't produce much overhead anyway.For me personally I wouldn't touch 8-bit PICs that much, especially not if I am looking out to write decent/clean code. I always have to do some adjustments here and there to make it compile and work efficiently on 8-bit PICs.16-bit and 32-bit PIC's seem OK, just like 8-bit AVR's was for years. Unfortunately, the support for C++ is very shabby from Microchip, where they only just released it for PIC32.. It sounds to me the code density on 8-bit AVR's may be a bit higher than PIC24s , but then again 8-bit AVR's work with 8-bits, and PIC24s with 16-bits.

author: andersm
author_rank: Super Contributor
timestamp: March 24, 2013, 03:32:15 pm
content: Quote from: hans on March 24, 2013, 12:47:28 pmOh lay off the conspiracies. The code generated by C compilers is almost always extremely verbose before any optimizations have been applied. The big difference is how much work a compiler will do even when it's claiming no optimizations are being used.

author: hans
author_rank: Super Contributor
timestamp: March 24, 2013, 05:48:05 pm
content: That's exactly what I mean; their optimizer isn't the worlds state of the art optimizer, it's just that; a normal 'optimizer' which has been left out the free version.If you have the PRO version and keep optimizations turned off, your code size already has dropped dramatically over the FREE version.Enabling extra optimizations (of which there aren't many - all default none) is not very effective in reducing the code footprint compared to the free/pro relationship.As I said, they bloat the code for no obvious reason other than marketing that their optimizer will optimize typically 40% over free version builds. They are charging an awful lot of money for something that's included in a standard GCC build.

author: andersm
author_rank: Super Contributor
timestamp: March 24, 2013, 08:38:52 pm
content: To claim they spent the effort to intentionally pessimize the code to make their own compiler look bad is ludicrous. XC8 isn't based on GCC, but comparing GCC's -O0 to other compilers' equivalent is a good illustration of my point.

author: westfw
author_rank: Super Contributor
timestamp: March 25, 2013, 09:05:15 am
content: QuoteThe examples I've seen of the microchip PIC compilers "completely unoptimized" compiler are MUCH worse than gcc's -O0 output. That's why people were/are disappointed; they were expecting -O0 like output, and instead got stuff that looks like a Compilers-101 class three-operand pseudo-code simplistically translated into PIC. I'll see if I can come up with a realistic example...

author: andersm
author_rank: Super Contributor
timestamp: March 25, 2013, 12:04:02 pm
content: I'm not disputing that the produced code isn't awful, but that's a lot different that saying it's made intentionally worse.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 25, 2013, 12:14:12 pm
content: With my simple code I have not had any issues with the XC8 compiler yet. On average I see a 10 byte increase. The only significant issue I see in the asm was writing to port instead of latch. The delays are a bit sloppy but if you need tight like others said inline asm. Not sure how it looks for more complex code with conditionals.

author: AlfBaz
author_rank: Super Contributor
timestamp: March 25, 2013, 01:19:55 pm
content: Quote from: blewisjr on March 25, 2013, 12:14:12 pmInteresting... are you saying that in c you type latb=xx and the compiler produces portb=xx, or are you typing portb=xx and you are expecting latb=xx. The latter would be a compiler bug

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 25, 2013, 01:46:04 pm
content: Writing in c latc = xxx and getting portb almost positive I will re look at and post the listing when I get home tonight.

author: AlfBaz
author_rank: Super Contributor
timestamp: March 25, 2013, 02:04:32 pm
content: assuming latc portb is a typo and you meant latc portc, I was under the impression you were working with a pic16 part, maybe it doesn't have a latch register and the compiler was kind enough to accommodate. If that's the case check the devices header file and see if they've defined latches equal to ports

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 25, 2013, 02:59:22 pm
content: Was working with a 16f1829 and I did mean portc but there is actually 1 latch for each port on the chip. So that is not the issue. This comes from the data sheet I checked and the tuts that came with the chip + dev board.

author: westfw
author_rank: Super Contributor
timestamp: March 25, 2013, 10:40:06 pm
content: OK, here's some actual code that I ran through a freshly-downloaded "free" version of XC8 for a "real" PIC12f675 application that I had lying around. The actual app runs pseudo-random PWM on several LEDs to create a "flame" effect, and was previously compiled using the free version of "cc5x"... I think the example serves to illustrate the sort of thing that people are complaining about...This is from MPLABS disassembly listing; I've added the ";;" comments.Code:void main(void)!{! char pwm1, pwm2, pwm3, pwm4, pwm5, level_delay, pwm_delay;! init();0x2FE: CALL 0x2F0! bright1 = 50; // "random" initialization0x2FF: MOVLW 0x320x300: BCF STATUS, 0x5 ;; unnecessary setting of status.0x301: MOVWF 0x23 ;; unnecessary (and soon overwritten) save to mem 23.0x302: MOVF 0x23, W ;; unnecessary move back to W.0x303: MOVWF bright1! bright2 = 20;0x304: MOVLW 0x140x305: MOVWF 0x23 ;; status already set, so only the mysterious loc 23 code!0x306: MOVF 0x23, W0x307: MOVWF bright2! bright3 = 10;So that's 4 or 5 instructions where there should be 2. Presumably the code generator has nice rules about keeping the status register up-to-date, along with some internally-used temporary register?Later, we have some conditional code:Code:! if (--pwm3 == 0) {0x350: MOVLW 0x10x351: SUBWF pwm3, F0x352: BTFSS STATUS, 0x20x353: GOTO 0x3550x354: GOTO 0x3560x355: GOTO 0x358! led3_off;0x356: BCF GPIO, 0x30x357: GOTO 0x358! }Isn't that a swell chain of three GOTOs? I think one would do... Presumably these implement a generic conditional branch if/else setup, using the skip instructions. But, yuck!(Just for reference, here's the similar part of code from CC5x (which also claims to have better optimization in their "non-free" version. I like the CC5X code just fine, but find the XC8 code "yucky." You can make your own judgements.)Code:0049 2001 0247 CALL init0248 ; bright1 = 50; // "random" initialization004A 3032 0249 MOVLW .50004B 00A8 0250 MOVWF bright10251 ; bright2 = 20;004C 3014 0252 MOVLW .20004D 00A9 0253 MOVWF bright20254 ; bright3 = 10;:0317 ; if (--pwm3 == 0) {0073 0BA2 0318 m010 DECFSZ pwm3,10074 2877 0319 GOTO m0110320 ; led3_off;0075 1283 0321 BCF 0x03,RP00076 1505 0322 BSF 0x05,GPIO2

author: andersm
author_rank: Super Contributor
timestamp: March 25, 2013, 11:03:22 pm
content: Looks like pretty typical unoptimized code, especially the redundant loads and stores. You get a lot of that from GCC too.

author: westfw
author_rank: Super Contributor
timestamp: March 26, 2013, 03:09:37 am
content: Here's what gcc produces for AVR, with -O0 (optimization explicitly turned off)Code:;; The initialization code is much nicerbright1 = 50; // "random" initialization178: 82 e3 ldi r24, 0x32 ; 5017a: 80 93 61 00 sts 0x0061, r24bright2 = 20;17e: 84 e1 ldi r24, 0x14 ; 20180: 80 93 64 00 sts 0x0064, r24bright3 = 10;184: 8a e0 ldi r24, 0x0A ; 10186: 80 93 60 00 sts 0x0060, r24:;; But the conditional code is considerably worse.if (--pwm3 == 0) {1fe: 8d 81 ldd r24, Y+5 ; 0x05 ;; local variables come from the stack200: 81 50 subi r24, 0x01 ; 1 ;; decrement202: 8d 83 std Y+5, r24 ; 0x05 ;; and go back to the stack.204: 8d 81 ldd r24, Y+5 ; 0x05 ;; and are gotten from the stack again206: 88 23 and r24, r24 ;; separate test for zero.208: 39 f4 brne .+14 ; 0x218 <main+0xb6>led3_off;20a: a8 e3 ldi r26, 0x38 ; 56 ;; and then we have this awful code for led3_off, which20c: b0 e0 ldi r27, 0x00 ; 0 ;; isn't quite fair because avr uses portb &= ~mask;;; while the PIC has "bit variables" gpio3 = 0;20e: e8 e3 ldi r30, 0x38 ; 56210: f0 e0 ldi r31, 0x00 ; 0212: 80 81 ld r24, Z214: 8b 7f andi r24, 0xFB ; 251216: 8c 93 st X, r24 ;; and separate pointers for reading and writing??}I rather like this "bad code" better than the PIC's bad code, because it's more obvious what it's doing and what it hasn't done. The AVR code is a sort of naive translation of the C into AVR assembler. The unoptimized PIC code is (probably) more of straightforward translation of an "intermediate abstraction" of a compiler target (one short sequence of PIC code for each abstracted operation), and is much less obvious (thus leading to the rumors of intentionally bad code.) (because you can think in C, or you can think in assembler, but somehow compiler writers' usual abstraction isn't very close to either one. Sigh.)Of course, avr-gcc does support optimization. With -Os, I get:Code:;; (The initialization code is the same)if (--pwm3 == 0) {11a: 91 50 subi r25, 0x01 ; 1 ;; local variables now optimized to registers.11c: 09 f4 brne .+2 ; 0x120 <main+0x5c>led3_off;11e: c2 98 cbi 0x18, 2 ; 24 ;; The special io bit set ins is used!}

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 26, 2013, 09:28:48 am
content: Ok here is the listing file for my binary counter program run on a raw PIC16F1829 from breadboard. I added ;; comments to point out the spots that I found as an issue in my previous few posts yesterday.Code:37: void main(void)38: {39: // 8 bit number (1 byte)40: unsigned char cnt = 0;07E7 01F2 CLRF cnt41:42: // set internal oscillator to 500kHZ43: OSCCON = 0b00111000;07E8 3038 MOVLW 0x3807E9 0021 MOVLB 0x107EA 0099 MOVWF T1GCON44:45: // make all of PORTC (RC0 - RC7) and output46: TRISC = 0;07EB 018E CLRF PORTC ;; NO! You should be clearing TRISC (Surprised this line is not causing issues)07EC 2FED GOTO 0x7ED47:48: while (1) {07FD 2FED GOTO 0x7ED ;; Why? totally not needed 7ED is the next instruction!49:LATC = cnt;07ED 0872 MOVF cnt, W07EE 0022 MOVLB 0x207EF 008E MOVWF PORTC ;; NO! You write to LATC not PORTC50:51:// 1 second delay52:__delay_ms(1000);07F0 30A3 MOVLW 0xA307F1 00F1 MOVWF 0x7107F2 3055 MOVLW 0x5507F3 00F0 MOVWF 0x7007F4 0BF0 DECFSZ 0x70, F07F5 2FF4 GOTO 0x7F407F6 0BF1 DECFSZ 0x71, F07F7 2FF4 GOTO 0x7F453:54:// increment count by 155:// when it overflows passed 255 it will reset to 056:cnt++;07F8 3001 MOVLW 0x107F9 00F0 MOVWF 0x7007FA 0870 MOVF 0x70, W07FB 07F2 ADDWF cnt, F07FC 2FED GOTO 0x7ED57: }58: }07FE 3180 MOVLP 0x0

author: baljemmett
author_rank: Unknown
timestamp: March 26, 2013, 12:35:14 pm
content: Quote from: blewisjr on March 26, 2013, 09:28:48 amI think this is just a failure of the listing pretty-printer -- remember the PIC banks its registers, so only the bottom part of the register address is present in the MOVWF instruction. The other half is in the bank select bits, which in your excerpts are set by the MOVLB calls prior to the MOVWFs; the pretty-printer is obviously just looking up the operand and translating to a bank 0 address, rather than trying to keep track of which bank will be selected for each instruction. I would imagine the register summary will show PORTC, TRISC and LATC are all at the same address but in banks 0, 1 and 2 respectively.(Not that I've actually checked, of course, but that's certainly how PORTx and TRISx are laid out on chips that don't have the LATx registers...)

author: JTR
author_rank: Regular Contributor
timestamp: March 26, 2013, 01:59:52 pm
content: Quote from: baljemmett on March 26, 2013, 12:35:14 pmCorrect. There is nothing wrong with the actual code it is just that the disassembler does not even try to track the bank select bits so all names given to SPRs will pretty much default to the name of the SPR in bank 0. The same thing happens regardless of language or compiler. It is the "dumb" disassembler that is defaulting the SPR names to bank 0 values.To get an assembler source listing containing the correct SPR names from XC8 I believe you must use the correct switches on the command line.

author: blewisjr
author_rank: Frequent Contributor
timestamp: March 26, 2013, 05:30:55 pm
content: Ok that makes perfect sense and explains why no code issues arise.

author: ptricks
author_rank: Frequent Contributor
timestamp: April 08, 2013, 01:22:29 pm
content: One thing to be careful of with PIC is controlling the bits on a port with the PORT command, use LAT for changing a port from 0 to 1 or 1 to 0 .If you use PORT to change the bit ,the bit may not change right away or may take a cycle or two to change because PORT is telling the chip to write the value to the latch. Depending on the chip the write may not take place at all if it is shared with a peripheral and the PORT command is used.PORT for read and LAT for write, keeps it simple.Early PIC chips may not have LAT so you have to use PORT.In the source code , setting up the oscillator should be done and tested before you start assigning port uses.Quote

author: blewisjr
author_rank: Frequent Contributor
timestamp: April 09, 2013, 01:56:04 pm
content: NOTE: This is not comprehensive and I may have made a few wrong assumptions etc... I am new to micro's like many other people and still learning various things about how the compilers work with them as I go along. I am also not a compiler expert in no way shape or form.Well it has been a while actually particularly because I have been doing various testing scenarios on my own to come to a conclusion. So now that the testing is done I figured I would stop by and explain the conclusion I came to.I ultimately Tested 2 chips ended up being 3 due to a odd discrepancy that came up on the PIC side but after reviewing the lst files generated by XC8 it turns out the discrepancy was only in setup code. So the 2 chips used were the PIC18F14K22 (20 Pin PDIP) and the ATMega328P (28 Pin PDIP).I reviewed basic chip features and peripherals first.PIC Flash = 16 kbytes AVR flash = 32 kbytesPIC SRAM = 512 bytes AVR SRAM = 2 kbytesPIC EEPROM = 256 bytes AVR EEPROM = 1024 bytesPIC ADC = 12 10-bit channels AVR ADC = 6 10-bit channelsPIC I/O = 17 + 1 (input only) AVR I/O = 22 + 1 if RSTDISBL Fuse is setNeither Chip has DACPIC Max Op Freq = 64MHZ (With PLLEN) AVR Max Op Freq = 20 MHZPIC Instruction set = 74 (std) 83 (ext) AVR Instruction set = 131PIC WREGs = 1 AVR WREGs = 32This was just a quick basic overview there are many differences but both chips are very comparable.With both chips I decided to write a hello world blinking led program to compare compiler output size as the biggest factor in my decision involves the toolchains and development environments. With PIC I used MPLABX with the XC8 C compiler. With AVR I used AVR Studio 6 with AVR-GCC compiler.The first major difference I noticed was that with developing PIC you need to set the chips fuses in code. This is rather crappy in my opinion as it is rather tedious to do and easy to make a slip up, however this can be negated by creating a standardized header file to handle this for us. With AVR you set the fuses with a tool in the IDE by setting Hex values. This tool was awesome especially when you have a calculator Like the one at Engbedded to calculate the bit values for you. You can also just select the fuse settings right from the tool as well instead of using values.The next major difference is in the IDE quality. MPLABX on netbeans does have the advantage of cross platform, however, as a whole MPLABX is very buggy and a lot of the issues arise directly from the core netbeans backend. These bugs have been in netbeans for a long time and I swear Oracle refuses to fix them. AVR Studio is built on VisualStudio and despite it not being cross platform it is rock solid and just works with no real annoyances. The only real annoyance I found was when programming the chip if the programming rate is too low or too high in the tool project settings the chip will not program and the error you get is so obscure you would almost never guess it was the programming rate.The code I wrote was as similar as possible. API wise XC8 wins by having the I/O registers built as structures where you can access the bits likeLATCbits.LATC0 ^= 1.With AVR you need to do aPORTB ^= (1<<0); or a PORTB ^= _BV(0); or PORTB ^= (1<<PORTB0); or PORTB ^= _BV(PORTB0);This is a negligible issue really but I think the Structure method leads to code that looks cleaner in the long run.Not really much more then this as it was just hello world. Now onto the code size difference.The PIC compiled to 62 bytes of flash (Free version of compiler with little optimization) With the AVR it compiled to 162 bytes of flash (O1 optimization, however it was the same under all levels of optimization due to simplicity of program).WOW!!!!! The AVR was 100 bytes larger. Okay Okay lol. Now in all seriousness yes it is 100 bytes larger but in the long run it would gradually equate to or be smaller then the PIC code. HUH? Yes it would. In such a simple program the differences are amplified so let me explain why. Setup Code!!!!!. All the extra working registers on the AVR take up some space. Also AVR-GCC sets up all the Interrupt vectors where the pic does not leading to 68 extra bytes. So if you take into account all of this stuff over time the AVR will come out ahead as the pic will have to add this extra stuff later. Also the 31 extra working registers means we have to use less ram overall. So if you put the chips under an even playing field the AVR has a extra 100 bytes of setup code take that away and they are both at 62 bytes of flash in theory ONLY. But as stated eventually the PIC will have to init the interrupts etc... Being that I do not have $450 - $1000 for compilers as projects become more complex the AVR will always come out on top for me code size wise because I have access to optimization levels that I don't get with PICs free XC8.So after all this I decided I have to make a decision over all. It is without a doubt that Microchip has a greater variety of chips available but AVR has a great selection as well just smaller. The tool chain for AVR covers all of their chips 8,32, and ARM. Where with PIC every chip class 8, 16, or 32 has a different compiler. Overall I have always like visual studio far better than netbeans. I also really like gcc it is a very solid tool. I have also decided to move away from asm for now and go to C because I have a much better understanding of how things are working under the hood now. So for me and my hobby endeavours I am going to have to go with AVR. I really like the development echo system and it really fits the tight hobby oriented budget. I will keep PIC in mind always because they really are great chips and you never know when a project might need one.

author: andersm
author_rank: Super Contributor
timestamp: April 09, 2013, 02:25:51 pm
content: Quote from: blewisjr on April 09, 2013, 01:56:04 pmMPLAB X does have a built-in editor for fuses. If you open up the Configuration Bits memory view you can edit the bits as you see fit, and when you click the "Generate Source Code to Output" button it generates code which you can copy into your source files.

author: blewisjr
author_rank: Frequent Contributor
timestamp: April 09, 2013, 04:13:21 pm
content: Quote from: andersm on April 09, 2013, 02:25:51 pmOh wow that is really cool can't believe I missed that I guess it is just not as in the face obvious as the one for AVR Studio.Another thing I did notice is from a Chip perspective feature wise PIC really does come out on top in almost every case there selection is really amazing. My biggest issue is there compilers the price is just so crazy and as a hobbyist eventually it will bite me in the ass if I embark on a crazy project. Having the different compiler for every chip is just bad imho and the $450 per compiler for 25% optimization + the maintenance subscription is just not feasible from my perspective. It would be really nice if they could smarten up about the compiler situation if it was not for the compiler price PIC would have been a really easy choice. Sure there is SDCC which is free and covers quite a bit of 8bit PIC chips but the pace that they add new chips is very slow and I am not sure how well it integrates with MPLABX.

author: ptricks
author_rank: Frequent Contributor
timestamp: April 09, 2013, 10:11:38 pm
content: SDCC is free for pic and you can use whatever IDE you want . If a pic isn't supported it is easy to add it, just create new include files.Some useful tools for pic that are free:http://vasco.gforge.enseeiht.fr/index.php?article=PUF.htmlhttp://sdcc.sourceforge.net/http://www.casadeyork.com/jalv2/https://code.google.com/p/jallib/http://www.sfcompiler.co.uk/swordfish/http://sourceboost.com/Products/Products.htmlSourceboost really isn't all that well known, but the compiler is one of the best I have used and the pricing is fair going from free to $150 for full commercial version.

author: westfw
author_rank: Super Contributor
timestamp: April 10, 2013, 09:04:47 am
content: QuoteThe AVR has different compilers for each range of chips (AVR, AVR32, ARM.) They're all builds of gcc, but you'll still have three directory structures, three sets of binaries, and (probably) version and up-to-date issues of one WRT another.QuoteIs that based on your personal experience, or hearsay? With MPLABX, or other NetBeans IDEs?QuoteOh come on. If you're going to create a benchmark, you shouldn't then make up excuses as to why the results "really mean" something different than they actually show. You don't have any evidence at all that the AVR code will be smaller in any real-world application; you're just repeating your assumptions. I mean, I think you're probably right, but you might as well not have done any benchmark at all! (In fact, the inability of avr-gcc to "prune" the interrupt vector table to reflect only the interrupts actually used is a subject of somewhat frequent "request for enhancements." That 68 bytes (plus or minus, for different AVRs) can be pretty painful for small chips, or if you're trying to fit a bootloader in 512bytes, or whatever. (Fortunately, it's pretty easy to omit the vector table entirely.)QuoteNo, not WRT the image size. In fact, you can write substantial AVR programs that use NO ram, storing all their data in registers (and there are (were) AVRs that don't HAVE any RAM; just the registers.)

author: blewisjr
author_rank: Frequent Contributor
timestamp: April 10, 2013, 11:08:35 am
content: The IDE bugs I talk about come from netbeans in general they are minor but can get annoying at times most deal with the code editor. I also do apologize for reiterating my assumptions but I really do not have much more to go off of. Everything turns out to actually be quite similar in the long run. I am still evaluating the situation partly because of the great pic community plus huge chip selection. Hands down there chips have more variety of perifs.As for the working registers sure they do not take ram but what the lst shows me is that they do inc the setup code size but I could be reading it wrong.

author: Unknown
author_rank: Unknown
timestamp: April 10, 2013, 11:48:29 am
content: Have you looked into Codeblocks as a potential tool-chain IDE?http://wiki.codeblocks.org/index.php?title=Using_the_Code::Blocks_IDE_with_SDCC_on_PIC_MCUs

author: andersm
author_rank: Super Contributor
timestamp: April 10, 2013, 12:33:00 pm
content: Quote from: westfw on April 10, 2013, 09:04:47 amMy own experience and opinion of using MPLAB X with PIC32s is that it's both buggy and kind of terrible as an IDE in general. It has a tendency of locking up either permanently or for extended periods (ie. several minutes) when debugging, especially if you try inspecting variables.I haven't used other versions of NetBeans so I can't tell what's Microchip's customizations and what's not, but there's also some completely unnecessary idiot-proofing that just gets in your way. For example, if you try to rename a source file the IDE does not allow you to change the extension (to get preprocessing for some assembly source files I had to change the extension from .s to .S, a trivial task that could not be done within the IDE). I also hugely dislike the insistence on collecting all your projects ever within a single instance. Since you inevitably end up with similar files in separate, unrelated projects, you always have to be very careful that you're editing the correct one. Most IDEs allow you collect related projects into a single workspace, but MPLAB X is the only one I know that forces this. And if you want to open a second IDE instance you have to do it from the command line with some special parameters to override the single-instance behaviour. I also just plain don't like the editor, and it's a huge chore to configure it to my liking.MPLAB X also doesn't take account for differences in text rendering on different platforms, so all text fields and buttons kind of overflow and look terrible on OS X. Still, nice of them to support something other than Windows.