Program Space to Sleep
The '508A has 511 address locations for program or data. These locations are 12 bits wide and each line of code takes up one address location.
To access one byte of data, it must be added to the instruction RETLW and placed in a table. Because of this requirement, one byte of data also occupies one address location. The byte of data contains 8 bits. See Program Layout.
To make programming easy, we have made a Program Template. It contains a layout for a program that you "add to" when creating a program. Before using Program Template, (PTplate1), copy it as PTplate2 etc so that PTplate is not destroyed. See Equates for more details.
PSEUDO'508A is the name given to a mini PC board carrying a PIC16F84 chip that can be programmed like a PIC12C508A microcontroller. The board has an 8 pins plug on a flying lead that can be plugged into an 8-pin socket on a development module such as '508A
Proto-1 Module or '508A Express-1 Module. It has an on-board 4MHz crystal. See
'508A Proto-1at end of chapter.
A resistor connected between an in/out pin and 0v (ground). The resistor produces a default (0) on the pin when the pin is read as an input.
A resistor connected between an in/out pin and 5v. The resistor produces a default HIGH (1) on the pin when the pin is read as an input.
Pulse-Width-Modulation can be used to vary the speed of a motor or dim a lamp without overheating the driver transistor. When a transistor is switched on fully or completely off, it dissipates very little
energy and thus it does not heat up very much. If a transistor is half-turned-on, it dissipates approx the same amount of energy as the load it is driving. If a transistor is turned on fully for a very short period of time then switched off for a long period time, the average energy delivered to the load will be small but the transistor will not heat up. If the duty-cycle is adjusted to say 50:50, the energy delivered will be half the fully turned on amount but the transistor will still remain cold. This is the principle of PWM.
PRODUCING AN ANALOGUE SIGNAL using PWM
PWM can also be passed through a resistor and capacitor network as shown in the diagram to produce an analogue voltage from a digital output.
There are two ways of delivering a PWM signal. The micro can spend all its time delivering a HIGH then a LOW or it can deliver a HIGH then go away and do other things then return and deliver a LOW. This is multi-tasking and allows the program to respond to a signal from a button to tell when to cease outputting etc.
RAM - Random Access Memory
The '508A does not have any RAM however any unused files can be used to store information. Files used as RAM should be consecutive. For instance files 07 to 15h could be used for RAM and files 16h to 1F used for programming. This gives fifteen files for RAM and they can be accessed via the INDF and FSR registers as shown below.
In setUp, put the start of the files for use as RAM into FSR via W.
SetUp MOVLW 07h
;Put start of files into W
MOVWF 04,1 ;07h into FSR - pointer
As each new piece of data is received from input lines GP0, GP1, GP2, GP3, GP4, and GP5 it is placed in the next available file.
MOVWF 00 ;Put W into what FSR sees
To read files 07 to 15h, use SetUp above to put 07h into FSR and call the following routine:
MOVF 00,0 ;Put what FSR sees into W
The first pass of the routine will put the value in file 07h into W. Remember, input GP0 to GP5 is only 6 lines (6-bits) and will produce values from 00 to 3F (00 to sixty-three). The second pass will put the value in 08h into W etc.
Computers find it very difficult to produce random numbers. Some of the ways to produce a random number are:
1. Increment a file during the execution of a routine where a button is pressed. This introduces a human factor and when the button is pressed, the file is read.
This produces a number from 0 to 256 (00 to FF). The file can be ANDed with 0F to produce a number from 0 to fifteen or with 07 etc to limit the number of possibilities. These values can then be used for a "look-up" table for a display etc.
If zero is not required, a table can be used or the following instructions will increment random file 1F, if it is zero:
2. Create a table of any length and increment down the table. At the end of the table the "jump file" starts at the beginning again.
3. Use a Random Number generator routine.
RanNum SWAPF 1C,0
;swap nibbles. Put in W
ANDLW 0F0h ;AND 1C with F0
ADDWF 1C,1 ;ADD W and 1C
MOVLW 0A3h ;Put A3 into W
;ADD W and 1C
File 1C is used to store the random number. It can start with zero and will contain 255 different values.
There is no PIC instruction to read a value of data at an address.
Data has to be put in a table and each byte needs a RETLW instruction.
For details on producing a table: see Relative addressing, Table, Write.
READ AN INPUT - see also INPUT
To read all the input lines at once:
This puts GP0 to GP5 into W (only 6 bits of information).
To read an input line (called an input bit - say GP3:
If GP3 is HIGH, the program will skip the GOTO 1 instruction and carry out the GOTO 2 instruction.
To read 2 lines at the same time:
To see if say GP0, GP3 are BOTH high:
MOVLW 09 ;0000 1001
BTFSS 03,2 ;Test Z flag
If both lines HIGH = Match, program will skip GOTO 1 and execute GOTO 2.
READ A PORT
- See also INPUT
To read a Port (an input) the bit (the line - such as GP3) must be set as an input bit (line). Put the following 2 instructions in SetUp:
To make GP3 input (for '508A):
MOVLW 08 ;0000 1000
TRIS 06 ;Make GP3 input
To make GP3 input (for Pseudo '508):
MOVLW 08 ;Make GP3 input
MOVWF 06,1 ;Load TRISB file
To read GP3:
The above instruction "reads" or tests bit 3 of the input port and skips the next instruction if it is clear.
The '508A chip is a one-time programmable device however there are ways to use the unused portion of the PROGRAM SPACE.
1. Read the chip and count the number of bytes in the program. Add this number of NOP's to the front of your new program and re-burn the chip. The program will be part-way down the program-space but
this will not affect the running.
If a table is included in the program, make sure the table does not go over the first-page boundary (0FFh) when the chip is re-burnt.
If an instruction in a sub-routine needs to be changed, place the sub-routine at the end of the program and ACCURATELY replace each instruction of the sub-routine with a NOP.
2. You can "NOP out" an instruction or data value (such as RETLW 07h), provided the instruction or value does not affect the operation of the program.
3. You can "burn down" any location to a lower value providing the bit(s) are being changed from "1" to "0."
For example 0F (0000 1111) can be burnt down to any lower value but 08 (0000 1000) can only be burnt down to 00.
Some microcontrollers have a feature where registers (files) can be combined so that you can increment the lower file and when it reaches FF, the higher file is automatically incremented. In this way numbers up to FF x FF = 65,536 can be counted. This feature can be created in six program steps:
Pair CLRF 0C
;Clear file 0C
;Clear file 0D
Pair1 INCFSZ 0C,1 ;Inc file 0C, Skip if zero
;Inc the low file
;Inc the high file
65,536 loops to here.
If data is placed in a table and accessed by a RETLW instruction, it is called Relative Addressing.
The table must be in the first 00 to FF locations as the routine for Relative Addressing only allows the Program Counter to be increased (via an ADD instruction) from 00 to FF.
To access data in a table, load W with the number of locations you want the program counter to jump down the table. In other words the "Offset" value. Then CALL Table1.
Table1 will have an instruction to ADD the Offset value to the Program Counter and cause the micro to jump down the table. Each location will have the instruction RETLW, then a byte of data. The W register will return to the sub-routine with the data byte in W.
The Table routine is as follows:
MOVLW 04 ;Load 4 into W
MOVWF 0C ;3C will be loaded into file 0C
Table1 ADDWF 02,1
;Add W to Program Counter
RETLW is a double-feature instruction. It is a return instruction that carries a value (a literal) in W back to the originating routine.
The '508A does not have an instruction or a pin on the chip that performs a
reset operation. When power is first applied to the chip it waits a short period
of time and begins to execute the program from the first address in memory.
Thus, by turning the power OFF and ON, the chip will perform a simple RESET
operation. If you think your program may "crash" or "freeze
up" you can include the WATCHDOG TIMER feature. When this feature is
activated, the micro will go to the first address in the program if the watchdog
is not reset every few hundred milliseconds. This is done by clearing the
Watchdog Timer (WDT) by using the instructions: CLRWDT on a regular basis. By
including this instruction at one or more points in a program, your project will
run smoothly. If it "runs off the end of the program" or freezes up,
the watchdog timer will cause a RESET.
The PIC16F84 has a "HARD RESET" as well as the watchdog feature
described above. By adding a push button to pin 4, as shown in the diagram
below, the chip will reset when the button is pressed.
The '508A instruction-set does not have RETURN. This does not matter as most assemblers interpret RETURN as RETLW and you have the added feature of having the value in W available for use in the routine being returned to.
You should get into the habit of using RETLW at the end of each called sub-routine.
A RETURN (RETLW) statement must be placed at the end of a sub-routine that has been CALLed.
Remember: Only two embedded CALLs are available with the '508A as the stack is only "2-high." Two embedded calls are as follows:
The Main routine makes a CALL to a sub-routine. While executing this sub-routine (say sub-routine1), you can make a CALL to another sub-routine (say sub-routine2).
At the end of sub-routine2 the RETLW statement takes you back to sub-routine1. The RETLW statement at the end of sub-routine1 takes the program back to Main. You can then make further CALLs.
You can also have a RETLW at the end of GOTO sub-routine. Here's what happens:
The Main routine makes a CALL to a sub-routine. While executing this sub-routine (say sub-routine1), you have a GOTO sub-routine2.
At the end of sub-routine2 the RETLW statement takes you back to Main.
Reverse will work on any of the 5 I/O lines (GP3 is input ONLY). It reverses the direction of the data.
For example: If GP0 is an input, REVERSE makes it an output. If it's an output, REVERSE makes it an input. You do not have to know the condition of the line before REVERSE - it simply reverses the state.
RevGP0 Reverses output GP0 and makes it input, or if GP0 is an input RevGP0 makes it an output.
Since TRIS register is a "Write-only" register, its condition has to be backed up by a file that can be tested. We use file 1D for long-term storage. In set-up, prepare GP0 as an output by making 1D
= 00. When GP0 is CALLed, file 1D is placed in W register and XORed with 01. The 00 will change to 01. The next time file 1D is XORed with 01, its value of 01 will change to 00.
In SetUp, prepare GP0 as an output by making file 1D 00.
SetUp CLRF 1D
;Clear file 1D
CALL RevGP0 ;GP0 will become input
your own code
your own code
CALL RevGP0 ;GP0 will become output
Before Main, include the sub-routine:
RevGP0 MOVF 1D,0
;Put 0000 0000 in W
XORLW 01 ;XOR W with 01
MOVWF 1D ;Put 01 into file 1D
TRIS 06 ;Put 01 into TRIS register
If you want GP1 to REVERSE:
RevGP1 MOVF 1D,0
;Put 0000 0000 in W
XORLW 02 ;XOR W with 02
MOVWF 1D ;Put 02 into file 1D
TRIS 06 ;Put 02 into TRIS register
If you want GP2 to REVERSE:
RevGP2 MOVF 1D,0
;Put 0000 0000 in W
XORLW 04 ;XOR W with 04
MOVWF 1D ;Put 04 into file 1D
TRIS 06 ;Put 04 into TRIS register
If you want GP4 to REVERSE:
RevGP4 MOVF 1D,0
;Put 0000 0000 in W
XORLW 08 ;XOR W with 08
MOVWF 1D ;Put 08 into file 1D
TRIS 06 ;Put 08 into TRIS register
ROTATION See Shifting
Also called Secret entry code.
To prevent unauthorised altering of timer values or any alterable data, a simple entry code can be added to the program.
To access the secret code, the chip is turned off and button 0 is pressed while the chip is turned on. The LED will flash 4 times to indicate the program is in Secret Code mode. By entering the code
7, 8, 9, 0, (or any code you wish to write into the program), you will be able to change the timer settings. See the Secret Code program in the Programs section.
A bit is SET when it is changed to a "1."
Set up a port for '508A:
SetUp MOVLW 08
;Load W with 0000 1000
TRIS 06 ;Load W into TRIS register
CLRF 06 ;Removes junk in file
Set up a port for Pseudo '508A:
SetUp BSF 03,5
MOVLW 08 ;GP3 input
MOVWF 06,1 ;Load TRISB file
BCF 03,5 ;Select Page0
CLRF 06 ;Removes junk in file
SHIFTING - Also called ROTATING
Shifting (or ROTATING) the bits in a file allows you to do three things:
1. Shifting LEFT doubles the value of the contents. The maximum value that can be doubled is 0111 1111 = 7F as the next shift will produce 1111 1111 = FF.
Before shifting, the carry bit must be CLEARed. This is done by the following instruction:
BCF 03,0 ;CLEAR the carry bit
2. Shifting RIGHT halves the value of the file. The minimum value that can be halved is 0000 0001 as the next shift right produces 0000 0000.
Before shifting, the carry bit must be CLEARed as shown above.
3. Shifting can be done to test a particular bit. By shifting and testing say bit 0, all the 8 bits in a file can be tested in a loop routine, if RRF instruction is executed.
In a shift (ROTATE) operation, the end bit goes into the carry and makes the carry flag either SET or CLEAR, depending on the value of the bit. 0 = CLEAR, 1 = SET.
The carry flag is located in the status register and the state of the carry flag from a previous operation will move into the opposite end of the file being rotated. The carry flag can be tested by including
the following instruction in the program:
;Test the carry flag. skip if SET.
or BTFSC 03,0
;Skip if CLEAR
Do not to use the file being rotated for its numerical value as it may be corrupted by the carry bit. To remove the carry bit, rotate the file 9 times and it will return to its original value!
To provide a current path to ground. An output line on a '508A will SINK a current (approx 25mA) when it is LOW (0v). Any device connected between the line and 5v will be turned on when the line is an OUTPUT and is LOW.
The '508A chip consumes approx 2mA while operating with its internal 4MHz RC oscillator. When powered-down the oscillator is turned off and the consumption falls to approx 1uA.
To power down, the SLEEP instruction must be included in the program. To wake the micro from SLEEP, change the state of GP3. This line must be an input before SLEEP is executed. For the lowest current consumption while in SLEEP mode, GP3 should be at a logic HIGH level, before and
during SLEEP. A change to LOW will wake the device from SLEEP.
Before entering SLEEP, any of the pins that are assigned as inputs, must be read. This action sets bits within the micro. When in SLEEP, wake up occurs when any input pin changes from the state they were at the last reading.
In addition, Bit7 in the OPTION register must be made "0" to enable the wake-up on pin change feature.
In summary, these are the three instructions:
BCF OPTION,7 ;Enable GPWU