Maker Pro
Maker Pro

Reading PIC ports

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
Hi all appreciate some help please. I'm using a pic16f876 and need to read one of the input ports connected to the output of a DTFM decoder which is a four bit binary output e.g. 5 = 1010 so only four inputs of the pic are used. I then have to convert each four bit code to a single individual latched output on one of the other spare ports from 0 to 8.
I'm not very good at programming and only use pic assembly code. Can anybody give me a simple example code to work from please. Kind regards
 

Minder

Apr 24, 2015
3,478
Joined
Apr 24, 2015
Messages
3,478
In Assembly programming the LSB is usually on the right not the left as you have shown, i.e. 5 = 0101, with a 16F you can use a look up table based on reading the four bits then extract the 8 bit value with the corresponding bit set for and out put to the port.
Look for look up table methods.
There are some examples in Nigel Goodwin's tutorial and also the PicList site.
M.
 

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
In Assembly programming the LSB is usually on the right not the left as you have shown, i.e. 5 = 0101, with a 16F you can use a look up table based on reading the four bits then extract the 8 bit value with the corresponding bit set for and out put to the port.
Look for look up table methods.
There are some examples in Nigel Goodwin's tutorial and also the PicList site.
M.
Hi M.. thanks for you reply, you are correct 5 = 1010 but don't understand "with a 16F" just need to decode the 4 bit output generated by a phone keypad. For each key pressed the corresponding four bit code will operate a control relay. One relay for each code generated. Regards
 

Minder

Apr 24, 2015
3,478
Joined
Apr 24, 2015
Messages
3,478
You either need a way to know when a key is pressed, either by periodic scan or interrupt.
Once you input the 4 digit binary value, you use a lookup table with all the individual bit values, this is then output to the port and turns on the relative bit, a 2n7000 on the output could be used on the output to pick up the relay.
M.
 

NorthGuy

Mar 24, 2016
53
Joined
Mar 24, 2016
Messages
53
You could use a jump table, but if you want something easily understandable then do something of that sort. It's called "binary tree":


Code:
 ; assume the code is stored in the variable called "CODE"
 ; use: call ProcessCode

ProcessCode:
 banksel CODE

CASE_xxxx:
 btfsc CODE,3
 goto CASE_1xxx

CASE_0xxx:
 btfsc CODE,2
 goto CASE_01xx

CASE_00xx:
 btfsc CODE,1
 goto CASE_001x

CASE_000x:
 btfsc CODE,0
 goto CASE_0001

CASE_0000:
 ; do here what you want for code 0000
 return

CASE_0001:
 ; do here what you want for code 0001
 return

CASE_001x:
 btfsc CODE,0
 goto CASE_0011

CASE_0010:
 ; do here what you want for code 0010
 return

CASE_0011:
 ; do here what you want for code 0011
 return

CASE_01xx:
 btfsc CODE,1
 goto CASE_011x

CASE_010x:
 btfsc CODE,0
 goto CASE_0101

CASE_0100:
 ; do here what you want for code 0100
 return

CASE_0101:
 ; do here what you want for code 0101
 return

CASE_011x:
 btfsc CODE,0
 goto CASE_0111

CASE_0110:
 ; do here what you want for code 0110
 return

CASE_0111:
 ; do here what you want for code 0111
 return

CASE_1xxx:
 btfsc CODE,2
 goto CASE_11xx

CASE_10xx:
 btfsc CODE,1
 goto CASE_101x

CASE_100x:
 btfsc CODE,0
 goto CASE_1001

CASE_1000:
 ; do here what you want for code 1000
 return

CASE_1001:
 ; do here what you want for code 1001
 return

CASE_101x:
 btfsc CODE,0
 goto CASE_1011

CASE_1010:
 ; do here what you want for code 1010
 return

CASE_1011:
 ; do here what you want for code 1011
 return

CASE_11xx:
 btfsc CODE,1
 goto CASE_111x

CASE_110x:
 btfsc CODE,0
 goto CASE_1101

CASE_1100:
 ; do here what you want for code 1100
 return

CASE_1101:
 ; do here what you want for code 1101
 return

CASE_111x:
 btfsc CODE,0
 goto CASE_1111

CASE_1110:
 ; do here what you want for code 1110
 return

CASE_1111:
 ; do here what you want for code 1111
 return
 

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
Thanks NorthGuy.. That sample gives me a good starting point to work by. I very rarely need to program anything so don't have much experience in this field, hence my request for guidance. I know there are several bog standard logic ic's which will work but I already have several pic 16f876's to hand and this project already has one.
Kind Regards
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
You constantly loop around the following 8 sets of instructions: (2 are below)
movlw xxxx 0001
subwf porta,1
btfss 03,2
goto $+2
the files match goto

movlw xxxx 0010
subwf porta,1
btfss 03,2
goto $+2
the files match goto
 

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
You constantly loop around the following 8 sets of instructions: (2 are below)
movlw xxxx 0001
subwf porta,1
btfss 03,2
goto $+2
the files match goto

movlw xxxx 0010
subwf porta,1
btfss 03,2
goto $+2
the files match goto

Hi Collin, Thanks for your code, will try it out. kind regards
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
The first thing you do is set up your output port with 8 LEDs on 8 x 330R resistors.
Then create a sub-routine that clears the port then increments the port and calls a delay and loops.
Watch the LEDs increment.

Then put 4 x 10k on the lower nibble of the input port and take them to 0v.
Create the poling sub-routine above and no LEDs should illuminate.
Take one LED to 5v and see the corresponding LED illuminate.

In the poling sub-routine you will need to mask the 4 upper bits.

This is all you need to set up the micro.
 

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
Hi Collin.. made a start if you could cast your eye over it, not sure if I'm following your example! I use MPLAB IDE
and use MP LAB simulator tool to test the program. I've uploaded the file saved in note pad.
 

Attachments

  • BINARY CODE 3.txt
    4.2 KB · Views: 161

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
Hi Collin.. made a start if you could cast your eye over it, not sure if I'm following your example! I use MPLAB IDE
and use MP LAB simulator tool to test the program. I've uploaded the file saved in note pad.

May I thank members who have offered there help and time in respect of this post. I've decided to tackle this project from a slightly different prospective by using individual bits from the output of the DTMF decoder which simplifies my knowledge and understanding of programming. Regards nepow
 

nepow

Jul 18, 2011
99
Joined
Jul 18, 2011
Messages
99
You can't bit-test. You must nibble-compare. Or you do a decrement and compare.

Thank you Collin.. The DTMF decoder produces a series of four bit binary codes depending on which tone was received. For example if say '0010' was recieved then I could use the first four portb bits as inputs and use portb,1 if it's set (btfsc) likewise if not set the next bit portb,2 is tested and so on. This would allow me to look at only one of four possibilities, but for what I want I can manage. I can put together a simple program this way with my very limited programing knowledge using pic assembly. If I knew how to read the lower binary nible inputs and write a short program to output say eight individual outputs then I'd be happy. Sadly at 70 years of age and for a one off home automation project it's a challanging ordeal.
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
You have to set up the micro with switches and leds so that you can turn on a LED when a particular switch is closed and turn off the led when the switch is open.
When you have done this and it works, you can add the DTMF chip

There are 16 results from 4 bits
simply take the port value and mask off the 4 upper bits
Here is the library of routines:

Library of Routines A-E
Library of Routines E-P
Library of Routines P-Z
 

NorthGuy

Mar 24, 2016
53
Joined
Mar 24, 2016
Messages
53
You can't bit-test. You must nibble-compare. Or you do a decrement and compare.

Why not? My code which I posted in post #5 does bit-test and works faster than the nibble-compares or even decrement and compare. Its execution time is from 9 to 13 cycles (not including return) - 10.5 average and 13 worst case. For comparison, the code you posted in post #7 takes 6 to 90 cycles (48 average and 90 worst case). Even if you replace it with more efficient decfsz/goto combination, it'll take 3 to 46 cycles (24 average and 45 worst case). I'd say, the bit-test beats the nibble compare hands down.
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
NorthGuy. Please don't come in. You don't know what you are talking about.
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.
 

NorthGuy

Mar 24, 2016
53
Joined
Mar 24, 2016
Messages
53
NorthGuy. Please don't come in. You don't know what you are talking about.
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.

I do know what I'm talking about. Just look at my code in post #5. I think it's clear enough to understand. There are 4 bits. My code tests each bit once. And that is enough to separate the execution into 16 branches, which are marked with "do here what you want for code such and such".

Since this code requires only 4 tests, it is much faster than 16 separate comparisons.
 

NorthGuy

Mar 24, 2016
53
Joined
Mar 24, 2016
Messages
53
Your code requires 7 tests.

No. Regardless of the nibble you feed to it, it tests each of the 4 bits only once. This makes 4 tests. You can run it in the debugger and count the tests.

If you think some of the branches take longer, please let me know what nibble should we feed to it to make more than 4 tests.
 
Top