PIC program - Newby question

Thread Starter

Man_in_UK

Joined May 13, 2008
192
Many years ago I learned how to program a PIC to be a multifunction timer but the program was very basic. It would monitor a bank of switches and run a set time sequence depending on what switch was active.
It could only ever run one timer sequence at a time.

I would like to start another project but this one would involve running two routines independently of each other and I do not have a clue where to start.
(example: if button A is pressed, output a time sequence on pin 1, at the same time still monitor button B. If button B is pressed output a separate time sequence on pin 2)

Can anyone suggest any sample code I could study to learn such things?

Sorry for asking such a basic question but I have not kept up with my programming ...... I can't use the word "skills".
 

Markd77

Joined Sep 7, 2009
2,806
C or assembler? <ed> Which PIC? </ed>
It's fairly simple, instead of checking for the buttons, then going into a sequence of delays, have a short fixed time delay, maybe a millisecond.
Every time the delay is over;
check the buttons,
if a sequence has been started increase a counter for that sequence and change pin state when required.
 
Last edited:

Thread Starter

Man_in_UK

Joined May 13, 2008
192
Cheers Mark.
I was using MPLab to write the code, I think that would be assembler.
I have not yet decided what PIC to use yet as I have not got far enough to work out pin counts. I have to get my head round the code as that is the hard bit for me.

I understand what your saying about checking the switches. Trouble is, my limited skills only know how to run one timer at a time.
 

t06afre

Joined May 11, 2009
5,934
I guess your problem will call for using Interrupts. With the most critical part of the program placed in an Interrupt Service Routine(ISR). This is not as hard as many people think. Using assembler is OK. But you might also consider using C. It is no problem to get free versions. That will do more than good in any hobbyist project.
 

Markd77

Joined Sep 7, 2009
2,806
If you have the old code, that would give a better idea of what you are trying to do, if not the sequences would be good.
In the cold light of day I realise I was underestimating it slightly in my last post.
A way which would cover most cases is to have a variable for counting the 1ms intervals, a variable for counting which part of the sequence it is in, and a table containing times (number of intervals) for the sequence. Also a flag to indicate if the sequence is running.
If times were only needed to 1 second resolution, or the sequence was very simple it could be easier.
Example:
There would be one of these for each sequence, and these are 16 bit values which are slightly easier to use in C (it's easy enough in assembler). I've used 65535 (the maximum value for a 16 bit variable) as an end point, but it could be done other ways, like storing how long the table is and having a counter variable for it.
It could just as easily use 24 or 32 bit variables which would give much longer possible times at the expense of a larger table.

1 second on, 3 seconds off, 1 minute on, then off and sequence end.
Table: 1000, 3000, 60000, 65535

When a button is pressed the first value from the table is fetched into the time counter variable, Time_count.
Every time the 1ms is up Time_count is decreased by one and tested if it has reached zero. If it has then the Sequence_count is increased by 1, a new value for Time_count is fetched from the table and checked to see if it is the end of sequence marker, and the pin is toggled.
If Time_count isn't zero then it just checks if the other sequence is running, checks the buttons, waits 1ms, then repeats.
 

MMcLaren

Joined Feb 14, 2010
861
Something simple like this BoostC example excerpt could easily be converted to assembly language. The two independent timers are based on a 25 msec loop time which is used to sample and debounce the switches.

Regards, Mike

Rich (BB code):
   while(1)                     // loop forever
   { delay_ms(25);              // 25 msec debounce interval
  /*                                                            *
   *  K8LH parallel switch state logic ("new press" filter)     *
   *                                                            *
   *  swnew  ___---___---_____     sample active lo switches    *
   *  swold  ____---___---____     switch state latch           *
   *  swnew  ___-__-__-__-____     changes, press or release    *
   *  swnew  ___-_____-_______     filter out 'release' bits    *
   *                                                            */
     swnew = ~porta;            // sample active lo switches
     swnew &= 0b00000011;       // on the RA0 and RA1 pins
     swnew ^= swold;            // changes, press or release
     swold ^= swnew;            // update switch state latch
     swnew &= swold;            // filter out 'release' bits
  /*                                                            *
   *  decrement any running timers                              *
   *                                                            */
     if(timer0)                 // if timer 0 "running"
     { timer0--;                // decrement the timer
       if(timer0 == 0)          // if timed out
         porta.2 = 0;           // turn LED0 (RA2) "off"
     }                          //
     
     if(timer1)                 // if timer 1 "running"
     { timer1--;                // decrment the timer
       if(timer1 == 0)          // if timed out
         porta.3 = 0;           // turn LED1 (RA3) "off"
     }                          //
  /*                                                            *
   *  check switch inputs                                       *
   *                                                            */
     if(swnew.0)                // if sw0 (RA0) "new press"
     { if(timer0 == 0)          // if sw0 timer not running
       { timer0 = 1000/25;      // set timer to 1 second
         porta.2 = 1;           // turn LED0 (RA2) "on"
       }                        //
     }                          //
     
     if(swnew.1)                // if sw1 (RA1) "new press"
     { if(timer1 == 0)          // if sw1 timer not running
       { timer1 = 5000/25;      // set timer to 5 seconds
         porta.3 = 1;           // turn LED1 (RA3) "on"
       }                        //
     }                          //
   }                            //
 
Last edited:

Thread Starter

Man_in_UK

Joined May 13, 2008
192
Markd77.
I like the sound of some of that. I think I can use it as my maximum delay will only be 1 second. I will go away and make a start at getting some specifics, a flow diagram is an obvious start.
I should have really done a bit more homework before I came here asking questions. I will return shortly.

MMcLaren.
I like the idea of learning from others code but I can't understand that routine. When I played about in MPLab it all looked so different. I wish I could say that I knew what some of those commands are, but I'm afraid not.
 

W4GNS

Joined Dec 1, 2008
18
MMcLaren.
I like the idea of learning from others code but I can't understand that routine. When I played about in MPLab it all looked so different. I wish I could say that I knew what some of those commands are, but I'm afraid not.

Why not download a demo(free) of SourceBoost and compile/build K8LH's code, then have a look in the Lst file, which is assembler that SourceBoost generates.
 
Top