some help/advice with a program with 16F1789

Enhanced mid-range devices. PIC12F1xxx and PIC16F1xxx

some help/advice with a program with 16F1789

Postby stef_r » Sat Aug 16, 2014 8:33 pm

Hi all,

I have written a small program in assembler which works almost perfect... Almost.....

I want the program to monitor the switch at input RB0.
As soon as the button has pressed AND released, a LED at RE2 must lit for about 800mSec.
After that, the LED turns off and the program repeats.

So far, this is exactly what the program does!
Code: Select all
;****MAIN PROGRAM
MAIN_LOOP
    ;wait for button press @ RB0
    banksel PORTB
    wait_dn btfsc PORTB,RB0        ; skip next instruction if RB0 => LOW
    goto wait_dn
   
    ;wait for button release
    banksel PORTB
    wait_up btfss PORTB,RB0        ; skip next instruction if RB0 => HIGH
    goto wait_up

    ;turn on LED @ RE2
    banksel LATE
    bsf LATE,RE2

    ;delay 800mSec
    movlw .80
    pagesel delay10
    call delay10
    pagesel $

    ;turn off LED @ RE2
    banksel LATE
    bcf LATE,RE2
 
    ;repeat forever
    goto MAIN_LOOP

END


Now, the main 'failure' of this program is that, when the LED is on, if the button is pressed within the 800mSec delay, nothing happends because the program is in the delay routine.
What I want is that if the LED is on, and if the button is pressed before the LED is turned off, the LED is switched off and the program waits unti the button is released again.

I think I know the answer to this and that is to use interrupts, right?
So, I have my switch monitoring in the MAIN_LOOP and the delay function as ISR, right?
Any tips or tricks are welcome!
stef_r
 
Posts: 15
Joined: Thu Aug 14, 2014 12:16 pm
PIC experience: Experienced Hobbyist

Re: some help/advice with a program with 16F1789

Postby Tom Maier » Sat Aug 16, 2014 9:06 pm

You can simplify that by just scanning for the input button inside your 800 msec delay loop.
User avatar
Tom Maier
Verified identity
 
Posts: 179
Joined: Mon May 26, 2014 2:37 pm
PIC experience: Professional 5+ years with MCHP products

Re: some help/advice with a program with 16F1789

Postby stef_r » Sat Aug 16, 2014 9:36 pm

Hmmmm.....
How can I agieve that?
Do I have to do that inside the 'delay10' routine?
The code of this routine is:

Code: Select all
delay10                         ; delay = 2+Wx(223+1023+4)-1+4
        banksel dc1             ;   = W x 1250 + 5 cycles
        movwf   dc2             ;   = W x 10.0 ms @ 8 us/cycle
dly3    movlw   .74             ; inner loop 1: 2 + 74 x 3 - 1
        movwf   dc1             ;   = 223 cycles
dly1    decfsz  dc1,f           
        goto    dly1                         
dly2    nop                     ; inner loop: 256 x 4 - 1
        decfsz  dc1,f           ;   = 1023 cycles
        goto    dly2 
        nop
        decfsz  dc2,f           ; end outer loop
        goto    dly3
       
        return
       

        END


Can / should I use something like the btfsc instruction?
stef_r
 
Posts: 15
Joined: Thu Aug 14, 2014 12:16 pm
PIC experience: Experienced Hobbyist

Re: some help/advice with a program with 16F1789

Postby Tom Maier » Sat Aug 16, 2014 10:33 pm

You seem to be struggling to learn the basics of assembly programming all by yourself. That's a pretty brave thing to do, but I think you will get frustrated and quit.

This company offers FREE tutorials on assembly language programming and it is written for beginners.
http://www.gooligum.com.au/tutorials.html

And, no I have no association with them. I just like the layout of their materials.

At this point in your learning you need to be guided step-by-step. Later on, after completing several of these tutorial chapters, you should be able to strike out in your own direction. Then you can start to fly solo. :D
User avatar
Tom Maier
Verified identity
 
Posts: 179
Joined: Mon May 26, 2014 2:37 pm
PIC experience: Professional 5+ years with MCHP products

Re: some help/advice with a program with 16F1789

Postby Olin Lathrop » Sun Aug 17, 2014 1:47 am

stef_r wrote:Now, the main 'failure' of this program is that, when the LED is on, if the button is pressed within the 800mSec delay, nothing happends because the program is in the delay routine. What I want is that if the LED is on, and if the button is pressed before the LED is turned off, the LED is switched off and the program waits unti the button is released again.


