Author Topic: My first PIC program  (Read 16939 times)

0 Members and 1 Guest are viewing this topic.

Online Zero999Topic starter

  • Super Contributor
  • ***
  • Posts: 19521
  • Country: gb
  • 0999
My first PIC program
« on: September 16, 2010, 09:17:03 pm »
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: [Select]
;************************************************************************
;                                                                       *
;   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

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.
« Last Edit: September 16, 2010, 09:26:17 pm by Hero999 »
 

Offline scrat

  • Frequent Contributor
  • **
  • Posts: 608
  • Country: it
Re: My first PIC program
« Reply #1 on: September 17, 2010, 12:11:07 am »
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!
« Last Edit: September 17, 2010, 12:13:48 am by scrat »
One machine can do the work of fifty ordinary men. No machine can do the work of one extraordinary man. - Elbert Hubbard
 

Offline ArtemisGoldfish

  • Regular Contributor
  • *
  • Posts: 58
Re: My first PIC program
« Reply #2 on: September 17, 2010, 01:31:14 am »
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.
John, Hardware Technician, F5 Networks
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11634
  • Country: my
  • reassessing directives...
Re: My first PIC program
« Reply #3 on: September 17, 2010, 01:38:32 am »
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!
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: My first PIC program
« Reply #4 on: September 17, 2010, 05:59:52 am »
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
 

Online Zero999Topic starter

  • Super Contributor
  • ***
  • Posts: 19521
  • Country: gb
  • 0999
Re: My first PIC program
« Reply #5 on: September 17, 2010, 08:43:28 am »
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!

I know both BASIC and some assembler for the PC. I tried C but actually found it harder than assembler so didn't bother learning it.

I've only used assembly for MCUs and it's not hard but it did take a few complies before my code worked:

The first time the code didn't compile because MPASM doesn't like decimal points, I tried 10/0.64 which has to be represented as d'10'/d'0.064" which it didn't like, then I tried .10/.0.064 which didn't work either so I just did 156.

The second time it compiled but it didn't work because I made a mistake with the code to turn on the fan.

The third time there was a mistake in the delay code.

Finally it worked, I don't think the third attempt is too bad considering I've never written a PIC program before.

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

The program is much more complicated than it needs to be but the main reason for assembly is to learn something. I could probably pick up BASIC in 5 minutes but you never learn much doing things the easy way!

Is there a switch debouncing library in BASIC? Does it get done automatically? If so, it's something you'll never learn how to do and you'll probably never even learn about the problem of switch bounce. The problem is, when a switch is pressed or released it bounces on and off for a couple of ms afterwards generating a stream of pulses which are accepted by the MCU so your program needs to ignore them.

In my program debouncing is implemented using the timer: the switch has to be pressed or released for at least 10ms, before the program considers it to be in the new state.

For example, to wait of the switch to be activated the BASIC the code would be something like:

Code: [Select]
' switch on GP3 which is low when activated.

' Set up timer and GP3, I don't know how this is done in basic
set timer to TOS                  ' timer counts clock pulses
set timer prescaler  64           ' set prescaler so timer counts every 64µs
set GP3 as input

do
 do
  TMR0 = 0                        ' reset timer
 loop while GP3                   ' loop while switch is not pressed, GP3 is high
loop until TMR0 = 10/0.064        ' loop for 10ms

The assembly code is a little longer (mostly due to my comments) but it's not that bad,  it's only more difficult to understand because you need to know what each instruction actually does and what the registers are.

Code: [Select]
;***** 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

   ; 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

Another way of doing it is to check for the switch to be activated and simply wait 10ms until checking it again which is not quite so robust as a pulse of EMI might trigger it. My program also uses this method during the timing delay which also uses the timer - there's only one timer on the 12F509 and it can't be used for two different things simultaneously.

There are limitations to the 12F509 architecture which make the code longer and harder to understand, for example because addresses are limited to 9 bits, the 1024 words of program memory is split into two pages so to do a long jump the correct page has to be selected first e.g.

Code: [Select]
pagesel start
goto start ; jump to main code

The call instruction is limited to 8 bits so all subroutines need to appear at the start of a memory page i.e. the first 256 words so you need to do things like:

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

