PDA

View Full Version : A (possibly) odd way to access a port



andywpg
- 14th November 2012, 02:14
I'm using the lower 6 bits of PORTC (16F886) as select lines for other chips. These bits would be set as outputs.

Can I use the following to access individual bits of PORTC? (I suspect not - but I've searched the manual and the forum and can't seem to find the answer)



COUNTER VAR BYTE

FOR COUNTER = 0 TO 5
PORTC.COUNTER = 0 'SET THE PORTC PIN LOW
NEXT COUNTER


My other idea was to use an array.



EN_ARRAY VAR BYTE[6]
COUNTER VAR BYTE

EN_ARRAY[0] VAR PORTC.0
EN_ARRAY[1] VAR PORTC.1
EN_ARRAY[2] VAR PORTC.2
EN_ARRAY[3] VAR PORTC.3
EN_ARRAY[4] VAR PORTC.4
EN_ARRAY[5] VAR PORTC.5

FOR COUNTER = 0 TO 5
EN_ARRAY[COUNTER] = 0 'SET PORTC PIN TO 0
NEXT COUNTER


If neither of these would work, any other ideas - it would simplify this project a lot if I can use an index of some sort to access those pins.

Thanks,

Andy

mister_e
- 14th November 2012, 02:19
it doesn't always work but give this a try


COUNTER VAR BYTE

FOR COUNTER = 0 TO 5
PORTC.0[COUNTER] = 0 'SET THE PORTC PIN LOW
NEXT COUNTER

andywpg
- 14th November 2012, 02:22
it doesn't always work but give this a try
COUNTER VAR BYTE

FOR COUNTER = 0 TO 5
PORTC.0[COUNTER] = 0 'SET THE PORTC PIN LOW
NEXT COUNTER


Ok, I get it - an offset from bit 0.

Thanks! I'll try that!

Charles Linquis
- 18th November 2012, 21:36
Although I have posted it before, the code below can be used as an example of referring to a port bit as a variable.
I use this code (or a variant) all the time to test new hardware.

Note that it was written for the 18F8720/18F8722/18F8723 family.






PORT OFFSETS
'
'
'"A.0",0
'"A.1",1
'"A.2",2
'"A.3",3
'"A.4",4
'"A.5",5
'"A.6",6
'"A.7",7
'"B.0",8
'"B.1",9
'"B.2",10
'"B.3",11
'"B.4",12
'"B.5",13
'"B.6",14
'"B.7",15
'"C.0",16
'"C.1",17
'"C.2",18
'"C.3",19
'"C.4",20
'"C.5",21
'"C.6",22
'"C.7",23
'"D.0",24
'"D.1",25
'"D.2",26
'"D.3",27
'"D.4",28
'"D.5",29
'"D.6",30
'"D.7",31
'"E.0",32
'"E.1",33
'"E.2",34
'"E.3",35
'"E.4",36
'"E.5",37
'"E.6",38
'"E.7",39
'"F.0",40
'"F.1",41
'"F.2",42
'"F.3",43
'"F.4",44
'"F.5",45
'"F.6",46
'"F.7",47
'"G.0",48
'"G.1",49
'"G.2",50
'"G.3",51
'"G.4",52
'"G.5",53
'"G.6",54
'"G.7",55
'"H.0",56
'"H.1",57
'"H.2",58
'"H.3",59
'"H.4",60
'"H.5",61
'"H.6",62
'"H.7",63
'"J.0",64
'"J.1",65
'"J.2",66
'"J.3",67
'"J.4",68
'"J.5",69
'"J.6",70
'"J.7",71

DEFINE OSC 20 '
DEFINE NO_CLRWDT 1

DEFINE HSER_RCSTA 90H
DEFINE HSER_TXSTA 20H
DEFINE HSER_BAUD 9600
DEFINE HSER_CLROERR 1
DEFINE LOADER_USED 1 ' Bootloader
Define USE_LFSR 1
DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 50
DEFINE ADC_CLOCK 6

Break VAR BIT

X VAR BYTE
Dummy VAR BYTE
ReadValue VAR BYTE
SelectedPort VAR BYTE
Position VAR BYTE
PortValue VAR BYTE
WholeVolts VAR WORD

Array1 VAR BYTE[3]
ADequiv VAR BYTE[74]
Invalids VAR BYTE[21]

ADResult VAR WORD
Counts VAR WORD
PartialVolts VAR WORD



TRISA = %11111111
TRISB = %11111111
TRISC = %10111111
TRISD = %11111111
TRISE = %11111111
TRISF = %11111111
TRISG = %11111111
TRISH = %11111111
TRISJ = %11111111

ADCON1 = $FF

PSPCON = %00000000 ' No PSP
MEMCON = %10000000 ' No External Memory
CMCON = %00000111 ' No Comparator used, turn it off
ADCON2 = %10000010 ' Right Justify, /32

T0CON =$86 ' Set up TMR0 prescaler to /128 for 1sec timer


For X = 1 to 73
ADequiv[X] = 255
Next X

ADequiv[0]= 0
ADequiv[1]= 1
ADequiv[2]= 2
ADequiv[3]= 3
ADequiv[5]= 4
ADequiv[40]= 5
ADequiv[41]= 6
ADequiv[42]= 7
ADequiv[43]= 8
ADequiv[44] =9
ADequiv[45] =10
Adequiv[46] = 11
ADequiv[60] = 12
ADequiv[61] = 13
ADequiv[62] = 14
ADequiv[63] = 15

TRISD = 0

For X = 1 to 20
Invalids[X] = 255
Next X

Invalids[0] = 22
Invalids[1] = 23

HSEROUT ["Port Tester",13,10,10]

Begin:
HSEROUT [13,10,10,10,"Port (ex: A.1) X.X",8,8,8]
Position = 0


Enter:
HSERIN [SelectedPort]
IF SelectedPort = 46 THEN GOTO ENTER
If Position = 0 THEN
SelectedPort = SelectedPort & %11011111
If SelectedPort <65 or SelectedPort > 74 THEN GOTO InvalidEntry
HSEROUT [SelectedPort,"."]
Array1[0]=SelectedPort
Position = 1
GOTO Enter
ENDIF
If SelectedPort <48 or SelectedPort > 55 THEN
GOTO InvalidEntry
ENDIF
HSEROUT [SelectedPort]
Array1[1]=SelectedPort
PortValue = ((Array1[0] - 65)*8) + (Array1[1]-48)

For X = 0 to 20
If PortValue = Invalids[X] Then
HSEROUT [13,10,"Disallowed/Invalid Port",13,10]
Pause 2000
HSEROUT [13,10,10]
GOTO Begin
ENDIF
Next X

Goto GoodEntry


InvalidEntry:
HSEROUT [13,10,"Invalid Entry",13,10]
Pause 1000
GOTO BEGIN

GoodEntry:

HSEROUT [13,10,10]
Hserout ["Output 0 (0), 1 (1), Toggle (T), Input (I), Loop Input (L), Analog (A) "]
HSERIN [Dummy]
IF Dummy > 64 THEN
HSEROUT [Dummy & %11011111]
ENDIF
HSEROUT[Dummy, CR,LF]
IF Dummy = "0" THEN ' Ouput a '0'
IF PortValue = 4 THEN
HSEROUT [10,13,"Port A4 is Open Collector!",13,10]
ENDIF
ADCON1 = $FF
TRISA.0(PortValue)=0 'Make it an output
PauseUs 20
PORTA.0(PortValue) = 0 'Write a '0'
GOTO StateCheck
ENDIF

IF Dummy = "1" THEN
IF PortValue = 4 THEN
HSEROUT [10,13,"Port A4 is Open Collector!",13,10]
ENDIF
ADCON1 = $FF
TRISA.0(PortValue)=0
PauseUs 20
PORTA.0(PortValue) = 1
GOTO StateCheck
ENDIF

IF Dummy = "T" or Dummy = "t" THEN
HSEROUT ["Press <ESC> to stop toggle"]
IF PortValue = 4 THEN
HSEROUT [10,13,"Port A4 is Open Collector!",13,10]
ENDIF
ADCON1 = $FF
TRISA.0(PortValue) = 0 'Make it an ouput
PauseUs 20

Loop1:
PORTA.0(PortValue) = 1
PAUSE 100
PORTA.0(PortValue) = 0
PAUSE 100
GOSUB CheckForChar
IF Break = 0 THEN GOTO Loop1
Break = 0
TRISA.0(PortValue) = 1 'Make it an input again
ENDIF

IF Dummy = "I" or Dummy = "i" THEN 'INPUT
ADCON1 = $FF
TRISA.0(PortValue) = 1
Pauseus 20
ReadValue = PORTA.0(PortValue)
HSEROUT [13,10,"Value = ",Dec1 ReadValue,13,10]
ENDIF

IF Dummy = "L" or Dummy = "l" THEN 'Loop read
ADCON1 = $FF
TRISA.0(PortValue) = 1 'Make an input
Pauseus 20

Loop2:

ReadValue = PORTA.0(PortValue)
HSEROUT [13,10,"Value = ",Dec1 ReadValue]
Pause 200
GOSUB CheckForChar
IF Break = 0 THEN GOTO Loop2
Break = 0

ENDIF

IF Dummy = "A" or Dummy = "a" THEN
IF ADequiv(PortValue) = 255 THEN
HSEROUT[13,10,"Invalid Analog Port",13,10]
PAUSE 2000
GOTO BEGIN
ENDIF
ADCON1 = %00000000
TRISA.0(PortValue) = 1
ADCIN (ADEquiv(PortValue)),ADResult
Counts = ADResult
ADRESULT = (ADRESULT *49)
WholeVolts = (ADresult/10000)
PartialVolts = (ADresult - (WholeVolts*10000))/10
HSEROUT [13,10,"AD Result = ",#Counts," Counts, ",#WholeVolts,".",DEC3 PartialVolts," Volts",13,10]
ADCON1 = %11111111 ' Back to all digital
ENDIF

PAUSE 500
GOTO BEGIN

StateCheck:
HSEROUT [13,10,"Leave output in this state (L), or Reset to Input (R) ? "]
HSERIN [Dummy]
IF Dummy = "R" or Dummy = "r" THEN
TRISA.0(PortValue) = 1
PORTA.0(PortValue) = 0
ENDIF
GOTO BEGIN



CheckForChar:


IF PIR1.5 = 1 THEN
HSERIN [Dummy]
if Dummy = ESC THEN
Break = 1
ENDIF
ENDIF
RETURN
RETURN

END