I was thinking about PIC testing, and came across the following nice trick. When you know it, it is obvious, but I haven't seen it elsewhere, and I think it deserves attention. The trick works on all 16C6x-8x, OTPs as well as reprogrammables. This trick is useful in several ways: - As a simple test program that you put into your stock of "fresh" PICs. When you need one you can quickly probe it to see if it has been used, without having to read it in a programmer. - The trick works for (partial) testing of OTP devices. It doesn't require changing the configuration fuses, and only destroys one word, which could be located anywhere in memory. The test discovers if execution logic works and may discover if part of the program memory is damaged. It executes all program memory locations. - As a test for an in-system programming circuit. * Ok, the trick is simple: TRIS PORTB anywhere in memory! Leave the rest at factory default settings. * GOOD DEVICE: RB7 will switch between HiZ and LowZ with a frequency of about F[in Hz] = f[in MHz]/m[in k word], where f is the RC oscillator frequency, and m is the program memory size. * NG DEVICE: RB7 switches much faster (at least twice F) or much slower. In other words, the maximally simple blinker program! Explanation: The test is the shortest possible PIC program the execution of which is externally detectable. PIC program memory defaults to all ones, which on the 6x-8x means ADDLW 0xFF, equivalent to W:=W-1. There is only one zero-instruction program (all ADDLW 0xFF), but the execution of this program cannot be observed. The chip could be broken but you wouldn't know. You can only see the oscillator oscillates. There are two one-instruction programs that are observable: 1. SLEEP 2. TRIS PORTx All of these will work, but TRIS PORTB is probably preferrable. The factory setting for the PIC is Watchdog timer on, with 1:128 prescaler. SLEEP means the PIC will run through the memory (ADDLW 0xFF), and then SLEEP for about 2.5 s. This will be detectable by a short blip on the CLKOUT pin. (The factory setting of the oscillator is RC.) TRIS PORTA and PORTB will work the same way, but PORTB is more useful. On startup, PORTB will contain a random value. W will also contain a random value. On every cycle through memory, W will be incremented by one (decremented by one n*2^8+255 times), and so will count from 0 to 255 and wrap around. Once every cycle, the TRIS instruction makes the PORTB pins corresponding to ones in W high impedance, and the others low impedance. This switching can be visually observed by connecting a LED and a resistor to the pin. Pin RBn will display a frequency F=f/4/m/2^(n+1), where f is the clock frequency, and m is the memory size. Eg, for a 16C84 with an RC oscillator 3.3 k/20pF, RB7 will display approx F = 5 M/4/1k/256 = 5 Hz, which is easily visible. A broken, non-ADDLW0xFF instruction which doesn't increment W will typically cause at least a doubling of F. The WDT is enabled, so there will be "hiccups" every 2.5 s. Personally, I like the TRIS PORTB version best, but the idea can be varied. For instance, TRIS PORTB + SLEEP, will make an ultra-slow blinker program, with period 5s on RB1, 10s on RB2,... about 5 min on RB6, 10 min on RB 7. (Egg timer?) -- Martin Martin Nilsson http://www.sics.se/~mn/ Swedish Institute of Computer Science E-mail: mn@sics.se Box 1263, S-164 28 Kista Fax: +46-8-751-7230 Sweden Tel: +46-8-752-1574