;***** Subroutine vectors
subroutine ; wait for switch to be released
        pagesel subroutine_R
        goto    subroutine_R   

;***** MAIN PROGRAM
MAIN CODE

;***** Initialisation
start
; your program code here
        call subroutine

subroutine_R
; the code for the subroutine goes here
        retlw

subroutine is called, which just selects the correct page and jumps to subroutine_R which is where the real code is.

Although I didn't need to worry about any of this, my program is under 256 words, I still did all of that as it's good practise and my program would break if it exceeded 256 words.

If you're using BASIC or C, this is all done for you so you never really learn how the MCU works.
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: My first PIC program
« Reply #6 on: September 17, 2010, 12:31:51 pm »
I think there is a switch debounce in mikroe basic but really you don't need it, you looking at it the wrong way: the MCU will not normally hang about for 10mS to see if the switch is pressed, if the program is a loop like most are in the time you press the switch it probably runs at least once so a fail contact is not an issue and once hooked it gets on with it's thing without looking at the switch until told to again. I'm sure there are som instances where you need a proper switch debounce and even manually easily done in basic. Basic still requires much registry setup so you still need to know about the pic setup it just means you can write you code faster and it's easier to review months or years later as what it does is often quite obvious
 

Online Zero999Topic starter

  • Super Contributor
  • ***
  • Posts: 19521
  • Country: gb
  • 0999
Re: My first PIC program
« Reply #7 on: September 17, 2010, 01:09:40 pm »
This is an example where debouncing is required, any program which is dependant on a switch changing state more than once will require some form of debouncing.

Let's look at the basic program function again.

1 Wait for the switch to be pressed.
2 Wait until the switch is released.
3 Turn on fan.
4 Wait for 10 minutes or until the switch is pressed again.
5 Turn off fan
6 Wait for switch to be released.
7 Go back to 1

Suppose the switch generates two pulses with a 1ms gap between each other when it's pressed once, how will it effect the program?

The fan will quickly turn on and off before the motor has time to start. In reality the switch will probably bounce more than once so the fan will turn on and off until the switch finishes bouncing: the motor might turn on or it could remain off. The same could happen when the fan is on: it might turn off or it could remain on.

It you don't believe me, write a simple program to simulate an on/off switch, when the push button is pressed, the LED turns on, when it's pressed again, the LED turns off. You'll find that the LED won't always turn on or turn off when the switch is pressed. Add a 10ms delay somewhere in the loop and it will be much better but could still be effected by EMI, add a counter routine and it'll be perfect. You'll have the same problem with a divide by 2 counter built with the CD4013, the problem of switch bounce has existed long before MCUs, it probably first arose with the first state machines constructed from valves, which were fast enough to respond to switch bounce.

 

Offline jahonen

  • Super Contributor
  • ***
  • Posts: 1054
  • Country: fi
Re: My first PIC program
« Reply #8 on: September 17, 2010, 02:17:51 pm »
Assembly is superficially simple for simple programs (like shown here), but C advantage quickly becomes clear when one does something more complicated applications (something which requires larger than 10-16F PIC). One can try writing something like serial terminal command line parser (have done that, string compare is just a pain in PIC asm, or just accessing string constants) or high-level protocol stack (TCP/IP, USB device classes etc.) with assembler. Not very clear anymore.

Regards,
Janne
 

Online Zero999Topic starter

  • Super Contributor
  • ***
  • Posts: 19521
  • Country: gb
  • 0999
Re: My first PIC program
« Reply #9 on: September 19, 2010, 05:16:40 pm »
I hated the way C handles strings: BASIC is much easier to work with.

The x86 has instructions targeted specifically at handling strings but I can see it being a nightmare with PICs and almost impossible with baseline PICs so you're probably right.

Anyway, here's the latest version of the program. I've changed it to remain on contentiously if the switch is pulled again 500ms after it's first been pulled.

The operating is as follows:

Pull switch once, fan is on until either delay expires or it's pulled again.
Pull switch twice within 500ms, fan is on until it's pulled again.

I'm embarrassed to say, t actually took me awhile to get this working. What I hadn't realised is that the retlw instruction doesn't update the zero flag so the btfss instruction following the call wasn't having any effect. What was worse was that the program was working as it was before so it appeared that the switch being pulled whilst delay_sw was working. What was happening was that the switch was being held down for at least 40ms each time so the delay_sw was executing in 10ms each time causing the delay to expire instantly.

This was fixed by adding iorlw 0 after each call but I decided it would be better to add bsf or bsc STATUS,Z before the retlw instruction so the status register is modified by the delay_sw routine.

Code: [Select]
;********************************************************************************
; *
; 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. If the switch is pulled again within 500ms, the *
; fan stays on continiously, until 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

wait_dn ; wait for switch to be pressed
pagesel wait_dn_R
goto wait_dn_R

delay_sw ; wait for switch press or delay to expire
pagesel delay_sw_R
goto delay_sw_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:
call wait_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   
movlw d'50' ; delay in multiples of 10ms, 500ms = 50*10ms
call delay_sw ; is the switch pulled again within the next 500ms?
btfsc STATUS,Z ; skip next goto if switch pressed (non-zero)
goto main_delay ; if switch not pressed goto main delay
call wait_up ; otherwise wait until switch is released
call wait_dn ; wait until switch is pressed again
goto turn_off ; when switch is pressed again turn off fan
main_delay
; long delay: waits until the switch is pulled or the time delay is over
movlw d'4' ; delay is in multiples of 2.5 seconds
movwf dc1
delay_loop
movlw d'250' ; waits 2.5s = 250*10ms, switch scanned every 10ms
call delay_sw ;
btfss STATUS,Z ; skip next goto if switch not pressed (non-zero)
goto turn_off ; if non-zero turn fan off
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

; wait until switch pulled, debounce using timer0:
wait_dn_R
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 d'156' ; (156=10ms/64us)
btfss STATUS,Z ; if not, continue checking button
goto chk_dn
retlw 0

; wait until switch is pressed or time delay has expired
; delay is in multiples of 10ms and is stored in the working register
; -1 is returned if switch (scanned every 10ms) is pressed otherwise 0
; the zero flag in the status register is set or cleared accordingly
delay_sw_R
movwf dc2
delayx ; 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
bcf STATUS,Z
btfss GPIO,3 ; check for switch pull (GP3 low)
retlw -1 ; if switch pulled, exit delay and pass a -1
decfsz dc2,f ; decrement counter, skip goto, if zero
goto delayx ; if counter is non-zero loop
bsf STATUS,Z
retlw 0 ; if timer has expired, return zero

END
 

Offline Thermal Runaway

  • Contributor
  • Posts: 48
Re: My first PIC program
« Reply #10 on: September 20, 2010, 01:47:27 pm »
Congratulations on your first PIC program! My first program was literally just to light an LED!!!

I learned to program PICs in assembly originally.  Prior to that I'd done some stuff with 6502, Z80 and 68000 processors in assembly.

These days I rarely find an application for assembly to be honest.  I almost exclusively use C as my programming language of choice.  You mentioned that you didn't think it was worth learning C - I would recommend that you reconsider this if you intend to write larger more complex programs in the future.  A large task can be accomplished much more quickly in C than it can in Assembly, and the end result is a more intelligable and highly portable piece of code.

If you only intend to play around with small tasks and experiment with quite simple problems then I agree with your decision not to bother learning C.  But if you want to build on your skill and tackle bigger problems, then C is the way to go in my opinion.  C is a tough learning curve, but I think it's worth it.

Brian.
--------------------
Electronics Engineer, Land Rover enthusiast, Amiga Computer fan and general GEEK
--------------------
 

Online Zero999Topic starter

  • Super Contributor
  • ***
  • Posts: 19521
  • Country: gb
  • 0999
Re: My first PIC program
« Reply #11 on: September 20, 2010, 02:41:04 pm »
You're probably right, I'll probably give C another go at some stage but I'll stick with assembler for now because it forces me to learn the hardware.

I don't think much of MPASM and preferred NASM because it has better macro support, context stack and local labels enabling one to cool things like:

Code: [Select]
Subroutine_1
.loop
some code here
goto .loop

Subroutine_2
.loop
some code here
goto .loop

The trouble with NASM is it's x86 only.

If there's an MCU assembler that can do that and is preferably free, I'd like to know.
 

Offline Thermal Runaway

  • Contributor
  • Posts: 48
Re: My first PIC program
« Reply #12 on: September 20, 2010, 04:10:37 pm »
I agree that it's worth familiarising yourself with assembly language (and, hence, the microcontroller architecture) before moving on.  It's the longer way around, but it's definitely the best way to learn.

Sorry I can't help you with assembler alternatives.  I've always liked and used the MPLAB dev environment, although I don't use their C compiler (I use a third party compiler within the MPLAB environment). 
These days, even when I do write assembly, it's usually as part of a bigger C program so I just mix it in with my C code and let my C compiler take care of it.

Good luck!

Brian
--------------------
Electronics Engineer, Land Rover enthusiast, Amiga Computer fan and general GEEK
--------------------
 

Online Zero999Topic starter

  • Super Contributor
  • ***
  • Posts: 19521
  • Country: gb
  • 0999
Re: My first PIC program
« Reply #13 on: September 20, 2010, 05:32:24 pm »
Sorry I can't help you with assembler alternatives.  I've always liked and used the MPLAB dev environment,
Have you used anything else before?

I like the IDE, it's just the assembler which I think is lacking in features, I think if I hadn't used any other assembler then I'd probably like it, but features wise, going from NASM to MPASM is like going from Firefox 3.6 to Internet Explorer 6.

NASM's macros were so good it could be made to be half way between a high level language and assembly, here's an example from the manual:
http://www.nasm.us/doc/nasmdoc4.html

Code: [Select]
%macro if 1
    %push if
    j%-1  %$ifnot
%endmacro

%macro else 0
  %ifctx if
        %repl   else
        jmp     %$ifend
        %$ifnot:
  %else
        %error  "expected `if' before `else'"
  %endif
%endmacro

%macro endif 0
  %ifctx if
        %$ifnot:
        %pop
  %elifctx      else
        %$ifend:
        %pop
  %else
        %error  "expected `if' or `else' before `endif'"
  %endif
%endmacro

      cmp   ax,bx ; compare registers ax and bx, subtracts bx from ax, updates the flags (status register) but doesn't store the result
        if ae
           cmp   bx,cx
             if ae ; if above or equal
                 mov   ax,cx
             else
                 mov   ax,bx
             endif
        else ; otherwise
           cmp   ax,cx
             if ae
                 mov   ax,cx
             endif
        endif

The same sort of thing can be done to make do, loop and exit structures which I used pretty frequently.

 

Offline Jon Chandler

  • Frequent Contributor
  • **
  • Posts: 539
    • Throw Away PIC
Re: My first PIC program
« Reply #14 on: September 21, 2010, 04:25:39 am »
Basic works well for many applications including some complex stuff.

The best basic compilers I have found are Swordfish Basic and Proton/Amicus.  Swordfish works only with 18F-series parts, and the Special Edition is free with extremely generous limits.  A free version of Proton Basic is available as Amicus - it's the full version of Proton, but limited to use with the 18F25k20 micro.  The paid version of Proton supports 10F - 18F series parts.

There's a brief discussion here, and a variety of helpful information and guidance here.



Jon
 

Online Zero999Topic starter

  • Super Contributor
  • ***
  • Posts: 19521
  • Country: gb
  • 0999
Re: My first PIC program
« Reply #15 on: September 21, 2010, 07:28:51 am »
Basic works well for many applications including some complex stuff.

The best basic compilers I have found are Swordfish Basic and Proton/Amicus.  Swordfish works only with 18F-series parts, and the Special Edition is free with extremely generous limits.  A free version of Proton Basic is available as Amicus - it's the full version of Proton, but limited to use with the 18F25k20 micro.  The paid version of Proton supports 10F - 18F series parts.

There's a brief discussion here, and a variety of helpful information and guidance here.

I don't like the proprietary nature of any of the products linked to. I think this is why I'll learn C as a first language for microcontrollers because it's standardised and I've never really done it before. I already know BASIC and don't see the point in learning several variants of it for MCUs.

