PIC design tutorial

Dec 10, 2012 at 8:46 PM Thread Starter Post #1 of 30

wakibaki

1000+ Head-Fier
Joined
May 26, 2011
Posts
1,088
Likes
68
A little while back I made a passing remark about writing a programming example for Microchip PIC.
 
Avro_Arrow said at the time that he would be interested if I took it on. I've been a bit remiss in keeping up my discrete amplifier co-operative design effort with him, so I'm going to write this tutorial. With luck, I'll have at least one reader.
 
The first thing we're going to build is a simple panel (volt) meter with digital readout. This can readily be adapted to show current, volume level, the passage of time or other quantities. It will illustrate an old, widely used, and basic hardware logic concept called BCD, or Binary-Coded Decimal, which dates all the way back to the pre-microprocessor days of early cash-registers and accounting computers.
 
Then we'll move on and convert the design into a push-button controlled TI PGA23xx based volume control, which is a little bit more demanding on the analog side and also introduces a widely used technique for serial control of peripherals called bit-banging. This opens up a simple way of doing I2C, I2S or SPI control.
 
We'll avoid the complications of high-speed timing-critical applications, but we will visit the conceptually important areas of interrupts and multiplexing and use visual persistence to create the illusion of a continuous display by repeatedly flashing 7-segment LEDs very fast.
 
The Microchip PIC and PIC design tools are a no-compromise system. They're not intended for artists or non-technical people to ease them into programming, but this means that if you learn to use them they are a good grounding for moving on to any other professional system. They're not really difficult to understand anyway, as we'll see...
 
These PIC designs use the most fundamental principles and the ideas contained in them can be extended to apply to virtually any kind of programming, be it applications programming for the PC or webpage programming using HTML and javascript. I regularly code in ladder logic, assembly language, C, C++, VHDL, XHTML, javascript, SQL, VBASIC and other scripting languages and I have used many other programming languages, both linear and object-oriented. Once you learn a few, picking up the threads of another is not difficult
 
To program a Microchip PIC you need a hardware programmer. I use a PicKit2 USB programmer. It's not the cheapest programmer, but it's not very expensive, and you can buy clones on ebay. The advantage is that it is 100% compatible with MIcrochip's free programming tools, collectively packaged under the name MPLab. A PicKit3 is also compatible.
 
You can use other toolsuites, build homemade programmers and still probably follow this tutorial. I've built programmers, but it's easier for me not to have to cover all the possible options, so if you use the standard Microchip tools, we'll all be on the same page. If anybody doesn't want to, or can't afford to, I'll try to answer any questions you may have.
 
The PicKit2 and 3 are ISP programmers. In System Programming. This means that you can build PICs into a device and reprogram them in place. You need to put a 5-pin header on the board to connect the programmer to. If you want to program a chip offboard, the simple thing to do is to build an adapter board with a chip socket on it to use with the PicKit and use a leaded chip which you can put into a socket on the target device.
 
I use a lot of surface mount components, it's a superior technology.
 
The first build will require:-
 
1 PIC 16F690
1 common-anode 3-digit 7-segment LED display
1 0.1u capacitor
1 1u capacitor
8 270R resistors
3 1k resistors

1 7805 regulator
3 GP PNP transistors
1 multi-turn preset potentiometer
11 470R resistors
 
PIC programmer, leaded and SMT PIC16F690's and a common-anode 3-digit 7-segment LED display:-
 

 

We can re-use some of these parts in the second build if we use through-hole parts.
 
Although I've built devices similar to these before, they're not complete re-hashes of existing designs. I haven't used this particular PIC before, so these circuits will be drawn up from scratch and hopefully I won't miss out any steps in the development. I'll try and break up the text with illustrations and code examples where I can, but unfortunately, given the nature of the subject, there will be some quite dense text to read.
 
I hope this teaser catches your interest, because there is quite a lot of work for me involved here, and I will need some encouragement if I'm going to plough through it all.
 
w
 
