Dmitry Kiryashov [zews at AHA.RU] says
Brief explanation. You are to run 10 tasks "simultaneously". 4 of them are counting pulses (or reading some buses if you would like to ;) while 6 others are some timing, converting information, sending and receiving RS232 stuff. Each slice of code has some execution time t1,t2,t3,... You can run everything in straight way in one loop when one follows by another but you will got total loop execution time exactly equal to t1+t2+t3+...+t9+t10 which is enormously huge ;) Forgot to mention that those pulses of course are longer than 10 sampling periods.
But you can reduce it significantly if will run each task separately in different time slots. Timer constantly generates required slots. Two different types of processes: constant rate happened and floating. Sampling ports and doing RS232 for instance are constant rate processes. Those should be sampled by every pass but finding edges can be scheduled for later. To reduce total time you also need to do finding edges in parallel for all 4 port pins. So you are just collecting information for analyzing it in later time. Total execution time in this case of every loop is no more than tC+tMAX where tC is time for driving/reading constant rate part of all process and tMAX is maximal execution time of longest process. Average execution time is reduced anyway. So applying this trick with accumulating first and executing later you can either do it faster or move this part of code into timer driven interrupt and forget about it (it becomes to be transparent and you don't care about low level programming anymore just playing with flags, buffers and semaphores on "high" level of art ;))
XORing the new value with the previous value yields a mask for all the changed bits. ANDing the result of that with the old value yields 1s for all the falling edges, and ANDing with the new value yields 1s for all the rising edges. These falling and rising edge masks can be accumulated by ORing them with previous versions if that's what you want to do.
Anding that mask with inverted current bit also produces falling flag. It's very easy to check. So you need to store only one variable (last one) and being exchanging it with a new one will have flags the same time.
I've been asked to design some trick to reduce code execution time for rise and fall edge events on some port pins. For instance we have two samples, previous byte x0 and current byte x1. Each holds inside value like aAbBcCdD. As a result of playing with vetical math I realized that:a) (x0^x1)&x1 = X0&x1 , which is "1" in case of rise event only b) (X0^X1)&X1 = x0&X1 , which is "1" in case of fall event only
where X0=!x0, Y0=!y0
Example:;... ;W holds 00ab00cd mov temp, W ;save it for or W, #$55 ;future usage add W, temp ;get aAbBcCdD xor W, prev ;put x1 byte to prev xor prev, W ;get x0^x1 byte into W and W, prev ;get edges a) and b) or edges, W ;detected edges ;...
We will get "rises detected" flags in 22.214.171.124. (case a) and "falls detected" flags in 126.96.36.199 (case b)
For instance edge can have a place somewhere within 10 samples period, so instead of reading and analizing it each time you can just accumulate it 10 times in edges cell and then analize it only ones. (don't forget to reset edges flags after that ;) Some clock saving anyway ;)
Probably someone can see another useful features of applying aAbBcCdD view of 4 bits variable.
How to convert 00ab00cd into aAbBcCdD? Bob Ammerman [RAMMERMAN at PRODIGY.NET] from RAm Systems says:
How about this:00ab00cd +00100010 --------------- 0aAb0cCd &01010101 ---------------- 0a0b0c0d +01010101 ---------------- aAbBcCdD
so, in code: [optimized for the SX by James Newton]mov temp, W add temp, #%00100010 and temp, #%01010101 rl temp
Dmitry Kiryashov [zews at AHA.RU] says
I got the same in two variations for pure W usage (without additional temp cell) and another one with temp cell usage.
And with temp cell:mov temp, W ;00ab00cd or W, #$55 ;01a101c1 add W, temp ;aAbBcCdD
Last one is useful for storing original W for futher usage.
|file: /Techref/scenix/lib/flow/int/edgedetect.htm, 4KB, , updated: 2004/6/10 14:40, local time: 2016/5/4 04:54,
|©2016 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?|
<A HREF="http://www.piclist.com/techref/scenix/lib/flow/int/edgedetect.htm"> Detecting riseing and falling edge events</A>
|Did you find what you needed?|
PICList 2016 contributors:
o List host: MIT, Site host massmind.org, Top posters @20160504 RussellMc, Neil, Richard Pope, Bob Blick, IVP, embedded systems, John Gardner, Jean-Paul Louis, alan.b.pearce, Isaac Marino Bavaresco,
* Page Editors: James Newton, David Cary, and YOU!
* Roman Black of Black Robotics donates from sales of Linistep stepper controller kits.
* Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters.
* Monthly Subscribers: Gregg Rew. on-going support is MOST appreciated!
* Contributors: Richard Seriani, Sr.
Welcome to www.piclist.com!