You got a very basic program working. That's good. However, as you are now seeing, such a simplistic firmware architecture doesn't lend itself well to various nuances. Here is what I would do:

1 - Use timer 2 to set up a periodic 1 ms interrupt. This is a good thing to learn, since it will be useful for most PIC projects. It's pretty rare that I don't have some sort of regular clock interrupt in a PIC project, usually 1 ms period (1 kHz frequency).

Your interrupt should do two things (other than the obvious of clearing the interrupt condition). First, it should debounce the button. Only this interrupt should ever look at the button line directly. The output of this piece of logic is a global flag that indicates whether the debounced state of the button is up or down. The rest of the system only looks at that flag to get the current button state.

To debounce the button, you compare its immediate state with the current debounced state. When they are the same, you set a counter to 50. When they are different, you decrement the counter and declare the instantaneous state to be the new debounced state, and then also reset the counter to 50. This means that the button must be seen in a new state for 50 consecutive interrupts before it becomes the official debounced state. 50 ms is a good debounce time. It is longer than just about all buttons bounce, but still short enough so that humans don't perceive a delay, or care if they do.

Second, it should decrement a 8 bit counter every 5 ms unless it is already 0, and then light the LED if the counter is non-zero after the decrement, and turn it off if the counter is 0. The rest of the system does not drive the LED line directly. It only writes a value to the counter, and the interrupt routine upates the LED on the next 5 ms clock tick accordingly. To turn the LED off, you write 0 to the counter. To turn it on for 800 ms, you write 160 to the counter. The rest happens by interrupt magic, as if by technology.

2 - The rest of the logic is handled by a main event loop. Such a loop never goes down a rathole, like your code when the LED is lit. Instead, you break the task down into small simple events that can be handle instantaneously. This may require a few flags indicating overal system operating state. Each event is then checked and handled in isolation, and such handling is "quick". The main event loop just runs in a loop checking for each event that it might need to handle, then goes back and does it all again. Actually, I usually add a small wrinkle, which is to jump back to the main event loop after actually handling a event (as apposed to finding the conditions not met and not handling it). This means your events have priorities, with higher priority the earlier a event is checked in the loop.

For example, the condition for one event is (LED on) and (button pressed). In that case, turn the LED off and clear the flag that says the LED is on.

This overall firmware architecture (clock tick interrupt and main event loop) is very worth learning and creating some template code to start other PIC projects with in the future. It is also a good mental exercise to break seamingly long tasks into a small set of immediately executable events. This is how a small PIC can appear to be doing various things independently but at the same time.
User avatar
Olin Lathrop
Verified identity
 
Posts: 48
Joined: Fri May 30, 2014 3:38 pm
Location: Littleton, MA USA
PIC experience: Professional 5+ years with MCHP products

Re: some help/advice with a program with 16F1789

Postby stef_r » Sun Aug 17, 2014 6:52 am

Tom Maier wrote:This company offers FREE tutorials on assembly language programming and it is written for beginners.
http://www.gooligum.com.au/tutorials.html


Ha, that's a good one!
I allready was familiar with these tutorials and honestly, I find them very great and usefull!
I even have bought the complete series of them! (I was amazed by how little money they ask for such good material!)

Since my only previous experience with PIC programming was the PICBasic language, I'm all new with assembler but these tutorials do work great for me.
(As I come along and finisch a working lesson, I try to alter the program and see what it does; change some timing delays, try something else, etc..)
This way I hope to get a grounded understanding on how these Enhanced Mid-Range devices really work.

As for my work, I have a project running which I started out in my private time but now has the approval of my boss to get a working version so we can run some tests with it.
In the mean time, I'm trying to get as much time available for learning the assembler language.
And there lays also a 'problem' for me... I need the timme to get familiar with the assembler language and get some experience with it, but on the other hand, my boss wants to see some real-working example by yesterday... :?

Olin Lathrop wrote:You got a very basic program working. That's good. However, as you are now seeing, such a simplistic firmware architecture doesn't lend itself well to various nuances. Here is what I would do:

1 - Use timer 2 to set up a periodic 1 ms interrupt. This is a good thing to learn, since it will be useful for most PIC projects. It's pretty rare that I don't have some sort of regular clock interrupt in a PIC project, usually 1 ms period (1 kHz frequency).


Is there a reason why to use Timer2 and not 'just' Timer0???
I assume they are both working the same way as they are both 8-bit timers?
stef_r
 
Posts: 15
Joined: Thu Aug 14, 2014 12:16 pm
PIC experience: Experienced Hobbyist

Re: some help/advice with a program with 16F1789

Postby ric » Sun Aug 17, 2014 1:42 pm

stef_r wrote:...
Is there a reason why to use Timer2 and not 'just' Timer0???
I assume they are both working the same way as they are both 8-bit timers?

Don't assume anything. Just look in the datasheet.
In particular, compare the block diagram of Timer 0 (Figure 22-1 in the datasheet), and Timer 2 (Figure 24-1).
Note that only Timer-2 has a PR register. Read what that register does, and you'll see why Timer 2 is very useful for a regular interrupt with little effort.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 453
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: some help/advice with a program with 16F1789

Postby Olin Lathrop » Mon Aug 18, 2014 3:08 am

I wrote:To debounce the button, you compare its immediate state with the current debounced state. When they are the same, you set a counter to 50. When they are different, you decrement the counter and declare the instantaneous state to be the new debounced state, and then also reset the counter to 50.


Oops. I must have been typing too fast and didn't notice I messed up the description. When the debounced and instantaneous states of the button differ, then you decrement the counter. Only if the counter reaches 0 do you then consider the instantaneous state the new debounced state.

The point still is that the button must be in a new state for 50 consecutive interrupts (50 ms) before that is considered the official debounced state.

stef_r wrote:Is there a reason why to use Timer2 and not 'just' Timer0???

Yes, as should be obvious since I bothered to say timer 2 specifically instead of a timer. This is not only a dumb question, but a stupid one too.

Learn to ask what you really want to know. A much better question would have been why timer 2 is more suited to the task. There is a good reason, but no point in explaining since you don't seem to care. A even better course of action would have been to look at the datasheet and see if you can spot something that makes timer 2 more appropriate for the task, then ask about details of that if it's still not clear.
User avatar
Olin Lathrop
Verified identity
 
Posts: 48
Joined: Fri May 30, 2014 3:38 pm
Location: Littleton, MA USA
PIC experience: Professional 5+ years with MCHP products

Re: some help/advice with a program with 16F1789

Postby Roche » Mon Aug 18, 2014 9:12 am

The only stupid question is the one that doesn't get asked...

Olin Lathrop wrote:
I wrote:To debounce the button, you compare its immediate state with the current debounced state. When they are the same, you set a counter to 50. When they are different, you decrement the counter and declare the instantaneous state to be the new debounced state, and then also reset the counter to 50.


Oops. I must have been typing too fast and didn't notice I messed up the description. When the debounced and instantaneous states of the button differ, then you decrement the counter. Only if the counter reaches 0 do you then consider the instantaneous state the new debounced state.

The point still is that the button must be in a new state for 50 consecutive interrupts (50 ms) before that is considered the official debounced state.

stef_r wrote:Is there a reason why to use Timer2 and not 'just' Timer0???

Yes, as should be obvious since I bothered to say timer 2 specifically instead of a timer. This is not only a dumb question, but a stupid one too.

Learn to ask what you really want to know. A much better question would have been why timer 2 is more suited to the task. There is a good reason, but no point in explaining since you don't seem to care. A even better course of action would have been to look at the datasheet and see if you can spot something that makes timer 2 more appropriate for the task, then ask about details of that if it's still not clear.
Roche
 
Posts: 30
Joined: Fri Jul 11, 2014 12:35 pm
PIC experience: Professional 5+ years with MCHP products

Re: some help/advice with a program with 16F1789

Postby Ian.M » Mon Aug 18, 2014 11:11 am

OTOH the requirement for a periodic interrupt may not include accurate timekeeping with a power of 10 time interval. Other timers can be used if you need to reserve Timer 2 for PWM, either accepting the inevitable inaccuracy of reloading a timer with an active prescaler, or simply using the natural overflow period of a free running timer, and keeping track of the elapsed time in units of the rollover period.

Its also possible to use Timer 1 + a CCP module special event trigger for precision time keeping.
Ian.M
Verified identity
 
Posts: 94
Joined: Wed May 28, 2014 12:47 am
PIC experience: Professional 1+ years with MCHP products

Next

Return to 14-Bit Core (enhanced)

Who is online

Users browsing this forum: No registered users and 2 guests

cron