+
-Tim's picmicro page
Back Home
Welcome to my Pic Micro Projects Page!
Under construction
Back Home
; alarmt.asm
__CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT
GPIO equ 6
STATUS equ 3
PC equ 2
#define CARRY STATUS,0
#define ZERO STATUS,2
#define outa GPIO,0 ;Output to Piezo - toggles with GPIO,5
#define modea GPIO,1 ;Input A0 determines 1 of 4 sounds: 00, 01, 10, 11
#define modeb GPIO,2 ;Input A1 determines 1 of 4 sounds: 00, 01, 10, 11
#define enbf GPIO,3 ;tied LOW
#define enbt GPIO,4 ;HIGH input enables the chip to produce sounds
#define outb GPIO,5 ;Output to Piezo - toggles with GPIO,0
;Files for temporary storage:
bits equ 0Ah ;flags file
temp equ 0Bh ;temporary storage
dwell equ 0Ch ;cycles
count equ 0Dh ;delay
steps equ 0Eh ;dwell
cnth equ 0Fh ;counter HIGH
cntl equ 10h ;counter LOW
#define flag bits,1 ;flags file, bit 1 = 0Ah,1
#define wabl_dir bits,2 ;flags file, bit 2 = 0Ah,2
#define wabl_dir_mask bits,4 ;flags file, bit 4 = 0Ah,4
;*************************************
;Program starts HERE
;*************************************
esetvec org 0
movlw 0D0h ;1101 0000
movwf option_reg ;Weak pull-up and Pin-change disabled
;Option is normally 1111 1111 - so 0D0h has no effect
movlw 1Eh ;0001 1110
movwf GPIO ;Make GP 0 and 5 LOW for piezo
movwf trisio ;Make GP4 input
top1
bcf wabl_dir ;clear flags bit 2
bcf flag ;clear bit 1 in flags file
top
btfss enbt ;test GPIO,4 - Chips is enabled when HIGH
goto top1 ;micro goes here when enable low - loops 4 instructions above
nop ;micro goes here when enable HIGH - then to rrf below!!
btfsc enbf ;Tied LOW!! - will always be "clear" - LOW
goto top1 ;micro can never go HERE.
;micro always goes here
;The following creates a miniature Table:
rrf GPIO,w ;GPIO will have 0000 0xx0 via A0 and A1
andlw 3 ;after rrf the result will be: 0000 00xx
addwf PC,1 ;masks all but the two lowest bits and adds to Program Counter
goto mode0 ;jumps here if A0 and A1 LOW
goto mode1 ;jumps here if A0 HIGH and A1 LOW
goto mode2 ;jumps here if A0 LOW and A1 HIGH
goto mode3 ;jumps here if A0 and A1 HIGH
mode3 ;mode 3 SIREN
i1 movlw 37 ;set frequency delay
movwf count
movlw 6 ; set number of frequency steps
movwf steps
i2
movlw 0x20 ; 0010 0000 set frequency dwell delay 64d
movwf dwell
alarm1 ; send 1 cycle
call alarm1_set
movlw 1Fh ;0001 1111
movwf GPIO ;Makes GP0 HIGH GP5 LOW
call alarm1_clr
out1
decfsz dwell,1 ; test if any more cycles
goto alarm1
movlw 5 ; step frequency delay
subwf count,1
decfsz steps,1 ; test if last step in progress
goto i2 ;
goto top ;see if Enable is still HIGH and loop again
;Enable must go LOW to stop alarm
mode0 ;init mode 0 CONSTANT
movlw 35 ; set frequency delay
movwf count
call alarm1_set ; send 1 cycle
movlw 1Fh ; 0001 1111
movwf GPIO ;Makes GP0 HIGH - GP5 LOW
call alarm1_clr
nop
goto top ;see if Enable is still HIGH and loop again
;Enable must go LOW to stop alarm
;
mode1 ;init mode 1 CHIRP
bcf flag ;clear bit1 in bits file - flags file
movlw 35 ; set frequency delay
movwf count ;put 35 into Count file
movlw 1 ;
movwf cnth ;put 1 in counter HIGH file
clrf cntl ;clear counter LOW file
mode1a
call alarm1_set ; set 1st pulse
movlw 1Fh ; 0001 1111
movwf GPIO ;Makes GP0 HIGH - GP5 LOW
call alarm1_clr
decfsz cntl,1 ; decrement and test counters
goto mode1a
decfsz cnth,1
goto mode1a
movlw 2 ; set pause delay to counters
movwf cnth ; pause = ~6*cnth*~255us
clrf cntl
mode1b
nop
nop
nop
decfsz cntl,1 ; decrement and test counters
goto mode1b
decfsz cnth,1
goto mode1b
movlw 1 ;init second pulsed delay to counters
movwf cnth
clrf cntl
mode1c ; send 1 cycle
call alarm1_set
movlw 1Fh ; 0001 1111
movwf GPIO ;Makes GP0 HIGH - GP5 LOW
call alarm1_clr
decfsz cntl,1 ; decrement and test counters
goto mode1c
decfsz cnth,1
goto mode1c
goto top ;see if Enable is still HIGH and loop again
;Enable must go LOW to stop alarm
mode2 ;init mode 2 WARBLE
btfsc flag ; test control flag
goto mode2fa
movlw 0x19 ; init frequency delay
movwf count
mode2e
movlw 8 ; init number of frequency steps
movwf steps
mode2b
movlw 5 ; init frequency dwell
movwf dwell
mode2a
decf dwell,1 ; test if dwell = 0
btfsc ZERO
goto mode2d
call alarm1_set ;set 1 cycle
movlw 1Fh
movwf GPIO
call alarm1_clr
goto mode2a
mode2d
decf steps,1 ; test if more steps
btfsc ZERO
goto mode2f
btfss wabl_dir ; test warble direction
goto mode2g
movlw 5
subwf count,1 ; increment frequency
goto mode2b
mode2g
movlw 5 ; decrement frequency
addwf count,1
goto mode2b
mode2f
bsf flag ; set control flag
goto top ;see if Enable is still HIGH and loop again
;Enable must go LOW to stop alarm
mode2fa
movlw wabl_dir_mask ; change direction
xorwf bits,1
movlw 7 ; reload number of frequency steps
movwf steps
goto mode2b
alarm1_set ; set 1 cycle sub-service
movlw 3Eh ; 0011 1110 Make GP0 LOW - GP5 HIGH
movwf GPIO ;toggles GP0 and 5
alarm1_clr ; copy and decrement frequency delay
movfw count ;set for *4 to define pulse frequency
movwf temp
Dec2 ; 14+2*(4*temp*~1us)= frequency
nop
decfsz temp,1
goto Dec2
clrf GPIO ; leave all output lines LOW
retlw 0
end
The .asm and .hex for 4 Alarm Sounds chip with Space Gun selected when A0 and A1
HIGH, is in the following files:
4 Alarm Sounds.asm
4 Alarm Sounds.hex
4 ALARM SOUNDS for PIC12F629
; alarm_4Sounds.asm for PIC12F629 29-1-2010
;
;This program has goto mode 2,3 changed to produce
;SPACE GUN with A0 and A1 HIGH
;quiescent current = 100microamps
;
;
;
; --+------------ +5v
; | | |
; +--- | -----------------|[]|----+
; | |Vdd ---v--- | | |
; | +---|1 Gnd| piezo |
; | | | |
; +--------|GP5 GP0|--------------+
; | |
; Enable-----|GP4 GP1|----A0
; | |
; +----|GP3 GP2|----A1
; | -------
; | PIC12F629
; |
; |
; ----+---------- 0v
;
radix dec
include "p12f629.inc"
errorlevel -302 ; Don't complain about BANK 1 Registers
__CONFIG _MCLRE_OFF & _CP_OFF &
_WDT_OFF & _INTRC_OSC_NOCLKOUT ;Internal osc.
STATUS equ 3
PC equ 2
#define CARRY STATUS,0
#define ZERO STATUS,2
#define outa GPIO,0 ;
#define modea GPIO,1 ;
#define modeb GPIO,2 ;
#define enbf GPIO,3 ;
#define enbt GPIO,4 ;
#define outb GPIO,5 ;
flags equ 20h ;flags file
temp equ 21h
delA equ 22h
delB equ 23h
dwell equ 25h ;cycles
count equ 26h ;delay
steps equ 27h ;dwell
cnth equ 28h
cntl equ 29h
org 0
goto setup
nop
nop
nop
nop
goto Enable
SetUp movlw b'00001111' ;0001 1111
movwf GPIO ;Make GP 0 HIGH and GP5 LOW for piezo & GP4 low
bsf status,rp0 ;Bank 1
movlw b'00011110'
movwf trisio ;Make GP1,2,3,4 input GP0,5 output
movlw b'10000110' ;Turn off T0CKI, prescaler for TMR0 = 1:128
movwf option_reg
bsf intcon,3 ;enable GPIO state change int
bsf intcon,7 ;enable global interrupt GIE
bsf IOC,4 ;enables interrupt on GPIO 4
bcf status,rp0 ;bank 0
movlw 07h ;Set up W to turn off Comparator ports
movwf CMCON ;must be placed in bank 0
clrf delA
movlw .140 ;for 3 minutes
movwf delB
;look for enable HIGH
goto $+1
goto $+1
decfsz temp,1
goto $-3
movf GPIO,w ;clears the Int-on-change flag
bsf status,rp0 ;Bank 1
bcf intcon,gpif
bcf status,rp0 ;bank 0
nop
sleep
nop ;micro goes to ISR at address 04!!!!!!!!!
Enable call _3min
btfsc GPIO,1 ;Test A0
goto $+4 ;A0=High
btfsc GPIO,2 ;A0=Low Test A1
goto mode3 ;A0=Low A1=high
goto mode0 ;A0=Low A1=low
btfsc GPIO,2 ;A0=High Test A1
goto mode2 ;A0=High A1=high This program produces SPACE GUN
goto mode1 ;A0=High A1=low with A0 and A1 HIGH
;mode 0 CONSTANT 2.2kHz tone A0=Low A1=low
mode0 movlw .20 ; set frequency
movwf count
call toggle
btfsc GPIO,4 ;test GPIO,4 - High Input enables chip to produce tone
goto $-4
goto Enable
;mode 1 CHIRP A0=High A1=low
mode1
movlw 35 ;set frequency delay
movwf count ;put 35 into Count file
movlw 1
movwf cnth ;put 1 in counter HIGH file
clrf cntl ;clear counter LOW file
mode1a call toggle
decfsz cntl,1 ;decrement and test counters
goto mode1a
decfsz cnth,1
goto mode1a
movlw 2 ;set pause delay to counters
movwf cnth
clrf cntl
mode1b nop
nop
nop
decfsz cntl,1 ;decrement and test counters
goto mode1b
decfsz cnth,1
goto mode1b
movlw 1 ;init second pulsed delay to counters
movwf cnth
clrf cntl
mode1c
call toggle
decfsz cntl,1 ;decrement and test counters
goto mode1c
decfsz cnth,1
goto mode1c
btfsc GPIO,4 ;test GPIO,4 - High Input enables chip to produce tone
goto mode1
goto Enable
;SPACE GUN A0=Low A1=high
mode2
movlw 7 ;number of steps
movwf steps
mode2a
movlw 5 ;dwell
movwf dwell
call toggle
decfsz dwell,1 ; test if dwell = 0
goto $-2
movlw 5
subwf count,1 ;increment frequency
btfss GPIO,4 ;test GPIO,4 - High Input enables chip to produce tone
goto Enable ;see if Enable is still HIGH and loop again
decfsz steps,1 ;test if more steps
goto mode2a
goto mode2
mode3 ;mode 3 SIREN A0=High A1=high
movlw 37 ;set frequency
movwf count
movlw 6 ; set number of steps
movwf steps
mode3a movlw 0x20 ; 0010 0000 set dwell
movwf dwell
mode3b call toggle
decfsz dwell,1 ; test if any more cycles
goto mode3b
movlw 5 ; step frequency delay
subwf count,1
decfsz steps,1 ; test if last step in progress
goto mode3a ;
btfsc GPIO,4 ;test GPIO,4 - High Input enables chip to produce tone
goto mode3
goto Enable
toggle movf count,0
movwf temp
goto $+1
goto $+1
decfsz temp,1
goto $-3
movlw b'00100001'
xorwf GPIO,1 ;toggle bits 0 & 5
retlw 00
_3min decfsz delA
retlw 00
decfsz delB
retlw 00
goto SetUp
end
--------------------------------------------------------------------
===========================================================
TALKING ELECTRONICS Interactive website
http://www.talkingelectronics.com
===========================================================
===========================================================
ROUTINES for "Copy and Pasting for PIC12F629"
by Colin Mitchell
talking@tpg.com.au 9-9-2008
===========================================================
The following are the ROUTINES for "Copy and Pasting" into
your program - commonly called your ".asm file"
They are in alphabetical order, so everything is easy to find
- and easy to use.
Simply copy and paste them into your program: Hold the
left mouse button down as you pass the mouse over the instructions.
Then click the right mouse button and a box will appear.
Select "Copy." Go to your program - in an another NotePad
or WordPad - and "Paste" the instructions. All the instructions
should "line-up" into three columns.
If you use a set of instructions as a complete routine,
it is called a sub-routine.
Alternatively they can be added to another routine, such as "Main."
Make sure you understand what to do before using this library.
All these instructions are fully explained in "Library of Routines."
"Library of Routines" can be found in our PIC Theory section when you
subscribe to the website or buy the CD.
The instructions for your program are arranged in three columns.
The first column contains the "labels." They identify the first
instruction for a sub-routine.
The second column contains the "instruction" - called the
mnemonic. The "half-computer" "half-English" instruction that
both computer and micro understands.
The third column contains the "comments." It must have a ";" before
each line so that they are not assembled - so they don't
appear in the final .hex file!
Note: All the instructions in this library will "run" when placed in
a program. But sometimes, something goes wrong. If an instruction
has hidden "formatting," the assembler may create the wrong code.
To see if an instruction has hidden formatting, simply hold down
the left button on the mouse and drag across the instruction.
The background will go black and will not extend past the actual word.
Try the following: DECFSZ del2A,1
This instruction has hidden formatting: DECFSZ del2A,1
Simply remove any hidden formatting by holding the mouse on the
unwanted spaces and use the back-space arrow to remove the spaces
(or re-type the complete instruction) and the problem will be fixed.
(It does not matter if "comments" have extra spaces. "Comments" are
not assembled.)
Start by usign the template "blank12F628.asm"
Delete the instructions you do not want and add the instructions
you want. Make sure the labels are correct.
-----------------------------------------------------
ADD A VALUE TO A FILE
-----------------------------------------------------
A file contains a known value. To add a value to the file use:
Add MOVLW 0xCC ;Put CC into W
ADDWF 2Eh ;CC will be added to the contents of file "2E."
If the file overflows, the Carry/Borrow bit in the Status file
(file 03,0) will be SET.
Add MOVLW 0CCh ;Put CCh into W
ADDWF 2Eh ;CC will be added to the contents of file "2E"
BTFSS 03,0 ;Test the carry bit in the Status file
GOTO AAA ;Micro will go to AAA if no overflow
GOTO BBB ;Micro will go to BBB if overflow occurs
-----------------------------------------------------
BEEP - TONE - this is a constant tone
-----------------------------------------------------
To use RB0 as the output: MOVLW 01h (see line 8 in subroutine below)
To use RB1 as the output: MOVLW 02h
To use RB2 as the output: MOVLW 04h
To use RB3 as the output: MOVLW 08h
To use RB4 as the output: MOVLW 10h
To use RB5 as the output: MOVLW 20h
To use RB6 as the output: MOVLW 40h
Tone MOVLW 40h ;The duration of the tone or "beep"
MOVWF 2B
Tone1 MOVLW A0h ;The length of HIGH and LOW - frequency of tone
MOVLW 2A
Tone2 NOP
DECFSZ 2A,1
GOTO Tone2
MOVLW 01h ;Put 01h into W
XORWF GPIO,1 ;XOR 01 with GPIO. Toggle GP0
DECFSZ 2B,1
GOTO Tone1
RETLW 00
-----------------------------------------------------
BEEP - BEEP - BEEP - repeat
-----------------------------------------------------
This beep routine is suitable for debugging a program. The
instruction GOTO Beep1 is inserted in a program to see how far the
micro has advanced through the instructions.
Beep1 produces an endless beep . . . beep . . . beep . . .
In the sub-routine you are trying to debug, put the instruction:
GOTO Beep1
At the beginning of memory, after Tables, put the following:
Beep1 CALL Beep
CALL BeepDel
GOTO Beep1
Beep MOVLW 40h ;The duration of the beep
MOVWF 2B
Beep1 MOVLW A0h ;The length of HIGH and LOW - frequency of beep
MOVLW 2A
Beep2 NOP
DECFSZ 2A,1
GOTO Beep2
MOVLW 02h ;Put 02 into W
XORWF GPIO,1 ;XOR 02 with GPIO. Toggle GP1
DECFSZ 2B,1
GOTO Beep1
RETLW 00
BeepDel DECFSZ 2A,1
GOTO BeepDel
DECFSZ 2B,1
GOTO BeepDel
RETLW 00
-----------------------------------------------------
BUTTON - SWITCH - PUSH BUTTON
-----------------------------------------------------
In this routine a push button is connected to GP0.
When it is pushed, a HIGH is delivered to GP0.
Or, if you want to make GP1 a button-line, the second instruction in
SetUp is: MOVLW 02.
To make GP3 an input, the instruction is: MOVLW 08
The button-file must be cleared in SetUp.
There are two flags. Bit0 in file 2F is the Debounce Flag
and Bit1 in file 2F is the Button Pressed flag.
The microprocessor executes Main and CALLs Sw.
If Sw detects a key-press, two flags are SET.
The first is the Button Pressed flag
and the second is the Debounce flag.
The micro returns to Main and tests the Button Pressed
flag to see if it is SET.
If is is SET, the micro goes to a sub-routine
such as CALL Increment, where a value can be incremented.
The Button Pressed flag is then cleared and the micro CALLs Sw.
If the switch is still pressed, the micro will return.
The program is looking for the button to be released.
When the button is released, the Sw sub-routine is ready
to detect another button-push.
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 01 ;Put 01 into W to
MOVWF TRISIO ;make GP0 input
BCF 03,5 ;Go to Bank 0
CLRF 2F ;Clear the button-press file
GOTO Main
Sw1 BTFSS GPIO,0 ;Test the button. Button is "Active HIGH"
GOTO Sw2 ;Button not pressed
BTFSC 2F,0 ;Button pressed first time? Test debounce flag
RETURN ;Button already pressed. Return to Main
Sw1A DECFSZ 2A,1 ;Create short delay
GOTO Sw1A ;Look again
BTFSS GPIO,0 ;Is switch still pressed?
GOTO Sw1B ;It was only noise
BSF 2F,1 ;Button Pressed. Set button-pressed flag
BSF 2F,0 ;Set debounce flag
RETURN ;Return to Main
Sw1B BCF 2F,0 ;Clear debounce flag
RETLW 00 ;Return to Main
Main CALL Sw
BTFSC 2F,1 ;Test button-press flag to see if button was pressed
GOTO Main1 ;Button pressed
your instruction;Button not pressed - carry out a sub-routine to
your instruction; display values on a display etc.
GOTO Main
Main1 CALL Increment ;Increment the display. (you provide the routine)
BCF 2F,1 ;Clear the button-press flag
GOTO Main
To connect two buttons to a micro.
The second instruction in SetUp must be the addition of the hex values
of the input lines
E.g: GP1 and GP2 = 0000 0010 + 0000 0100 = 0000 0110 = 06h
GP3 and GP5 = 0000 1000 + 0010 0000 = 0010 1000 = 28h
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 03 ;Put 03 into W to
MOVWF TRISIO ; make GP0 and GP1 input
BCF 03,5 ;Go to Bank 0
CLRF 2F ;Clear the button-press file
GOTO Main
Sw1 BTFSS GPIO,0 ;Test the first button. Button1 is "Active HIGH"
GOTO Sw2 ;Button not pressed
BTFSC 2F,0 ;Button pressed first time? Test debounce flag
RETURN ;Button already pressed. Return to Main
Sw1A DECFSZ 2A,1 ;Create short delay
GOTO Sw1A ;Look again
BTFSS GPIO,0 ;Is switch still pressed?
GOTO Sw1B ;It was only noise
BSF 2F,1 ;Button Pressed. Set button-pressed flag
BSF 2F,0 ;Set debounce flag
RETURN ;Return to Main
Sw1B BCF 2F,0 ;Clear debounce flag
RETLW 00 ;Return to Main
Sw2 BTFSS GPIO,0 ;Test the second button. Button2 is "Active HIGH"
GOTO Sw2 ;Button not pressed
BTFSC 2F,2 ;Button pressed first time? Test debounce flag
RETLW 00 ;Button already pressed. Return to Main
Sw2A DECFSZ 2A,1 ;Create short delay
GOTO Sw2A ;Look again
BTFSS GPIO,0 ;Is switch still pressed?
GOTO Sw2B ;It was only noise
BSF 2F,3 ;Button Pressed. Set button-pressed flag
BSF 2F,2 ;Set debounce flag
RETLW 00 ;Return to Main
Sw2B BCF 2F,2 ;Clear debounce flag
RETLW 00 ;Return to Main
Main CALL Sw1
BTFSC 2F,1 ;Test button-press flag to see if button was pressed
GOTO Main1 ;Button pressed
your instruction;Button not pressed - carry out a sub-routine to
your instruction; display values on a display etc.
your instruction
CALL Sw2
BTFSC 2F,3 ;Test button-press flag to see if button was pressed
GOTO Main2 ;Button pressed
GOTO Main
Main1 CALL Increment ;Increment the display. (you provide the routine)
BCF 2F,1 ;Clear the button-press flag
GOTO Main
Main2 CALL Decrement ;Decrement the display. (you provide the routine)
BCF 2F,3 ;Clear the button-press flag
GOTO Main
-----------------------------------------------------
CALLS - a list of suitable Calls:
-----------------------------------------------------
Any names can be used. Keep the length to less than 8 letters.
CALL Alarm
CALL Beep
CALL Button
CALL Count
CALL Dec
CALL Delay
CALL Display
CALL Find
CALL HeeHaw
CALL Inc
CALL Look
CALL Loop
CALL Main
CALL Send
CALL Show
CALL Siren
CALL Sound
CALL Sw
CALL Switch
CALL Table
CALL Test
CALL Toggle
CALL Tone
-----------------------------------------------------
CALL A TABLE
-----------------------------------------------------
Load a value into W and CALL Table1. The micro will look down the
table. If the value you have loaded into W is 00, the first value
in the table will be fetched. If the value is 01, the second value
will be fetched.
The micro adds the value in W to the Program Counter and this
causes the micro to jump down the table. The PC naturally increments
to the next instruction and that's why 3Fh is selected if the loaded
value is 00.
Table1 ADDWF 02h,1 ;Add W to the Program Counter to create a jump.
RETLW 3Fh ;0 format= gfedcba
RETLW 06h ;1
RETLW 5Bh ;2
RETLW 4Fh ;3
RETLW 66h ;4
RETLW 6Dh ;5
RETLW 7Dh ;6
RETLW 07h ;7
RETLW 7Fh ;8
RETLW 6Fh ;9
Main - - - - -
MOVLW 00h ;load a value into W. 00h will pick up 3Fh from table
CALL Table1 ;The micro will return with 3Fh in W
MOVWF GPIO ;Move 3Fh to in/out Port GPIO (file 05)
- - - - -
- - - - -
-----------------------------------------------------
DECREMENT A FILE
-----------------------------------------------------
DECF 2A,1 ;Puts the new value into the file
-----------------------------------------------------
DECREMENT A FILE and SKIP WHEN IT IS ZERO
-----------------------------------------------------
DECFSZ 2A,1 ;Puts the new value into the file
Not zero ;Goes here if file is not zero
zero! ;Goes here if file is zero!
-----------------------------------------------------
DELAYS
-----------------------------------------------------
This delay creates FFh loops. Each loop takes 4uS
Total time: 256 x 4 = 1024uS = say 1mS
Del NOP
DECFSZ 2A,1 ;Decrement file 2A
GOTO Del ;Loop until file 2A is zero
RETLW 00
This delay creates 80h loops. Each loop takes 4uS
Total time: 128 x 4 = 512uS
Del MOVLW 80h ;Put 80h into W
MOVWF 2A ;Copy 80h into file 2A
DelA NOP
DECFSZ 2A,1 ;Decrement file 2A
GOTO DelA ;Loop until file 2A is zero
RETLW 00
NESTED DELAY
This delay creates FFh loops (determined by file 2B).
Each loop takes 4uS and there are 256 inner loops = 1024uS = 1mS
This inner loop is executed 256 times via file 2B.
Total time = 260mS
Del NOP
DECFSZ 2A,1 ;Decrement file 2A
GOTO Del ;Loop until file 2A is zero
DECFSZ 2B,1 ;Decrement file 2B
GOTO Del ;Loop until file 2B is zero
RETLW 00
For a delay between 1mS and 260mS, you will need to pre-load file 2B:
Del MOVLW 7Dh
MOVWF 2B
Del1 NOP
DECFSZ 2A,1 ;Decrement file 2A
GOTO Del1 ;Loop until file 2A is zero
DECFSZ 2B,1 ;Decrement file 2B
GOTO Del1 ;Loop until file 2B is zero
RETLW 00
-----------------------------------------------------
EEPROM ROUTINES
-----------------------------------------------------
To load EEPROM:
ORG 2100h
DE 84h, 16h, 23h, 80h, 0CAh, 32h, 7Bh, 0A2h
DE 34h, 53h, 25h, 02h, 0FFh, 20h, 03h, 04h
The sub-routine to read a value in the EEPROM is shown below.
It reads EEPROM data at location specified in EEADR and
returns the value in W
EERead BSF Status, RP0 ;Go to Bank 1
BSF EECON1, RD ;Set the RD bit
BCF Status, RP0 ;Back to bank 0
MOVF 08, W ;EE Data is file 08. Put into W
RETLW 00
The sub-routine to write to EEPROM is shown below.
Delay1 MOVLW 13h ;Create a 20mS delay
MOVWF 2B ;20 loops
Delay1a NOP
DECFSZ 2A,1 ;4uS x 256 loops=approx 1mS
GOTO Delay1a
DECFSZ 2B,1
GOTO Delay1a
RETLW 00
EEWrite MOVWF 08 ;W to EEData
BSF 03,5 ;Switch to bank 1
BCF 0B,7 ;Disable interrupts
BSF 08,2 ;Write Enable bit set
MOVLW 55h ;Toggle EEPROM Control
MOVWF 09 ; Register bits
MOVLW 0AAh ;Toggle EEPROM Control
MOVWF 09 ; Register bits
BSF 08,1 ;Begin write sequence
CALL Delay1 ;Call Delay1
BCF 08,2 ;Disable any further writes
BSF 0B,7 ;Enable Interrupts
BCF 03,5 ;Back to data bank 0
RETLW 00
-----------------------------------------------------
GOTO
-----------------------------------------------------
To make the micro go to another part of your program, use the
GOTO instruction. Simply write the word "GOTO." Following
GOTO, we place a "label" The label may be "Sw1" or "Count" or "Test."
"Sw1" or "Count" or "Test." will appear in the first column
of your program. The instruction "GOTO Test" will take the micro
to the line containing the label: Test.
The micro will not return to the instruction following GOTO Test,
unless you have a label at the line such as "Togu1" and include
an instruction GOTO Togu1 in your program.
If you GOTO a sub-routine, the last instruction in the
sub-routine cannot be RETURN as the micro does not have a return
address in its memory - on the STACK.
The only time a return address is placed on the stack is when a CALL
is executed.
GOTO Alarm
GOTO Beep
GOTO Button
GOTO Count
GOTO Dec
GOTO Delay
GOTO Display
GOTO Find
GOTO HeeHaw
At the end of the sub-routine will be a GOTO Main or GOTO another
sub-routine. It does not have to be the last instruction in a
sub-routine but it is the only exit instruction you can use.
You cannot use "RETLW 00."
-----------------------------------------------------
HEX VALUES
-----------------------------------------------------
All the files in a micro have 8 bits.
All the input/output ports have 8 lines.
The lowest bit or line is shown as a "1" in the folling value:
0000 0001
The lowest bit is called Bit0
The lowest line is called GP0
The next line (in/out line) or "bit" is called GP1:
0000 0010
The lowest line has a value of zero when not active and ONE when active.
The next has a vaue of TWO when active.
The next has a value of FOUR when active.
The next has a value of EIGHT when active.
The 4 in/out lines have the following 16 possibilities:
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
They are given the following values:
0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = A
1011 = B
1100 = C
1101 = D
1110 = E
1111 = F
The four HIGH lines have the same format:
0000 0000 = 00
0001 0000 = 10
0010 0000 = 20
0011 0000 = 30
0100 0000 = 40
0101 0000 = 50
0110 0000 = 60
0111 0000 = 70
1000 0000 = 80
1001 0000 = 90
1010 0000 = A0
1011 0000 = B0
1100 0000 = C0
1101 0000 = D0
1110 0000 = E0
1111 0000 = F0
The four HIGH and LOW lines produce 256 combinations.
Here are some:
0011 0101 = 35
1011 0000 = B0
1110 1001 = E9
1011 0000 = B0
0110 1110 = 6E
0101 0000 = 50
1001 1011 = 9B
0110 1011 = 6B
The value to make GP2 and GP5 input:
0010 0100 = 24
-----------------------------------------------------
INCREMENT A FILE
-----------------------------------------------------
INCF 2A,1 ;Puts the new value into the file
-----------------------------------------------------
INPUT
-----------------------------------------------------
To make a line (or lines), an INPUT, it must be given the
value "1." This can be done anywhere in the program
but it is best to put the instruction in SetUp.
This makes it easy to locate when trouble-shooting.
The instructions between BSF and BCF in the routine below are
operating on a register in bank 1 and this is the in/out
control register for PortA. It is NOT PortA. It is the
register that determines the IN or OUT condition of
each line in PortA and is called the TRIS register.
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 0F ;Put 0000 1111 into W to
MOVWF TRISIO ; make GP0, GP1, GP2, and GP3 input
BCF 03,5 ;Go to Bank 0
GOTO Main
-----------------------------------------------------
INPUT A VALUE
-----------------------------------------------------
The input lines for a 12F629A are: GP0, GP1, GP2, GP3, GP4 and GP5.
GP3 is input-only and this line is usually the chosen input.
To input a value (A HIGH or LOW), make sure the line is an
input. This is done in SetUp:
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 01 ;Put 0000 0001 into W to
MOVWF TRISIO ; make GP0 input
BCF 03,5 ;Go to Bank 0
GOTO Main
In Main, test the input line:
Main BTFSS GPIO,0
GOTO - - -
- - - - -
- - - - -
-----------------------------------------------------
LAYOUT OF A PROGRAM
-----------------------------------------------------
Use the following when layingout your program:
SetUp
Table1
Table2
LabelA - put all labels in alphabetical order so they can be found
quickly.
LabelB
LabelC
LabelD
Main
-----------------------------------------------------
LOOK for a Table-value
-----------------------------------------------------
See Table-value
-----------------------------------------------------
LOOP
-----------------------------------------------------
When writing a program, you can use a loop to create a STOP function.
Loop NOP
GOTO Loop
Inside the loop you can put a tone routine so you can see if the
micro has reached the location.
Loop MOVLW A0h ;The length of HIGH and LOW - frequency of tone
MOVLW 2A
Tone NOP
DECFSZ 2A,1
GOTO Tone
MOVLW 01h ;Put 01 into W
XORWF GPIO,1 ;XOR 01 with GPIO. Toggle GP0
GOTO Loop
-----------------------------------------------------
MAIN
-----------------------------------------------------
Main is the last routine in your program. It is a loop routine
and has a number of CALL and/or GOTO instructions: (If you GOTO
a sub-routine, the sub-routine must have a GOTO as the exit).
Main - - - - -
- - - - -
- - - - -
CALL Delay
- - - - -
- - - - -
- - - - -
GOTO Main
-----------------------------------------------------
OUTPUT
-----------------------------------------------------
To make a line (or lines), an OUTPUT, it must be given the
value "0." This can be done anywhere in the program
but it is best to put the instruction in SetUp.
This makes it easy to locate when trouble-shooting.
The instructions between BSF and BCF in the routine below are
operating on a register in bank 1 and this is the in/out
control register for PortB. It is NOT PortB. It is the
register that determines the IN or OUT condition of
each line in PortB and is called the TRIS register.
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 00 ;Put xx00 0000 into W to
MOVWF TRISIO ; make all six GPIO lines output
BCF 03,5 ;Go to Bank 0
GOTO Main
In Main, output a HIGH on GPIO (file 05):
Main - - - - -
MOVLW 0FFh ;
MOVWF GPIO ;Output a HIGH to the 6 lines of GPIO
- - - - -
- - - - -
-----------------------------------------------------
OVERFLOW
-----------------------------------------------------
If a value is added to a file, overflow may occur.
To see if overflow occurs, test the Carry/Borrow bit in the Status file
(file 03,0). It will be SET if overflow occurs.
Add MOVLW 0CCh ;Put CCh into W
ADDWF 2Eh ;CC will be added to the contents of file "2E."
BTFSS 03,0 ;Test the carry bit in the Status file
GOTO AAA ;Micro will go to AAA if no overflow
GOTO BBB ;Micro will go to BBB if overflow occurs
-----------------------------------------------------
RETURN
-----------------------------------------------------
The PIC12F629 does not have a RETURN instruction.
If you use RETURN in your program, the assembler will replace
it with RETLW 00 when creating a .hex file
-----------------------------------------------------
SetUp
-----------------------------------------------------
This is the first sub-routine in your program. It sets up the
in/out port in the microcontroller. GPIO has up to 6 lines
and these can be inputs or outputs. (GP3 is input-only).
The input lines for a 12F629 are: GP0, GP1, GP2, GP3, GP4 and GP5.
GP3 is input-only and this line is usually the chosen input.
The output lines are: GP0, GP1, GP2, GP4 and GP5.
An input line can be changed to an output at any time during
the running of a program.
An output line can be changed to an input at any time during
the running of a program.
The input/output lines of a PIC12F629 are in file 05.
To make GP0 an input, place the following instructions in SetUp:
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 01 ;Put 0000 0001 into W to
MOVWF TRISIO ; make GP0 input
BCF 03,5 ;Go to Bank 0
GOTO Main
To make GP0 an output, place the following instructions in SetUp:
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 00 ;Put 0000 0000 into W to
MOVWF TRISIO ; make GP0 output
BCF 03,5 ;Go to Bank 0
GOTO Main
To make any GP line an input, place "1" in the corresponding
position for the value loaded into W:
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 08 ;Put 0000 1000 into W to
MOVWF TRISIO ; make GP3 input
BCF 03,5 ;Go to Bank 0
GOTO Main
To create two input lines:
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 12 ;Put 0001 0010 into W to
MOVWF TRISIO ; make GP1 and GP4 input
BCF 03,5 ;Go to Bank 0
GOTO Main
-----------------------------------------------------
STATUS FILE
-----------------------------------------------------
The STATUS file is file 03.
Bit0 is the Carry/Borrow
Bit1 is the Digit Carry/Borrow
Bit2 is the Zero bit
Bit3 is the Power Down bit
Bit4 is the Time-out bit
When bit5 is SET Bank1 is selected
When bit5 is CLEAR Bank0 is selected
-----------------------------------------------------
STOP
-----------------------------------------------------
The micro does not have a STOP or HALT instruction.
When writing a program, you can use a loop to create a STOP function.
Loop NOP
GOTO Loop
Inside the loop you can put a tone routine so you can see if the
micro has reached the location.
Loop MOVLW A0h ;The length of HIGH and LOW - frequency of tone
MOVLW 2A
Tone NOP
DECFSZ 2A,1
GOTO Tone
MOVLW 01h ;Put 01 into W
XORWF GPIO,1 ;XOR 01 with GPIO. Toggle GP0
GOTO Loop
-----------------------------------------------------
TABLE - see also CALL A TABLE
-----------------------------------------------------
Load a value into W and CALL Table1. The micro will look down the
table. If the value is 00, the first value in the table will be
fetched. If the value is 01, the second value will be fetched.
The micro adds the loaded-value into the Program Counter and this
causes the micro to jump down the table. The PC naturally increments
and that's why 3Fh is selected if the loaded value is 00.
Any values with a letter as the first part of the hex value must
begin with a "0" E.g: FFh = 0FFh CDh = 0CDh
The end of a table can be identified by using 0FFh (providing FFh is
not a required table value). In Main, look for 0FFh as a table value.
Table1 ADDWF 02h,1 ;Add W to the Program Counter to create a jump.
RETLW 3Fh ;0 format= gfedcba
RETLW 06h ;1
RETLW 5Bh ;2
RETLW 4Fh ;3
RETLW 66h ;4
RETLW 6Dh ;5
RETLW 7Dh ;6
RETLW 07h ;7
RETLW 7Fh ;8
RETLW 6Fh ;9
RETLW 0FFh
Main - - - - -
MOVLW 00h ;load a value into W. 00h will pick up 3Fh from table
CALL Table1 ;The micro will return with 3Fh in W
MOVWF GPIO ;Move 3Fh to output Port GPIO (file 05)
- - - - -
- - - - -
-----------------------------------------------------
Table-value
-----------------------------------------------------
To "Look for" or "fetch" a table value, you need 2 instructions.
To fetch the first table value, load W with 00.
To fetch the second table value, load W with 01 etc.
The second instruction is CALL Table1
The micro will return with the table-value in W:
Table1 ADDWF 02h,1 ;Add W to the Program Counter to create a jump.
RETLW 3Fh ;0 format= gfedcba
RETLW 06h ;1
RETLW 5Bh ;2
RETLW 4Fh ;3
RETLW 66h ;4
RETLW 6Dh ;5
RETLW 7Dh ;6
Main - - - - -
- - - - -
MOVLW 04
CALL Table1
- - - - -
- - - - -
The micro will return with 66h in W
-----------------------------------------------------
TEMPLATE
-----------------------------------------------------
Use this template as a start to writing your program.
This is not a fully-functional program.
It is a set of example-instructions.
Delete the unwanted instructions.
;Expt1.asm
;Project: Turning on a -----
;This program can be assembled for a PIC12F629
ORG 0 ;This is the start of memory for the program
SetUp BSF 03,5 ;Go to Bank 1
MOVLW 01 ;Load W with 0000 0001
MOVWF TRISIO ;Make GP0 input
BCF 03,5 ;Go to Bank 0 - the program memory area
GOTO Main
Delay NOP ;Create approx 250mS delay
DECFSZ 2A,1
GOTO Delay
DECFSZ 2B,1
OTO Delay
RETLW 00
Look CLRF 2C ;Count-down file
- - - - -
CALL Delay ;250mS delay
BSF 03,5 ;Go to Bank 1
MOVLW 04 ;Load W with 0000 0100
MOVWF GPIO ;Make GP2 input & GP0 output
BCF 03,5 ;Go to Bank 0 - the program memory area.
RETLW 00
Main BTFSS GPIO,0 ;Test the input line on GPIO
GOTO Main2 ;Button not pressed
BSF GPIO,0 ;Button pressed. Turn on LED
CALL Delay
- - - - -
CALL Look
Main2 BCF GPIO,0 ;Button not pressed. Turn off LED
GOTO Main ;Loop Main
END ;Tells assembler end of program
-----------------------------------------------------
TOGGLE
-----------------------------------------------------
Toggle changes the state of an output. You do not have to know
the state of the output before the operation. The output changes
from HIGH to LOW or LOW to HIGH. You do not know the output after
the operation. This operation is not suitable if you want to
leave an output low when not in use so that it is not left in a
"driving" condition when not required.
To toggle GP0 use: MOVLW 01h
To toggle GP1 use: MOVLW 02h
To toggle GP2 use: MOVLW 04h
To toggle GP3 use: MOVLW 08h
To toggle GP4 use: MOVLW 10h
To toggle GP5 use: MOVLW 20h
Toggle MOVLW 02h ;Put 02 into W
XORWF GPIO,1 ;XOR 02 with GPIO. Toggle GP1
-----------------------------------------------------
TRIS
-----------------------------------------------------
"Tris" is the file (register) that determines if each bit in GPIO
(Port 05) is input or output.
See Library of Routines for more details.
==============================alarm below======================
Alarm4Zone.asm for PIC12F629 16-12-2013
;; Alarm4Zone.asm for PIC12F629 6-1-2014
;
;
radix dec
include "p12f629.inc"
errorlevel -302 ; Don't complain about BANK 1
;Registers during assembly
__CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF &
_INTRC_OSC_NOCLKOUT ;Internal osc.
STATUS equ 3
PC equ 2
#define CARRY STATUS,0
#define ZERO STATUS,2
;Files:
flags equ 20h ;flags file
tempA equ 21h
delA equ 22h
delB equ 23h
delC equ 24h
dwell equ 25h
steps equ 26h
count equ 27h
temp1 equ 28h
loops equ 29h
store equ 2Ah ;stores triggered input No
loop30 equ 2Bh ;loops for 5 minute siren
org 0
goto SetUp
nop
SetUp
movlw 07h ;Set up W to turn off Comparator ports
movwf CMCON ;must be placed in bank 0
goto Main
;**************************
;* Delays *
;**************************
_1mS movlw .40 ;reduced to 40/255 of 1mS
movwf delA
decfsz delA,f
goto $-1
retlw 00
;240mS delay
_240mS nop
decfsz delA,1
goto $-2
decfsz delB,1
goto $-4
retlw 00
_500mS goto $+1
goto $+1
decfsz delA,1
goto $-3
decfsz delB,1
goto $-5
retlw 00
;****************************
;* Sub-routines *
;****************************
;beep-beep-beep to siren for soft start
beep
movlw .50
movwf tempA
bsf gpio,5
movlw .40
movwf delA
nop
decfsz delA,f
goto $-2
bcf gpio,5
movlw .240
movwf delA
goto $+1
decfsz delA,f
goto $-2
decfsz tempA,f
goto $-13
call _240mS
retlw 00
;Charge 22n
Charge bsf status,rp0 ;Bank 1
movlw b'00101111'
movwf trisio ;Make GP0,1,2,3,5 input GP4 output
bcf status,rp0 ;bank 0
bsf gpio,4
call _1mS ;charge 22n
bsf status,rp0 ;Bank 1
movlw b'00111111'
movwf trisio ;Make GP0,1,2,3,5 input GP4 input
bcf status,rp0 ;bank 0
bcf gpio,4
call _1mS ;time for swA to discharge 22n
retlw 00
;Indicate
;flash 1 time for constant wailing or 4 times for 5 minutes wailing
Indicate
bsf status,rp0 ;Bank 1
movlw b'00111001'
movwf trisio ;Make GP1,2 output
bcf status,rp0 ;bank 0
clrf gpio ;make outputs low to turn off LEDs,
call read ;read 0 or 1 from EEPROM location 1
btfss temp1,0
goto Ind_1
bsf gpio,2 ;temp1 = 1 = contant siren
call _500mS
bcf gpio,2
call _500mS
retlw 00
Ind_1 bsf gpio,1 ;temp1 = 0 = 5 minute siren
call _500mS
bcf gpio,1
call _500mS
bsf gpio,1
call _500mS
bcf gpio,1
call _500mS
bsf gpio,1
call _500mS
bcf gpio,1
call _500mS
bsf gpio,1
call _500mS
bcf gpio,1
call _500mS
retlw 00
;read takes the value 0 or 1 from EEPROM location 0 and puts in temp1
read
movlw .0
bsf status,rp0
movwf EEADR
bsf EECON1,0 ;starts EEPROM read operation result in EEDATA
movf EEDATA,w ;move read data into w
bcf status,rp0
movwf temp1 ;temp1 has the value 0 or 1 to flash a LED
retlw 00
;SIREN - WAILING SIREN
Siren movlw 7 ;number of steps
movwf steps
Siren1 movlw 5 ;dwell
movwf dwell
bsf gpio,5
movf count,0
movwf tempA
decfsz tempA,1
goto $-1
bcf gpio,5
movf count,0
movwf tempA
goto $+1
goto $+1
goto $+1
decfsz tempA,1
goto $-4
decfsz dwell,1 ;
goto $-14
movlw 5
subwf count,1 ;
decfsz steps,1 ;
goto Siren1
retlw 00
;Siren Beeps for 10 seconds
SirenBeep
bsf status,rp0 ;Bank 1
movlw b'00011111'
movwf trisio ;Make GP0,1,2,3,4 input GP5 output
bcf status,rp0 ;bank 0
movlw .50 ;number of loops (cycles)
movwf tempA
SirenBeep1
bsf gpio,5 ;siren BD679 HIGH
movlw .40
movwf delA
nop
decfsz delA,f
goto $-2
bcf gpio,5 ;siren BD679 LOW for: 255 delA
nop
decfsz delA,f
goto $-2
decfsz tempA,f
goto SirenBeep1
call _240mS ;silence
retlw 00
;exit tone to piezo buzzer
tone ;524Hz for 250mS
bsf status,rp0 ;Bank 1
movlw b'00101111'
movwf trisio ;Make GP0,1,2,3,5 input GP4 output
bcf status,rp0 ;bank 0
movlw .50 ;number of loops (cycles)
movwf tempA
tone1 bsf gpio,4 ;buzzer BD679 HIGH
movlw .40
movwf delA
nop
decfsz delA,f
goto $-2
bcf gpio,4 ;buzzer BD679 LOW for: 255 delA
nop
decfsz delA,f
goto $-2
decfsz tempA,f
goto tone1
call _240mS ;silence
retlw 00
write
bsf status,rp0 ;select bank1
movwf EEDATA
bcf status,rp0 ;select bank0
movlw .0
bsf status,rp0 ;select bank1
movwf EEADR
bsf eecon1,wren ;enable write
movlw 55h ;unlock codes
movwf eecon2
movlw 0aah
movwf eecon2
bsf eecon1,wr ;write begins
bcf status,rp0 ;select bank0
writeA btfss pir1,eeif ;wait for write to complete
goto writeA
bcf pir1,eeif
bsf status,rp0 ;select bank1
bcf eecon1,wren ;disable other writes
bcf status,rp0 ;select bank0
retlw 00
;****************************
;* Main
;****************************
Main ;45 second exit with button A detect
;exit beep produced
clrf store ;stores triggered input No
movlw .180 ; 180 x 250mS = 45 seconds
movwf loops
call Indicate ;flash LED 4 times
M1 call Charge
btfsc gpio,4 ;is button A pressed?
goto M2 ;not pressed
call read ;0 or 1 will be in temp1
btfss temp1,0
goto $+4
clrf w
call write
goto M2
movlw 1
call write
M2 call tone ;call exit tone
decfsz loops,1
goto $-2
;monitors 4 inputs
Monitor bsf status,rp0 ;select bank1
movlw b'00101111'
movwf trisio ;Make GP0,1,2,3,5 input GP4 output
bcf 81h,7 ;turn on pulls-ups in option_reg
movlw b'00000111'
movwf 095h ;WPU register for GP0,1,2
bcf status,rp0 ;bank 0
btfsc gpio,0
goto Mon1
btfsc gpio,1
goto Mon1
btfsc gpio,2
goto Mon1
btfsc gpio,3
goto Mon1
goto Monitor
Mon1 bsf status,rp0 ;select bank1
bcf trisio,5 ;Make GP5 output
bcf status,rp0 ;bank 0
;soft-start siren with beeps for 10 seconds
movlw .40
movwf loops
call SirenBeep
decfsz loops,1
goto $-2
;constant siren if temp1,0 = 1
;5 minute siren if temp1,0 = 0
btfss temp1,0
goto Siren5min
call Siren ;constant siren
goto $-1
Siren5min
movlw .30 ;30 loops
movwf loop30
movlw .185 ;inner loop = 10 seconds
movwf loops
call Siren
decfsz loops,1
goto $-2
decfsz loop30,1
goto $-6
goto $
;************************************
;*EEPROM *
;************************************
org 2100h
de 00h
END