Here's some information to include in the FAQ. ============================================================================= For section 2.1: Australia: tel: 61 03 890 0970 France: Arizona Microchip Technology SARL 2, Rue Du Buisson aux Fraises F-91300 Massy, France tel: 33 01 6930 9090 fax: 33 01 6930 9079 Germany: Arizona Microchip Technology GMBH Alte Landstrasse 12-14 D-8012 Ottobrunn, Germany tel: 49 089 609 6072 fax: 49 089 609 1997 Hong Kong: Microchip Technology Inc. Unit No. 2520-2525 Tower 1, Metroplaza Hing Fong Road, Kwai Fong N.T., Hong Kong tel: 852 410 2716 fax: 852 418 1600 Italy: tel: 39 039 689 9939 Japan: Microchip Technology International Inc. Shinyokohama Gotoh Bldg. 8F, 3-22-4 Shinyokohama, Kohoku-Ku, Yokohama-Shi Kanagawa 222 Japan tel: 81 45/471-6166 fax: 81 45/471-6122 Korea: tel: 82 2 518 8181 Singapore: tel: 65 222 4962 Taiwan: tel: 886 2 760 2028 United Kingdom: Arizona Microchip Technology LTD. Unit 3, Meadow Bank, Furlong Road Bourne End, Bucks SL8 5AJ tel: 44 062-885-1077 fax: 44 062-885-0178 United States: Microchip Technology Inc. 2355 West Chandler Blvd. Chandler, AZ 85224-6199 tel: (602) 786-7200 fax: (602) 899-9210 ============================================================================= Other useful contacts: Parallax - makes programmers, downloaders, emulators, etc. tel: (916) 624-8333 fax: (916) 624-8003 bbs: (916) 624-7101 Advanced Trans Data - makes programmers, emulators, etc. tel: (214) 980-2960 fax: (214) 980-2937 Micro Engineering Labs - makes PIC-Proto boards tel: (719) 520-5323 Myriad Development - C compiler tel: (303) 692-3836 CCS - C compiler tel: (414) 781-2794 extension 30 Needham Electronics - I don't think they make PIC stuff, but they make a great inexpensive EPROM programmer, the PB-10 tel: (916) 924-8037 fax: (916) 972-9960 bbs: (916) 972-8042 ============================================================================= For section 2.2: PIC processors are available in three families, which Microchip refers to as the PIC16C5x, PIC16Cxx, and PIC17Cxx families. PIC16C5x: 12 bit program word size, 33 instructions, 2 level stack, no interrupts Program Data Max. Voltage Typical Digikey memory memory I/O freq. Range Current Price (words) (bytes) pins (MHz) (Volts) (mA) (US $) ---------- --------- --------- ----- ----- -------- ------- ------- PIC16C54 512 25 12 20 2.5-6.25 2 4.39 PIC16C54A 512 25 12 20 2.5-6.25 2 PIC16CR54 512 ROM 25 12 20 2.0-6.25 1 PIC16CR54A 512 ROM 25 12 20 2.0-6.25 1 PIC16C55 512 24 20 20 2.5-6.25 2 5.44 PIC16C56 1024 25 12 20 2.5-6.25 2 5.03 PIC16C57 2048 72 20 20 2.5-6.25 2 6.24 PIC16CR57A 2048 ROM 72 20 20 2.0-6.25 1 PIC16C58A 2048 73 12 20 2.5-6.25 1 PIC16Cxx: 14 bit word size, 35 instructions, 8 level stack Program Data Max. Voltage Typical Digikey memory memory I/O freq. Range Current Price (words) (bytes) pins (MHz) (Volts) (mA) (US $) ---------- --------- --------- ----- ----- -------- ------- ------- PIC16C64 2048 128 33 20 2.0-6.0 3 11.05 PIC16C71 1024 36 13 16 3.0-6.0 2 14.38 PIC16C74 4096 192 PIC16C84 1024 EE 36 + 64 EE 13 10 2.0-6.0 2 10.15 PIC17Cxx: 16 bit word size, 55 instructions, 16 level stack: Program Data Max. Voltage Typical Digikey memory memory I/O freq. Range Current Price (words) (bytes) pins (MHz) (Volts) (mA) (US $) ---------- --------- --------- ----- ----- -------- ------- ------- PIC17C42 2048 256 33 25 4.5-5.5 6 15,15 PIC17C44 8192 480 33 25 Notes: 1. Program memory is EPROM unless otherwise noted. 2. Data memory is number of usable bytes, not including special function registers. 3. Digikey prices are quantity 10 prices for 4 MHz DIP packaged OTP parts with RC oscillator option (where applicable), except that the 16C84 uses EEPROM program memory, and the slowest speed 17C42 is rated at 16 MHz. Prices are from Digikey catalog number 943 for May/June 1994. Other distributors often have lower prices, but typically also have high minimum order requirements. Digikey also usually has plenty of parts in stock. Windowed EPROM parts cost substantially more. ============================================================================= Notes for programmers: All PIC instructions are a single word. The equivalent of the immediate address mode of other processors is the literal mode, used by instructions ending in "LW", such as MOVLW, ADDLW, SUBLW, ANDLW, IORLW, XORLW, and RETLW. The byte of data used by these instructions is directly encoded in the instruction itself. All PIC instructions take a single instruction cycle (four oscillator cycles) to execute, except instructions which can cause a change of flow or have PCL as their destination, which take two instruction cycles. The Microchip documentation is misleading in that they claim that two cycles are taken only if the PC changes. Actually any instruction which potentially could change the PC takes two cycles. For example: movlw 37 goto next next: movwf porta The goto instruction takes two cycles even though the PC doesn't change. This is useful as a two-cycle NOP, and is often written as "goto .+1" to avoid the need for a label. The W register is equivalent to the accumulator on other processors. Almost all data movement, arithmetic, and logic operations use W. Instructions that operate on W and a register (i.e., instructions ending in "WF", like ADDWF and MOVWF) allow the result to be placed in either W or the register (but not both). This is specified by a ",W" or ",F" after the operand. The default is ",F", which will place the result in the register. This can cause a lot of confusion if you're not careful, so I recommend always specifying the destination explicitly. An example of a confusing instruction: incf foo,w ; w := foo+1 note that foo is unchanged! If you want the result in both W and the register, you can use either: incf foo,w mowwf foo or: incf foo,f movf foo,w The stack is not accessible to the programmer in any way other than the call and return instructions. There is no way to push or pull data, or even to examine the stack pointer. On the 16C5x family the stack has only two levels, so it is frequently necessary to write code in a different style than would be used on a typical processor; you can only call subroutines from your main code, or from a subroutine called from main, but no deeper. The 16C5x family doesn't have a normal return instruction; instead it has RETLW, which stands for RETurn Literal Word. RETLW loads an eight bit constant into W (just as a MOVLW instruction would), then returns from the subroutine. This can be useful, but is agravating if you want to return a computed value. On the newer PIC families there is a normal RETURN instruction. With the exception of the 17Cxx family, there is no way for software to read an arbitrary location of program memory. In order to implement lookup tables, it is necessary to combine the use of the ADDWF and RETLW instructions. For example, the following code implements a lookup table of the first four odd prime numbers: primes: addwf pcl retlw 3 retlw 5 retlw 7 retlw 11 To use the table, load the appropriate index (in this case, 0 to 3) into W, and "call primes". The addwf instruction adds the contents of W to the PC, which has already been incremented to point to the "retlw 3". The table will return with the value in W. The total time taken is 6 instruction cycles, or 24 oscillator cycles. Note that while on most processors the use of an out-of-range index will result in the use of incorrect data, but the program execution will continue normally, on the PIC a bad index value will cause the execution of arbitrary instructions! Normally the index would range from 0 to the size of the table minus one, but it is possible to use other ranges by putting the retlw instructions somewhere other than immediately following the "addwf pcl". It is also possible to implement tables using a "subwf pcl", or perhaps other instructions with pcl as the destination. The subtract instructions (SUBWF and SUBLW) work differently than most people expect. SUBWF subracts W *from* the contents of the register, and SUBLW subtracts W *from* the literal. (SUBLW is not available on the 16C5x family.) If you want to subtract a literal from W, it is easiest to use the ADDLW instruction with the two's complement of the literal. For example: addlw 0feh ; w := w - 2 Some assemblers allow this to be written as: addlw -2 There is no instruction to take the two's complement of W (like the NEG instruction on Motorola processors), but because of the way the subract instructions work you can use: sublw 0 On the 16C5x family, the CALL instruction can only address the first 256 words of a bank of program memory. It is common practice to use "call extenders", which are simply GOTO instructions in the first 256 words with a target in the last 256 words. On the 16C57 and 16C58, if you plan to use indirect addressing (via the FSR and IND registers), it is vitally important that your reset code clear FSR before using any other RAM locations. Otherwise you may start up in an arbitrary bank, and as soon as you change FSR all your carefully set up variables will effectively disappear. ============================================================================= Useful code fragments: It is very useful during debugging to hook up a piezo beeper to a port pin, and beep it after initialization and at other strategic times. Here's some useful code from Rich Ottosen (the delay function is not needed but is thrown in as a bonus): ;delay for w *1ms at 4mhz osc. freq. delay movwf mscnt ;count milliseconds dly10 movlw 250 movwf dlycnt dly20 decf dlycnt ; 1 cycle btfss status,zero ; 1 goto dly20 ; 2 =4 cycles decf mscnt ;last msec? btfss status,zero goto dly10 retlw 0 ;return nothing ;make a "bell" sound beep: movlw 200 movwf cycles bp10: movlw 83 ; a nice tone??? movwf period call click decfsz cycles goto bp10 retlw 0 ; return nothing ;make a "click" sound. (used for button pushes) ; frequency = 1 /(1 /(osc frequency /4) *5 cycles *period *2) click: bsf porta,pzt ;click high movf period,w ;time for one half of cycle movwf dlycnt ; into delay counter clk10: nop ; 1 cycle nop ; 1 decfsz dlycnt ; 1 goto clk10 ; 2= 5 cycles bcf porta,pzt ;click low movf period,w ;time for one half of cycle movwf dlycnt ; into delay counter clk20 nop ; 1 cycle nop ; 1 decfsz dlycnt ; 1 goto clk20 ; 2= 5 cycles retlw 0 ;return nothing =============================================================================