At the moment I'll just see if there's a better assembler out there. I think someone should modify NASM for PICs but I accept it won't be an easy task.

EDIT:
For my next PIC project, I think I'll do a clock, a timer with a 7 segment LED display or something like that. I'll keep to the low end range of PICs for now and might even use a PIC16F54 as I have a few in my junk box.
« Last Edit: September 21, 2010, 07:30:50 am by Hero999 »
 

Offline darrylp

  • Regular Contributor
  • *
  • Posts: 127
  • Country: gb
Re: My first PIC program
« Reply #16 on: November 22, 2010, 09:38:26 pm »
GC basic ( great cow basic )  is open source,  and works well.

having access to the source, means you can see how its working, and can modify itas needed.
 

Offline scrat

  • Frequent Contributor
  • **
  • Posts: 608
  • Country: it
Re: My first PIC program
« Reply #17 on: November 22, 2010, 10:59:19 pm »
With C you have the possibility of going up to a high level (without loosing a low-level view), and portability is a real thing. For example, I used the same pieces of code (apart from some minor changes due to numeric types and optimized functions) for motor control on a Texas C2000 fixed-point, a PowerPC floating point and an Infineon Tricore with f.p.u. too.
I doubt Basic can be worth for an EE, while perhaps an hobbist can quickly start developing with it.
One machine can do the work of fifty ordinary men. No machine can do the work of one extraordinary man. - Elbert Hubbard
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: My first PIC program
« Reply #18 on: November 23, 2010, 06:28:14 am »

I doubt Basic can be worth for an EE, while perhaps an hobbist can quickly start developing with it.

that does seem to sum up the situation very well
 

Online Zero999Topic starter

  • Super Contributor
  • ***
  • Posts: 19521
  • Country: gb
  • 0999
Re: My first PIC program
« Reply #19 on: February 01, 2011, 01:17:59 am »
It's been awhile but I've decided to continue with the project.

Here's the schematic so far, I've not update the code yet but I thought I'd ask people their opinions of the schematic before going any further. I decided to go for a TRIAC and implement zero crossing. I decided using a relay and a transformer would be far too power hungry. The PIC12D509 uses a maximum of 400µA at 2.5V and the TL431 requires 1mA to regulate properly. I've simulated the capacitive power supply, at 230VAC the total RMS current draw is 3.44mA, the current through fluctuates between 1.09mA and 1.4mA with a constant current load of 400µA which simulates the MCU. The internal pull-ups will be disabled as I think they'll draw too much power.

Now here is where I ask a question: look at how I've configured the TRIAC, is it all right?

The TRIAC is the TICP206 which requires a trigger current of 10mA which I know is too high for the transformerless power supply but it it should only take 10mA for a few µs as once triggered, it will shoot up, cutting the gate off. The trouble is I'm not sure this will also happen when the mains goes negative. Will it blow the MCU and TRIAC gate or just draw too much current?

If this is a problem I can change to the traditional low side appoach and set the MCU to only provide a pulse for a few µs after each zero crossing.

What about the zero crossing input? Is it true that the PIC has internal protection diodes and 1M resistor will limit the current?

http://www.datasheetcatalog.org/datasheet/PowerInnovations/mXtwqqx.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/41236E.pdf
« Last Edit: February 01, 2011, 01:32:53 am by Hero999 »
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11634
  • Country: my
  • reassessing directives...
Re: My first PIC program
« Reply #20 on: February 01, 2011, 04:19:16 am »
1) i dont see the triac, but maybe its my noob. i guess its the D4 and D5
2) mcu pin connected to mains? seems dangerous to me, but then maybe i miss something.
someone else could advice better.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline scrat

  • Frequent Contributor
  • **
  • Posts: 608
  • Country: it
