Electronics > Projects, Designs, and Technical Stuff

My first PIC program

(1/7) > >>

Zero999:
I've been wanting to get into MCUs for awhile, I've had a PICkit 2 clone programmer for a few weeks now and have only just got round to reading a tutorial and writing a program.

Here's the schematic and code. The idea is to control an extractor fan which will be connect to a pull switch. Once the cord is pulled, the fan will turn on until ten minutes has passed or the cord is pulled again. For the purposes of testing the delay has been shortened to 10 seconds and the relay has been replaced with an LED.



--- Code: ---;************************************************************************
;                                                                       *
;   Description:    Extractor Fan Timer                                 *
;                                                                       *
;   Waits for the switch to be activated then turns on the fan which    *
;   stays on until either a period of time has passed or the switch     *
;   is pulled again. Switch debouncing is performed where requireed.    *
;                                                                       *
;                                                                       *
;************************************************************************
;                                                                       *
;   Pin assignments:                                                    *
;       GP1 - Fan output                                                *
;       GP3 - Pullcord switch                                           *
;                                                                       *
;************************************************************************

    list        p=12F509
    #include    <p12F509.inc>

                ; int reset, no code protect, no watchdog, 4MHz int clock
    __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC

;***** VARIABLE DEFINITIONS
        UDATA
sGPIO   res 1 ; shadow copy of GPIO
dc1     res 1 ; delay counter 1
dc2   res 1 ; delay counter 2

;************************************************************************
RESET   CODE    0x000 ; effective reset vector
        movwf   OSCCAL ; update OSCCAL with factory cal value
pagesel start
goto start ; jump to main code

;***** Subroutine vectors
wait_up ; wait for switch to be released
        pagesel wait_up_R
        goto    wait_up_R    

;***** MAIN PROGRAM
MAIN CODE

;***** Initialisation
start
        movlw   b'111101' ; configure GP1 (only) as an output
        tris    GPIO    
        movlw   b'10010101' ; enable internal pull-ups & configure Timer0:
; -0------ pullups enabled (/GPPU = 0)
; --0----- timer mode (T0CS = 0)
; ----0--- prescaler assigned to Timer0 (PSA = 0)
; -----101 prescale = 64 (PS = 101)          
        option ;   -> increment every 64 us
        clrf    GPIO ; start with fan off
        clrf    sGPIO ; update shadow

;***** Main loop
loop
        ; wait until switch pulled, debounce using timer0:
wait_dn clrf    TMR0 ; reset timer
chk_dn  btfsc   GPIO,3 ; check for switch pull (GP3 low)
        goto    wait_dn ; continue to reset timer until button down
        movf    TMR0,w ; has 10ms debounce time elapsed?
        xorlw   .156 ; (156=10ms/64us)
        btfss   STATUS,Z ; if not, continue checking button
        goto    chk_dn
        ; turn on fan on GP1
        bsf     sGPIO,1 ; set bit 1 on shadow register
        movf    sGPIO,w ; write back to shadow register
        movwf   GPIO ; write to port
call wait_up ; wait until switch is released
    
; waits until either a the switch is pulled or the time delay is over
movlw .4 ; delay is in multiples of 2.5 seconds
movwf dc1
delay_loop
movlw .250 ; waits 2.5s = 250*10ms, switch scanned every 10ms
movwf dc2
delay2s
; waits 10ms
clrf TMR0 ; reset timer
delay10 movf TMR0,w ; has 10ms elapsed?
xorlw d'156' ; (156=10ms/64us)
btfss STATUS,Z ; if not, go back to the beginning
goto delay10
btfss GPIO,3 ; check for switch pull (GP3 low)
goto turn_off ; if switch pulled, exit delay and turn off fan
decfsz dc2,f ; decrement counter, skip goto, if zero
goto    delay2s ; if counter is non-zero loop
decfsz dc1,f ; decrement counter, skip goto, if zero.
goto delay_loop

turn_off ; turn off fan on GP1
clrf GPIO ; fan off
clrf sGPIO ; update shadow
call wait_up ; wait until switch is released, if pressed
goto loop ; repeat forever

;***** Subroutines
SUBS    CODE

  ; wait until switch released, debounce using timer0:
wait_up_R
clrf TMR0 ; reset timer
chk_up btfss GPIO,3 ; check for button release (GP3 high)
goto wait_up_R ; continue to reset timer until button up
movf TMR0,w ; has 10ms debounce time elapsed?
xorlw d'156' ; (156=10ms/64us = 10/0.064)
btfss STATUS,Z ; if not, continue checking button
goto chk_up
retlw 0

        END

--- End code ---

I'll modify the code so if the switch is quickly pulled twice, it'll stay on continuously.

EDIT:
Here's a lnk to the tutorials I've followed, as you can see, I've borrowed lots of the code from demonstrations.
http://www.gooligum.com.au/tutorials/baseline/PIC_Base_A_4.pdf

Yes I know I could use some constants to make my code easier to read and I could've used timer debouncing in the main loop but I didn't think it was worth it and my tests indicate that it isn't necessary, just reading the switch status every 10ms seems to work fine.

scrat:
You used assembly... Was it hard at beginning? Did you consider starting with C or was assembly your choice just to learn more in deep?

edit: however, it's not a simple "hello world", the program is quite complex to start with. Congrats!

ArtemisGoldfish:
Assembly can be significantly easier than high-level languages for simple tasks, though for some things, I'd rather leave the impossible stuff to the compiler of a high-level language.

Mechatrommer:
most people dont like asm for mcu i think. except me and some of us, but even me struggling to understand my own code after i leaved it for a while, worst if its somebody else's code :P. all i need is a fresh big cup of cafein, a long stick of nicotine and a cold deep night ;) sorry i cannot finish reading your code, but if its working, then its working. Cheers!

ps: Agreed with Artemish though!

Simon:
well I have to say that as sinple as programming my DC-AC driver MCU was I prefered to do it in Basic as that's all i know and it was still a doddle, just a couple of registers to setup as I'd have to do in assembly and then about 10 lines of code, it would have been no more simple in assembly

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version