Dec 10, 2012 at 9:08 PM Post #2 of 30
I for one will be following along with great interest mate. I'll not be able to contribute to the topic with knowledgable questions, but I'll wade into the water when I can. I for one hugely appreciate your time and effort to do this Fred.
 
Dec 10, 2012 at 9:46 PM Post #3 of 30
Really appreciate this as well. Being a computer science major, I have a bit of programming experience, but only rudimentary knowledge of assembly and low level programming. I really wish I had taken more electrical engineering classes for stuff like this.I have 0 knowledge on pic programming.  I'll definitely be keeping up with this thread as well :)
 
Dec 10, 2012 at 9:58 PM Post #4 of 30
Hi, Mike.
 
Nice to hear from you.
 
One of the hardest things when talking 'into the blind' like this, is trying to remember the things that I found puzzling and needed to know when I was first learning the subject and making sure that I don't skip over necessary details because I've become so familiar with them.
 
So just give me a poke if you think that I'm running on a bit too quickly, or, on the other hand, if I start to labour the point a bit and get boring, tell me to get a move on...
 
Fred
 
Hi, gambit300, nice to make your acquaintance.
 
Dec 10, 2012 at 10:53 PM Post #5 of 30
What's in a PIC?
 
It's not really possible to discuss PIC utilization without having some kind of idea of what a PIC is.
 
Programming is full of specialised concepts and has its own vocabulary. It really helps to understand a few of these before launching into the business of writing a program, but I'll try to keep this to a minimum and stick to what is really necessary.
 
A PIC is what is sometimes called a microcontroller. It's the essentials of a small computer all built into a single chip.
 
This doesn't really help much if you don't have much of an idea what's in a computer...
 
The overwhelming majority of computers in common use employ what is called a Von Neumann architecture. This consists of a number of internal components. The principal ones are: a processing unit consisting of an arithmetic logic unit (ALU) and processor registers, a control unit containing an instruction register and program counter, a memory to store both data and instructions and input and output mechanisms, or ports.
 
The ALU is a large and complex arrangement of gates.
 
A gate is a device that performs a simple logic function.
 
A logic function is a simple decision made on the basis of inputs. Inputs can be ones (1's) or zeros (0's). In electrical terms, a 1 is normally thought of as a high level voltage and a 0 is thought of as a low level voltage.
 
There are many different technologies from which logic circuits can be built, but the most common one, the one which was first used in personal computers (PCs), was called TTL (transistor-transistor logic). It used 5 volts as a high voltage, which represented a 1, and 0 volts as a low voltage, which represented a zero.
 
PICs can actually use a range of voltages from a bit over 2V to about 6V as their high level, but we're going to talk about them as being 5V devices, and we're going to run them from a 5V supply.
 
So, let's go back to logic functions.
 
An AND gate is a device (black box) with 2 inputs and one output. If (and only if) input 1 AND input 2 are high (1, 5V) then the black box will decide that the output will be 1, 5V. Otherwise it will be 0, 0V
 
An OR gate is a device (black box) with 2 inputs and one output. If input 1 OR input 2 is high (or both inputs are high) (1, 5V) then the black box will decide that the output will be 1, 5V. If both inputs are zero (0, 0V) then the output will be zero (0, 0V).
 
There are a number of simple gates with names like NOR, XOR, XNOR and so on, you can have a 3-input AND or OR gate, but suffice it to say that a bunch of such gates can be combined into what is called an ADDER.
 
Arithmetic.
 
Yes, I know. Most of us would prefer to leave arithmetic and maths to a calculator.
 
The next post will deal with binary and hexadecimal arithmetic. We can't make much progress without dealing with these because the ADDER uses binary arithmetic.
 
w
 
Dec 11, 2012 at 3:39 AM Post #6 of 30
Dec 11, 2012 at 7:34 AM Post #7 of 30
Thanks for taking this on Fred...we are all ears (or eyes as the case may be...) 
bigsmile_face.gif

 
Dec 12, 2012 at 6:29 PM Post #9 of 30
It's hard to be a computer user in this day and age, particularly one who is as technologically aware as somebody who builds their own audio gear is likely to be, and not be aware that binary arithmetic is out there.
 
So if you already understand this aspect of the subject, you may prefer to go away for a while, because I haven't finished writing about it, and I won't be moving on to the other stuff until I've dealt with it.
 
Now it may be that you've looked at some of this stuff before and gone blank, or failed to understand or retain this information for some other reason, but this wouldn't be a tutorial if I didn't attempt to explain some things.
 
We're constantly confronted with digital encoding. Telecommunications companies sell us bits and they sell us bytes, but what are they, and why are they the way they are? If we fail to confront these issues we will be unable to design logic circuits.
 
Why bytes?
 
A byte is eight bits wide. Or long. Why?
 
Guys who were looking at the situation at the time decided that was the best way to go.
 
8 is 2^3. 2 to the power of 3. This makes it a kind of mystical number when designing digital circuits. Digital designers love powers of 2. It's highly convenient because in this case (8 bits) it lends itself to the design of a basic comprehensive hardware computer and it's convenient for human comprehension. Eight bits provides a convenient sized decimal number to contain a wide variety of information by binary coding. Eight bits provides a convenient bridge between human and machine arithmetic via hexadecimal coding. Hexadecimal coding is the fundamental language whereby human requirements are translated into hardware results in electronics when large numbers of numbers have to be processed handraulically.
 
A typical ADDER takes its inputs from 2 ports, typically 8 bits wide, and outputs its result on a third port, again 8 bits wide, but with the proviso that it has in addition a carry or borrow bit. You probably recognize the idea of carrying or borrowing from the arithmetic which you're already familiar with. We'll come back to the ADDER later on. 
 
What we're dealing with is the nitti-gritti detail of how a bunch of numbers can be made to perform a given hardware task. If you're not prepared to think long and hard about what this means, there's not much point in reading any further.
 
So we're going to attempt to learn binary and hexadecimal arithmetic by osmosis, by doing, and by seeing how it's a convenient way of getting things done electronically.
 
The good news is that much of the hard slog can be left to a calculator, the one built in to Windows will do, but a handheld calculator is a useful thing to have.
 
If you're not familiar with the Windows calculator, you can access it by going Start Menu -> Run and typing 'calc' <return>. You'll probably see this usage more than once here, it's common in programming and other computer applications. You type what's inside the speech marks '' and press return, or Enter, the big square key with the hooked arrow on it. There won't be many people reading this who aren't familiar with this convention.
 
That is how the calculator can be accessed in Win XP and earlier versions, perhaps somebody else could write in and tell us how to get it up in later versions of Windows, I noticed just today that the 'run' feature has moved from the Start Menu in WIndows 7, and I have refused to give up my existing installations which use XP, so I'm not familiar with some aspects of Win 7 & 8.
 
You need to put the Windows calculator in scientific mode. Go View -> Scientific. When you see these arrows (->) that means you have to use the menus at the top of the window, or in the Windows Start Menu.
 
Memory is organised in bytes. A byte memory is an array of gates (latches) which are capable of storing a number in the form of eight binary states. The individual states are called bits. States are another name for 1's and 0's. Such an array of latches is also called a register.
 
So bits and bytes actually mean the numbers which can be represented on a port, but also the hardware locations in which a number can be stored, either temporarily (volatile) or (semi)permanently (non-volatile).
 
We like to call this kind of dual-usage of terms 'operator overloading' in computing, and it is an aspect of abstraction, the process whereby digital representations are translated to humanly identifiable quantities for the convenience of programming. Operator overloading means the the same word is used to mean 2 different things, but you have to figure out which one is meant from the context. This makes it much easier for me to write about the subject because I don't have to keep writing 'byte in the sense of an 8-bit number' and 'byte in the sense of an 8-bit register'.
 
A typical address bus of an 8-bit computer system is 16 bits wide, each address comprising storage for 8 bits. This means that in such a system 65536 bytes of storage are provided. Each byte potentially contains a number between 0 and 255.
 
A bus is a bunch of wires connecting corresponding bits of 2 or more ports.
 
The address bus may access a single contiguous series of memories, or it may access an additional array of port addresses and a third array of video memory. 
 
One other important idea we need to become familiar with is the idea of a clock.
 
When the number on any port or in any register needs to be moved to another part of the system its progress is synchronized by a clock.
 
A memory requires to be read for it's contents to be known. This means that the required address is displayed on the processor address bus and the read pin on the memory is set (to 1) (or, more usually, unset [to 0]). If the memory is a standalone chip, very often some other conditions must be met, (it's not uncommon to have 2 dedicated pins designated as Chip Enables) and when the system clock toggles the memory's contents are briefly displayed on the Data Bus.
 
A memory can similarly be written by impressing the number to be stored onto the data bus, the memory address to be written on the address bus, unsetting or setting the write pin as the particular chip requires, and when the clock pin toggles, the memory is set to the number expressed on the data bus.
 
Because, historically, each memory location (bit) had a cost, the organisation of memory was a critical issue in the design of microprocessor systems.
 
It was almost instantly recognized that an 8-bit wide data bus offers the first useful plateau in performance versus width.
 
Hence no systems in common use do not owe a legacy to the 8-bit format for the storage of basic data, and a knowledge of how numerical data is used to represent other forms of data, such as an alphabet, is crucial to understanding how computer systems work. Binary arithmetic is fundamental to understanding this subject, because we need to know how to turn the binary numbers into the more familiar decimal numbers because those are the ones we're familiar with and we find them easier to recognize and deal with.
 
Hexadecimal is a half-way house between decimal numbers and binary numbers.
 
Binary numbers look like 00110100 01010111 10100100 11001011 00101001 00101011 10001001 10101110.
 
It's very difficult for a human to deal reliably with numbers when they're expressed like this, but the numbers 00000000 - 11111111 just mean the numbers 0 to 255. Somehow it's easier to comprehend the meaning of 121 than 01111001, but you can probably see that 79, the hexadecimal representation, is easier to deal with than the decimal when transcribing numbers by hand, which is sometimes unfortunately necessary, and was more so in the early days of computing. 
 
Hexadecimal numbers look like 34 57 A4 CB 29 2B 89 AE (these correspond to the binary numbers above).
 
Each of these pairs of hexadecimal numbers is just another way of representing the numbers in the binary string. Each 4 bits (nybbles), upper and lower, of the byte can be represented by a number between 0 and fifteen and each of the numbers between 0 and 15 can be represented either by a number or a letter. 
 
0000 - 0 - zero
0001 - 1 - one
0010 - 2 - two
0011 - 3 - three
0100 - 4 - four
0101 - 5 - five
0110 - 6 - six
0111 - 7 - seven
1000 - 8 - eight
1001 - 9 - nine
1010 - A - ten
1011 - B - eleven
1100 - C - twelve
1101 - D - thirteen
1110 - E - fourteen
1111 - F - fifteen
 
So we can take 11101010 and divide it up; 1110 1010 and look at the table and go - EA
 
Or we can take the number 11101010, put the calculator in bin mode (by clicking the 'bin' radiobutton), paste in the number, and click the hex radiobutton and get the hex value EA or click the dec button and see that the number is 234 in decimal (human) terms.
 
This is why bytes are 8 bits long, it's becaue 8 bits can easily be translated to 2 hexadecimal characters and the biggest number you can get into 8 bits is 255, which is not too big and not too small. And because 8 is a power of 2.
 
Let's just recap.
 
What we're talking about is a system for the storage, retrieval, movement and manipulation of numbers, specifically 8-bit binary numbers. These numbers range from 0 to 255 decimal, and are this size for a number of reasons, some historic, and some practical. Each number is represented by voltage levels on a port (a bunch of wires or terminals) or in a register. A port can be internal to a device or external in the case of pins. Ones (1's) are represented by 5V and zeros (0's) are represented by 0V. The bits making up a number represent decimal numbers according to their position in the byte:-
 
(128), (64), (32), (16), (8), (4), (2), (1) 
 
...and the decimal number they represent can be reconstructed by adding up the decimal numbers represented by each bit, with every bit that is zero (0) counting as zero, 0.
 
So 1010 0101 = 128+0+32+0 .... plus 0+4+0+1 = 165 or A5 Hex.
 
These numbers are frequently represented in hexadecimal form, because they are more readily understood, transcribed or typed by humans when in that form.
 
The operations of the system are controlled by a clock. A clock is a square wave generator, or frequently the square wave itself.
 
Depending on the design of the individual system, operations often occur on the rising edge of the clock (the sampling instant), although systems are sometimes clocked on the falling edge, or more rarely on both rising or falling edges of the clock. Thus a number on an input port at the instant that the clock toggles may be stored in a memory location according to the voltages present on the terminals.
 
Clocks typically operate at frequencies of 1 million transitions per second or higher. This means that we can turn any pin in a system on or off with great precision, which is how we control events in the real world, or alternatively get information into the system about the state of affairs in the real world with great accuracy and detail.
 
It is for these reasons that understanding how to manipulate binary and hexadecimal numbers with a degree of fluency is critical to designing microprocessor based systems, and that is why we deal with the subject so extensively when learning to design such systems.
 
The systems we're going to use for learning purposes are 8-bit systems because (nearly) all subsequent systems use extensions of principles first elucidated in 8-bit systems, and the simplest Microchip PICs are 8-bit systems drawing on the design legacy of preexisting 8-bit systems.
 
w
 
Dec 13, 2012 at 3:20 AM Post #10 of 30
Quote:
It's hard to be a computer user in this day and age, particularly one who is as technologically aware as somebody who builds their own audio gear is likely to be, and not be aware that binary arithmetic is out there.

There are 10 types of people in the world: those who understand binary, and those who don't.
 
Dec 13, 2012 at 3:06 PM Post #11 of 30
Good treatment of 'base' number systems Fred! As a software developer, I can't think of anything critical to add as you move into to PIC programming.
 
Dec 13, 2012 at 8:01 PM Post #12 of 30
Here's the circuit for the meter:-
 

 
...you shouldn't have any difficulty making out the detail at this scale. This is jumping ahead a bit, but I'll review a lot of the design decisions later. In the meantime you have the circuit to refer to and think about.
 
The circuit is simple.
 
Only the vaguest nod is given to signal conditioning in the form of C2, which will smooth the input a bit, but this thread is not about signal conditioning. Most any relatively steady DC voltage will readily be read by the PIC. The input DC resistance of the circuit is 10k.
 
How is the circuit intended to function?
 
The program will use the PIC's internal ADC to read the voltage on pin 17. This will produce a 10-bit (0-1023) number. The program will cause the lower 3 (decimal) digits of this number (0-999) to be shown on the display.
 
Referring to the schematic, J1 is the PIC_ISP_HDR, a 6-pin PCB header (only 5 are used, but Microchip evidently intend to use the sixth at some point in the future). This is the In System Programming interface, it enables us to program the chip without removing it from the PCB. The significant connections are GND, VDD, VPP, ICSPDAT and ICSPCLK.
 
If you look at the symbol for the 16F690, you will see that the pins are multi-purpose, and have titles like RA0/C1IN+/ICSPDAT/ULPWU. These pins can take on different functions, depending either on the program, which can configure them, or the actions of the hardware programmer (PicKit).
 
The PicKit supplies a limited amount of power to the circuit via the VDD and GND pins. This is sufficient to permit operation of simple circuits such as this one, and will light up the display without any other power supply connected.
 
When the PicKit wants to program the chip, it raises VPP to a voltage not encountered in normal usage. This causes pins 18 and 19 to shift into their ICSPCLK and ICSPDAT modes. The programmer sets ICSPDAT either high or low, (5V or 0V), and toggles ICSPCLK. When the ICSPCLK pin toggles, the value in the ICSPDAT pin is transferred into the first bit programming location. The programmer sets the ICSPDAT pin to the next value to be stored and toggles the clock. This process is repeated until the entire program has been shifted into the PIC. The exact details of this process are of little concern to us at the moment, suffice it to say that the whole process takes a minute or two at the most.
 
J3 is the sense input. The voltage to be displayed is connected to this input. It is important to observe correct polarity when connecting to this input, the circuit as designed has no capacity to correct for an inverted connection in the way that a digital multimeter can. The voltage is applied to a preset pot. which allows us to calibrate the system so that an appropriate number is displayed. The wiper of the pot is connected to pin 17 (RA2/AN2/T0CKI/INT/C1OUT). The important designator in this case is AN2, this indicates that this pin can act as an analog input to the built-in analog to digital converter (ADC). Any one of 12 pins can be connected to the internal ADC, I simply chose the lowest numbered that was not being used for another purpose. We could actually use pin 19, AN0, with some precautions, because the programmer will release this pin for other functions once the chip is programmed, but I thought it simpler for the purposes of the tutorial not to deal with the issues involved.
 
Each 7-segment display comprises 8 LEDs, 7 bars and the decimal point. These are connected via 470R resistors to the pins for RC0 thru RC7. RC means port (or register) C, which is byte-wide. Not all the ports on the 16F690 are a full byte. The resistors simply provide a little current limiting, the circuit will probably function without them. The 16F690 outputs are designed to provide (or accept, input, sink) sufficient current to operate an LED. Not all PICs have such current capacity, you must read the datasheet to find such details. The bars of the display are named (by convention) A, B, C, D, E, F, G starting at the topmost bar, A, and working round clockwise to F, with the remaining horizontal bar being G. The decimal point is called DP. Again you can identify which pin corresponds to which bar (A, B, C) by reading the datasheet for the display in question.
 
7-segment displays come in 2 types, common anode and common cathode. This indicates whether the common connection goes to the positive rail or the negative rail respectively. In the case of multiplexed displays such as these (3 digits in a package) the common terminal is called D1, D2 or D3, for each of the digits, left to right.
 
D1, D2 and D3 are connected to the positive supply via the 3 transistors, Q1, 2 and 3 respectively. This is because, although a PIC pin can source sufficient current for one display segment, up to 8 segments of any digit may be turned on simultaneously and the transistor is necessary to pass this much current without a problem. Each of the transistors can be turned on by driving RB4, RB5 or RB6 LOW.
 
So in order to turn on segment A of digit 3, pin 16 (RC0) and pin 11 (RB6) must both be driven LOW. The digits and segments are said to be ACTIVE LOW. This is a consequence of using a common-anode-type display. The display could be organised with the digits and segments ACTIVE HIGH if a common cathode display and NPN transistors were used, the circuit simply reflects what inventory I had in stock. The display is blanked (dark) when RB4,5 & 6 are HIGH OR when RC0-7 are HIGH. 
 
w
 
Dec 14, 2012 at 8:56 AM Post #14 of 30
As someone who's messed with AVR chips and Arduino boards before, and who's learning semiconductor theory but never had a "real" bottom up course on chips and logic, I'm really enjoying this. Definitely going to keep following!
 
 
Nick
 
Dec 14, 2012 at 8:31 PM Post #15 of 30
What does a microcontroller or microprocessor do?
 
A microcontroller is obviously intended to do something. But what?
 
When first switched on, a microcontroller outputs a specified address on its address bus and reads (fetches) the contents of the memory at that address. (This can be external to the device or entirely internal, depending on the exact design). The specific memory location is hardware programmed into the processor's gate logic. It could be externally set, the address could be read from an external port, hardwired by the user or designer, but it's generally built-in and it's most often address 0, which is the case in the 16F690. The processor treats the number it finds in the first memory location as an instruction, or opcode.
 
This instruction tells the processor what to do next. This may be any one of a number of things, according to a predetermined list of behaviours specified by number, for example the instruction may tell the processor to read the next memory location in sequence and move the number it contains into an internal register.
 
In order to sequence its operations, the processor maintains a counter which points to the memory location currently being read. This counter, which is again a number recorded in a register (usually 16-bit), is called the Program Counter. So typically, on switch on, the processors activity is initiated by loading the program counter with 0. The processor reads the contents of address 0, decodes the instruction stored there, increments the program counter and moves on to read the contents of address 1.
 
The processor must always move on to read another memory address, otherwise the process would stall. Frequently the next address contains a literal or pointer to a variable which the opcode specifies must be treated in a particular fashion. This object of the opcode's attention is called an operand.
 
The simplest instruction is: do nothing. Otherwise called a no-op.
 
Do nothing, that is, other than fetch the contents of the next memory location in sequence, and then do what that tells you to do. Such instructions are useful to maintain synchronization in timing-critical operations, by causing a delay.
 
These number-coded instructions (opcodes) are also collectively known as machine code. Each opcode number is loaded into a special register in the processor called the Instruction Register, causing a unique, numerically coded, chain of events to take place. This chain of events is structured into the hardware configuration in much the same way that an adder is structured to accept 2 numbers at its input ports and output their sum on their output port. This is otherwise called decoding, and the design of such hard-coded logic is beyond the scope of this tutorial. Anyone interested in learning more about this subject should study VHDL (Very-high-speed Hardware Description Language).
 
For the sake of completeness I have reprinted the block diagram of the 16F690 here:-
 

 

It is possible to program a computer by looking up the opcodes in a table and loading a memory bank with a series of numbers which represent instructions. You could do this by setting up the numbers on a data bus using switches, setting up the memory addresses on an address bus using switches and toggling a line connected to the WE (write enable) input manually, using a switch. This is often done in teaching programs, although not all memory responds well to being treated in such a halting fashion.
 
Now we need to consider types of memory.
 
Some memories lose their contents when the power is switched off. These are said to be volatile, and are frequently referred to as RAM (random access memory). This is a bit of a misnomer, because most memories other than serial memories can be accessed randomly. Non-volatile memory is often called ROM, or read-only memory, which is also an inaccurate description, since it obviously can be written to. This name came about because early-technology ROMs stored information permanently and could not readily be reprogrammed, if at all.
 
Memory technology constantly changes. Some Microchip PICs are OTP (One-Time-Programmable) devices. These are still in use, because they offer cost and permanence advantages, but the 'F' series devices have large banks of 'flash' memory which retain their programs over comparatively long times, even when the power is removed, but can still be electrically erased or reprogrammed, although programming is comparatively slow. 
 
PICs also contain a small bank of 'RAM', fast (write) memory which loses its contents when the power is removed. Flash memory is slow to write to by comparison, which is why the 'RAM' is still required.
 
Curiously, the volatile memory registers in a PIC are called 'file' memories, in contrast with PC usage, where a 'file' usually means a stream of bytes, often read from or written to a hard disk. Files in a PIC are used for the storage of variables.
 
Before leaving the subject of memory, I should perhaps mention 2 other concepts frequently used in computer systems. These are the stack and the heap.
 
The heap is commonly an area at the bottom of memory used for the storage of variables, usually global variables, or variables having more than limited scope. Scope just means where in a program a variable can be accessed. A global variable can be accessed from any part of a program, whereas local variables are only accessible from the subroutine in which they are declared. More on this later. In the case of PICs this function is served by the file memories.
 
The stack is normally an area of memory used for the temporary storage of variables at the top of memory. Stack variables are unnamed, and are stored in reverse order, the first at the highest address, the second at the next highest address, and so on. They can only be retrieved in reverse order, last first, and it is the programmer's responsibility to manage these variables appropriately. PICs also have an independent (fast RAM) hardware stack, 8 levels deep in the case of the 16F690.
 
The stack comes into its own when writing ISRs, Interrupt Service Routines.
 
w
 

Users who are viewing this thread

Back
Top