Re: My first PIC program
« Reply #21 on: February 01, 2011, 12:50:46 pm »
The 1M resistor is a quite standard way to sense voltage, AFAIK (I haven't done this yet). If you're worried about overvoltage, a diode or zener costs very little, isn't it?

I'd change to the low-side, since otherwise the MCU won't be able to turn on the triac on one of the two halfwaves, and in the opposite case gate voltage will be very high.

If you calculate the voltage drop on the 100uF cap for giving the gate charge required (at least 10mA for 20us), it results only 2mV. With the your gate resistance and diode current should be a higher ( (2.5-0.6) / 82 = 23mA), but voltage drop will be negligible too (provided that the on pulse is sufficiently narrow).

One machine can do the work of fifty ordinary men. No machine can do the work of one extraordinary man. - Elbert Hubbard
 

Online Zero999Topic starter

  • Super Contributor
  • ***
  • Posts: 19521
  • Country: gb
  • 0999
Re: My first PIC program
« Reply #22 on: February 01, 2011, 05:47:43 pm »
I'd change to the low-side, since otherwise the MCU won't be able to turn on the triac on one of the two halfwaves, and in the opposite case gate voltage will be very high.
You could be right. I'm not sure about this. I certainly agree with you about the gate voltage being really high when the mains is negative, but I don't see why it won't trigger. I'd rather have high side, I might couple it with a ferrite bead transformer (I know this works) which will allow me to use full wave rectification but it might be too much bother. I definitely won't build it without doing some experiments first at lower voltages. I'm going to bread board it running from a 12V transformer with the ballast capacitor and resistors replaced with suitable values, then when I assemble it on a PCB, I'll use an isolation transformer until I'm sure it's working as expected.

Quote
If you calculate the voltage drop on the 100uF cap for giving the gate charge required (at least 10mA for 20us), it results only 2mV. With the your gate resistance and diode current should be a higher ( (2.5-0.6) / 82 = 23mA), but voltage drop will be negligible too (provided that the on pulse is sufficiently narrow).
I think you missed the diode in series with the gate and that the gate voltage drop is 0.9V@10mA, I make it (2.5-0.7-0.9)/82 = 11mA but you're right, it doesn't matter as long as the pulse is narrow enough.

Oh and do you think I'll need to add a snubber network or MOV? With it zero voltage switching I hope the back EMF won't be too bad.
« Last Edit: February 01, 2011, 05:49:36 pm by Hero999 »
 

Offline osmosis321

  • Regular Contributor
  • *
  • Posts: 64
Re: My first PIC program
« Reply #23 on: February 02, 2011, 05:30:42 pm »
I'm one of those that prefers C in general, but am quite happy to mix in a bit of assembly when there's a clear benefit to be had by doing so.  The better the C compiler, the fewer those times occur.
 

Offline scrat

  • Frequent Contributor
  • **
  • Posts: 608
  • Country: it
Re: My first PIC program
« Reply #24 on: February 03, 2011, 11:38:34 am »
I'd change to the low-side, since otherwise the MCU won't be able to turn on the triac on one of the two halfwaves, and in the opposite case gate voltage will be very high.
You could be right. I'm not sure about this. I certainly agree with you about the gate voltage being really high when the mains is negative, but I don't see why it won't trigger.
On a positive halfwave you'll be trying to impose a positive gate current using 2.5V on the gate but having a high voltage on the lower anode (the motor is running and has its B-EMF). Since the MCU is fed by a supply referenced to neutral, this won't work, IMHO.

Quote
If you calculate the voltage drop on the 100uF cap for giving the gate charge required (at least 10mA for 20us), it results only 2mV. With the your gate resistance and diode current should be a higher ( (2.5-0.6) / 82 = 23mA), but voltage drop will be negligible too (provided that the on pulse is sufficiently narrow).
I think you missed the diode in series with the gate and that the gate voltage drop is 0.9V@10mA, I make it (2.5-0.7-0.9)/82 = 11mA but you're right, it doesn't matter as long as the pulse is narrow enough.
I missed the gate voltage, quite a big mistake :)

Oh and do you think I'll need to add a snubber network or MOV? With it zero voltage switching I hope the back EMF won't be too bad.
I'm not really experienced, but I think a little RC snubber would be a good thing there, since you don't know how current-voltage phase shift will be under all conditions.
This could be useful, I'll take a look, since I'd like to learn it too: http://www.st.com/stonline/books/pdf/docs/6785.pdf
« Last Edit: February 03, 2011, 11:42:36 am by scrat »
One machine can do the work of fifty ordinary men. No machine can do the work of one extraordinary man. - Elbert Hubbard
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf