On Fri, Jul 12, 2013 at 11:38:46PM +0530, eCHIP wrote: > Byron Jeff wrote: > >On Fri, Jul 12, 2013 at 09:43:15PM +0530, eCHIP wrote: > >> > >I'm just trying to figure out why what seems like a embedded systems nov= ice > >is working on the most complicated way to implement simple timing delays= .. > >I'm not a novice and honestly I rarely use interrupts unless the main > >application has some computational complexity that cannot be broken up i= n a > >state driven way. > > He needs to keep that structure. I have a feeling that he is asked > to do it in the same format for something complicated future on. My question now is has the main loop finally been restructured to operate on an event basis. The interrupt has a 1 mS trigger. The ISR keeps a count of 200 (hopefully finally counting down instead of counting up as the last several iterations of his code has done) to generate a 200 mS trigger. What I'm interested in knowing is if that simply raises a flag to the main loop, or does the code actually try to process the nacent state machine in the ISR? The latter is a path to confusion. The ISR should be simple and fast: ISR: if TMR0IF is set: clear TMR0IF flag DECFSZ count200ms,F goto check_next_interrupt_flag raise the200ms flag in a GP register reset count200ms to 200 endif check_next_interrupt_flag: ; Whatever other interrupts that may need to = be processed. ... retfie In other words don't do any more than necessary in the ISR for the timer. Track the 200ms counter, raise a flag when it times out and reset the count. The main loop is structured the same except now it checks the200ms flag instead of the TMR0 flag: main_loop: if the200ms flag is set: clear the200ms flag DECFSZ state_timer,F goto check_next_main_flag change the state if state1: LED on set state_timer to 1 else if state2: LED off set state_timer to 150 endif check_next_main_flag: ; Whatever other flags the main loop needs to proce= ss ... goto main_loop Making the process event based keeps it simple. Look for an event. When it happens, clear the flag, do the work, reset any counters. If no event, then skip the code until the next loop iteration. This works if you have a system that needs to blink an LED, or one that needs to track multiple inputs and outputs with varying delays. In each case every interrupt triggered will cause all the flags to be checked. All the main loop flags are checked each iteration. This type of system is easily structured, easily extended, and reasonably responsive as long as the event processing isn't too terribly complicated. BAJ > > >Interrupts are important when you have multitasking, fast events that ne= ed > >to be processed, or implementing an OS with a system that implements > >protection levels. Few PIC projects fall into any of these categories, w= ith > >the last being impossible. > > His original code would not have solved anything for him. > > >EC has spent quite a bit of time asking what to do, I think the more > >important issue is to discuss why he's doing it. > > He needs a 200 mS ON LED and 30 seconds OFF LED wiht the PICmicro > running at 20 MHz. > > Cheers > > Ravi > > > > > >Just my two cents. > > > >BAJ > > > >> > >>Just sent him the code. > >> > >>Cheers > >> > >>Ravi > >> > >>Byron Jeff wrote: > >>>Since it's a count, you really do not need to store the value 300 in b= inary > >>>in a pair of 8 bit memory locations. Since it's a count you only need = to > >>>store two values whose product is 300 and whose values are each less t= han > >>>255. Examples are 150x2, 100x3, 75x4, 60x5, 30x10, 20x15. > >>> > >>>Once that is done you can then build a nested loop where the outer loo= p is > >>>decremented once for each timeout of the inner loop. Here is a complet= e > >>>example using 10 and 30 for the inner and outer loops: > >>> > >>>wait300: > >>> movlw .10 > >>> movwf outer > >>> movlw .30 > >>> movwf inner > >>>loop300: > >>> decfsz inner > >>> goto not_done_yet ; Loop has not timed out. keep waiting > >>> decfsz outer > >>> goto reset_inner ; Outer loop not timed out. Reset inner loo= p > >>> goto timed_out ; Loop has timed out. Do what you need > >>>reset_inner: > >>> movlw .30 ; Reset the inner timer count > >>> movwf inner > >>>not_done_yet: ; Do something else when no timeout > >>> goto loop300 ; And loop after that > >>> > >>>timed_out: ; Do code when you time out > >>> goto wait300 ; Reset the total count for next interation > >>> > >>>Of course you need to fill in the areas of not_done_yet and timed_out = with > >>>waht you want done if the timer has not timed out and when it does. Th= at is > >>>application dependent. > >>> > >>>Of course this loop still works if you store the binary 300 (1 in oute= r, 44 > >>>in inner) and you remove the reset_inner code. This counts down 44 the > >>>first time, and then the inner loop is 256 the second time. This also = gives > >>>a total of 300 counts. But the structure of the inner and outer loops = stay > >>>the same. BTW you can extend this to as many bytes as you need. 4 byte= s > >>>could give you counting loops up to 4.2 billion counts, which at a 5 M= hz > >>>tick count can delay up to 14 minutes. > >>> > >>>BAJ > >>> > >>> > >>>On Fri, Jul 12, 2013 at 08:06:16PM +0800, electronic.consultation.au@g= mail.com wrote: > >>>>I see, and then how can I reduce them ? > >>>> > >>>>could it be like this ? > >>>> > >>>>*movlw LOW .300 > >>>> movwf LedTimer > >>>> movlw HIGH .300 > >>>> movwf LedTimer+1 > >>>> > >>>>counter* * > >>>> Global counter ;Decrementing Sec's > >>>> BANKSEL LedTimer ;timer value > >>>> movf LedTimer,w ;for every counts > >>>> btfss STATUS,Z > >>>> decf LedTimer+1,f > >>>> return* > >>>> > >>>>Thank you > >>>>On 12/07/2013 7:36 PM, IVP wrote: > >>>>>Tag added > >>>>> > >>>>>>how can I enter .300 into LedTimer ? > >>>>>You might assign two registers, LedTimer_lo and LedTimer_hi > >>>>> > >>>>>The low( ) and high( ) operators do the division/remainder for you > >>>>> > >>>>>movlw low(.300) ;loads LedTimer_lo with 44 > >>>>>movwf LedTimer_lo > >>>>> > >>>>>movlw high(.300) ;loads LedTimer_hi with 1 > >>>>>movwf LedTimer_hi > >>>>> > >>>>>For 24-bit numbers this can be extended to > >>>>> > >>>>>movlw upper(.300) > >>>>>movwf LedTime_up ;if LedTimer_up is also present > >>>>> > >>>>>If the 300 is defined as a constant, this makes it easier to change > >>>>>in the following line rather than in the code > >>>>> > >>>>>LedTimer =3D .300 > >>>>> > >>>>>movlw low(LedTimer) > >>>>>movwf LedTimer_lo > >>>>> > >>>>>movlw high(LedTimer) > >>>>>movwf LedTimer_hi > >>>>> > >>>>>A register LedTimer can also be addressed as LedTimer+0, the next > >>>>>in memory as LedTimer+1 and so on, if that suits you better > >>>>> > >>>>>Joe > >>>> > >>>>-- > >>>>http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive > >>>>View/change your membership options at > >>>>http://mailman.mit.edu/mailman/listinfo/piclist > >>> > >> > >>-- > >>http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive > >>View/change your membership options at > >>http://mailman.mit.edu/mailman/listinfo/piclist > > -- Byron A. Jeff Chair: Department of Computer Science and Information Technology College of Information and Mathematical Sciences Clayton State University http://faculty.clayton.edu/bjeff -- http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .