Maker Pro
Maker Pro

Reading PIC ports

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
The code in post 5 looks good to me, and should be very time efficient as it has unrolled the loop(s). It may not be space efficient.

I didn't check to see if the port is read once at the beginning of if each bit is tested "live" from the port. In the latter case there is a potential problem if the value changes.

And you are right, only 4 bit tests are required (which seemed pretty obvious since there are 4 bits)

What may have confused Colin is that the code contains many more than 4 compares, but that the flow through them ensures that only 4 of them are required.

My gut feeling is that Colin simply didn't read the code (because I'm assuming he wouldn't so badly mis-read it)
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
Main CLRF PORTB

movf portA,0 ;put the port value into w
movwf tempPort ;put port value into a file
MOVLW 0Fh ;to only use the lower nibble
ANDWF tempPort,1 ;only lower nibble remains in tempPort

clrf w
subwf tempPort,0
btfss 03,2 ;tempPort is zero
goto $+4
movlw b'00111111' ; "0" -|F|E|D|C|B|A
movwf portB
goto Main

decfsz tempPort,1
goto $+4
movlw b'00000110' ; "1" -|-|-|-|C|B|-
movwf portB
goto Main

decfsz tempPort,1
goto $+4
movlw b'01011011' ; "2" G|-|E|D|-|B|A
movwf portB
goto Main


3,4,5,6,7,8,9,A,B,C,D,E,F
 

Attachments

  • DTMF.txt
    4.3 KB · Views: 123

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,700
Joined
Nov 17, 2011
Messages
13,700
There are 16 results from 4 bits. Bit testing a single bit does not tell you anything as each bit has 4 different possible results.
1 bit -> 2 results (0 | 1)
Not 4.
Testinmg single bits spans up a branch structure in tree form. This is a perfectly reasonable way to keep the number of comparisons down. NorthGuy is right in his staement in post #16.

Disclaimer: I haven't looked at the actual code. I'm reasoning from what has been explained in posts 16...20
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
I am talking about this particular case and the first test.
bit 0 will have 0000 0010 0100 0110 1000 1010 1100 1110 that corresponds with the last bit being zero and you haven't done much by just testing for bit zero.
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,700
Joined
Nov 17, 2011
Messages
13,700
bit 0 will have 0000 0010 0100 0110 1000 1010 1100 1110 that corresponds with the last bit being zero and you haven't done much by just testing for bit zero.
Of course you have.
By testing bit 0 for "0", you exlude all other possible combinations:0001 0011 0101 0111 1001 1011 1101 1111

Let me explain graphically for just two bits:
upload_2016-9-29_8-35-48.png

Here you see 2 bits (b0, b1) checked one after another using only 2 comparisons leading to 4 different branch targets.

This in fact a binary search.
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
Yes, of course, I was not thinking.

I was really thinking along the lines that you haven't really achieved much in the test as you still have to go through all the testing eventually.
Your method is suitable for large numbers as you halve the possibilities with each test.
With mine, each test achieves a final outcome.
And it's simple and linear and easy to follow for a small set of unknowns.
 
Last edited:

BobK

Jan 5, 2010
7,682
Joined
Jan 5, 2010
Messages
7,682
A jump table is better than either of the methods discussed in this thread.

Bob
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
"A jump table is better than either of the methods discussed in this thread."

Ok. I will produce a table.



table addwf PCL,F ;02h,1 add W to program counter
retlw b'00111111' ; "0" -|F|E|D|C|B|A
retlw b'00000110' ; "1" -|-|-|-|C|B|-
retlw b'01011011' ; "2" G|-|E|D|-|B|A
retlw b'01001111' ; "3" G|-|-|D|C|B|A
retlw b'01100110' ; "4" G|F|-|-|C|B|-
retlw b'01101101' ; "5" G|F|-|D|C|-|A
retlw b'01111101' ; "6" G|F|E|D|C|-|A
retlw b'00000111' ; "7" -|-|-|-|C|B|A
retlw b'01111111' ; "8" G|F|E|D|C|B|A
retlw b'01101111' ; "9" G|F|-|D|C|B|A




Main CLRF PORTB
movf portA,0 ;put the port value into w
movwf tempPort ;put port value into file tempPort
MOVLW 0Fh ;to only use the lower nibble
ANDWF tempPort,1 ;only lower nibble remains in tempPort

movf tempPort,0 ;copy tempPort value into w
call table ;unit display value will return in w
movwf portB ;output value to 7-segment display
call delay ;call delay
goto Main
 
Last edited:

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
I've gone back to have another look as I nearly abandoned this project! Theres a purpose built TX/RX ic set that will work directly with the DTMF decoder and output serial data to interface with an FM short range module. However I have plenty of unused pic16f876 to use so it's a question of getting my head around the programing where I need the guidance. I had no idea with regards to masking, however the links Collin put up proved useful. Cracked that obstacle.. at least I'm getting there slowly.
 

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
I've gone back to have another look as I nearly abandoned this project! Theres a purpose built TX/RX ic set that will work directly with the DTMF decoder and output serial data to interface with an FM short range module. However I have plenty of unused pic16f876 to use so it's a question of getting my head around the programing where I need the guidance. I had no idea with regards to masking, however the links Collin put up proved useful. Cracked that obstacle.. at least I'm getting there slowly.


Incidentally the output from the four bit binary code will convert to individual pic port outputs for swicthing relays etc.
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
Here's the subroutine. It's now only 10 lines. Once you get this working, you can add toggle.
 

Attachments

  • DTMF-2.txt
    4.8 KB · Views: 124

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
Here's the subroutine. It's now only 10 lines. Once you get this working, you can add toggle.

High Collin .. Thanks again, just to mention I outputted portb to a seven segment display simulator and then individually switched porta inputs to see the results.
Works fine except if I switched three of the four input bits to (1) the pic simulator I'm using stopped with a hardware stack overflow! Hey.. I'm getting there and learning something new. I need single outputs to switch relays so output portb bits as needed. I had to use portc as input as my simulator thinks this is an analogue input! Would you mind checking the attachment you sent to see if I need to disable anything else to switch porta as an input/output port only.
 
Last edited:
Top