The program is presented on the next page. It is very complex and needs a lot of explaining. That’s the the purpose of this project. It’s to teach programming.
Up to now our programming has been very simple; consisting of sub-routines, followed by a Main routine. We call it “linear programming” as you can look down the program and see what the micro is doing. We now come to a completely different approach.
A microcontroller can only do one thing at a time. It can only be in one place in the program and although it can execute one million instructions per second (for this particular microcontroller), a project such as the 2-Input Alarm needs a number of things done at the same time.
For instance, the output devices need to be turned on and off at different times, with some of the times overlapping.
To do this the micro needs to be organizing a number of things at the same time and each is given a time-duration in the form of a value in a file.
These files are then placed in the program, (one after each other) and accessed by the micro and decremented each time it goes through this part of the program. When a file becomes zero, an action is performed.
But this decrementing cannot be done if the micro is concentrating on the main program, looking for the press of a push-button or the trigger of a detector etc.
So we have to devise a way to get the microcontroller to do two things at the same time.
This is done by a concept called INTERRUPT. The micro is interrupted while executing the main program and is taken to the Interrupt Routine, then returns.
The microcontroller has a number of “counters” or “timers” that consist of 8-bit files or registers and can be incremented. These can be used to perform this requirement.
The main oscillator is connected to a counter called the Program Counter (PC). This counter causes the microcontroller to advance down the program, “read” each instruction and carry out each instruction. At the same time, the timers can be programmed to increment.
When combined with a feature called Global Interrupt Enable we can get the timer to interrupt the micro and make it go to a particular location - called the Interrupt Vector location (address 04).
To get the micro to do this we add instructions to the program and every time the timer “ticks-over” from FF to 00, the micro stops the current instruction and goes to address 04. The timer is called “Timer0” and at address 04, the microcontroller executes the “goto” instruction placed at this location. We call our “goto” routine, the ISR (Interrupt Service Routine) (you can give it any name). This routine can be considered a “secret” or “hidden” routine as it is not obvious how it is accessed. There are no “calls” or “jumps” to this part of the program.
In our program we have added a pre-scaler to the front of timer0 to divide the incoming clock-line by 8. It can be configured to divide by 2 or any value up to 32. In our case we have selected a divide-by-8 by setting bit 2 of the counter.
We now have the situation where the micro carries out 256x8 = 2048 instructions of the main program then goes to address 04 and performs the Interrupt Service Routine then comes back to the main program and carries out another 256x8 instructions.
When the micro is carrying out the Interrupt Service Routine instructions, it is not called back to address 04 - luckily! At the end of the Interrupt Service Routine it finds an instruction RETFIE (Return From Interrupt) and goes back to the main program.
This type of programming introduces lots of complications. Especially timing, as time-intervals will change if the Interrupt Service Routine is increased in length. This can be overcome by fine-tuning at the completion of writing the program.
The instructions that create the Interrupt Service are shown below:
ORG 0 GOTO Main NOP NOP ORG 4 GOTO isr isr instructions go here etc etc isr_0 instructions go here etc isr_1 instructions go here etc RETFIE Main instructions go here BSF STATUS, RP0 ;select bank 1 (the special registers area) MOVLW b'00000100' ;set bit 2 MOVWF Option_Reg ^ 0x080 ;load prescaler to create a divide by 8. BCF STATUS, RP0 ;select bank 0 (the program area) CLRF TMR0 ;clear Timer0 register MOVLW 0xA0 ;set GIE <7> and T0IE <5> (see below) MOVWF INTCON ;enable Interrupts instructions go here GOTO Main 0xA0 = 1010 0000 GIE = Global Interrupt Enable T0IE = Timer Zero Interrupt Enable
If you don’t know the reason for selecting Bank 0 and Bank 1, or any of the other instructions, you will need to go to one of our PIC projects - such as PIC LAB-1.
We are only dealing with advancements and improvements over our older-style “linear-mode” programming.
The next thing you will notice is a name has been given to each file. This may be its “computer name” or one generated by the developer of the program.
Since all microcontrollers have an abundance of files, it is possible to use a new file for each sub-routine. In older style microprocessors, the lack of files meant you had to reuse files and had to remember if a file was available for re-use. This has now changed. Files are in abundance.
Assign a short name to each file to allow you to remember its function. At the beginning of the program, tell the assembler the name you have used by creating an identity called an ”equate” (equ). This means “equal to” or “applies to.”
When assembling the program, MPASM will need to find P16F628.inc
file. Place it in the same folder as the file you are assembling. If the assembler does not detect the P16F628.inc
file, you will need to put all the relevant equates into your .asm file. This has been done in 2-InputAlarm.asm in 2 Input Alarm so you will be able to assemble it immediately in MPASM.
Make sure the programmer you are using will burn PIC16F628 chips.
Refer to Multi Chip Programmer article for a suitable programmer.
A delay is created by adding a sub-routine to the isr
section of the program. Use one or two files and load them with 80h (the maximum value is 0FFh). The actual delay-time can be trimmed after the program has been written.
Each decrement is approximately equal to 2048mS plus the number of instructions in the isr section, with the answer in microseconds.
The entry delay was the last modification to the program and is not executed in the isr section. It consists of 48 flashes and “beep-beep” from the entry/exit piezo - creating a delay of approx 45 seconds. File 4Dh is loaded with 30h to create the delay at Alrm_z
.
At the completion of 48 flashes, the program executes a 2 second delay via isr. To execute a delay in the main part of the program, interrupts are turned off.
Alrm_z CLRF 4Eh ;clear "button-pressed" flag file MOVLW 0x00 MOVWF INTCON ;turn off interrupts MOVLW 30h ;48 beeps/flashes for entry MOVWF 4Dh BCF 06,1 ;clear orange LED Entry BSF 06,0 ;turn on red LED BSF 06,4 ;turn on beeper CALL Del2 ;short delay BCF 06,4 ;turn off beeper CALL Del2 ;short delay BSF 06,4 ;turn on beeper CALL Del2 ;short delay BCF 06,4 ;turn off beeper CALL Del1 ;call long delay BCF 06,0 CALL Del1 BTFSS 4Eh,0 ;test button-detect flag GOTO Entry1 BCF 4Eh,0 ;clear button-detect flag in delay routine GOTO Entry2 Entry1 DECFSZ 4Dh,1 GOTO Entry Entry2 MOVLW 0x0A0 MOVWF INTCON ;turn on interrupts MOVLW 0x0FF ;Set delay time for two extra seconds MOVWF tmr_Delay1 MOVLW 0x02 MOVWF tmr_Delay2
The exit delay was also a last-minute inclusion in the program and consists of 48 flashes and “beep” from the entry/exit piezo - creating a delay of approx 45 seconds. File 4Dh is loaded with 30h to create the delay at Exit.
MOVLW 30h ;number of beeps/flashes MOVWF 4Dh ;storage file for decrementing Exit BSF 06,2 ;turn on green LED BSF 06,4 ;turn on beeper CALL Del2 ;short delay BCF 06,4 ;turn off beeper CALL Del1 ;call long delay
Any changes to the program must be done in very small steps.
This is done in Notepad++ or VS Code. Always save with a new name, such as Alarm-A.asm, Alarm-B.asm etc.
Go to MPASM and change -A, -B in the top window and click: assemble. Make sure you have selected: 16F628 as the processor, TAB size “8,” Default Radix, Warning Level: Default, Hex output: Default, Generated Files: Error File and List File.
MPASM will only generate a .hex file when no errors are present.
Test the operation of the circuit fully before making any more changes and save each modification with the new name in case you need to back-track.
One of the values you may want to change is the duration of the siren. It is only short in the program as its “on-time” will depend on your local laws. Some laws limit it to 5 or 10 minutes.
We have found the best arrangement is to put a piezo tweeter inside the house. The noise it produces will send the invader away as he will not be able to hear if anyone is nearby. It’s better than putting a wailing siren outside.
Download 2-InputAlarm.asm file and open it in Notepad++ or VS Code.
The program is very complex and uses an interrupt feature that interrupts the Main routine every 2048 microseconds.
This feature is activated by setting the Global Interrupt bit in the INTCON file. The duration between each interrupt is determined by the value of the pre-scaler, multiplied by 256 (for TMR0).
TMR0 is a timer that increments on every instruction-cycle and “ticks-over” from FF to 00 after 256 cycles.
Quick Links
Legal Stuff
Social Media