+ -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