PDA

View Full Version : Setting GPIO and TRISIO



AvionicsMaster1
- 9th March 2011, 14:24
Gents,
I'm using a 12f683 to light close to 20 LEDs. I'm currently using select case statements to set the GPIO and TRISIO so I can use several LEDs on each I/O pin. Then cycle through the LEDs pausing where necessary and repeating but not repeating on all LEDs.

Is there a way to define LEDXs' TRISIO and GPIO and then call LEDX. It would make the repeated use of individual LEDs alot easier.

Something like this:
LED1 VAR BIN
LED2 VAR BIN
LED1 = trisio%011110, gpio=%000001
LED2 = trisio%011110, gpio=%100000

main:
LED1
pause 500
LED2
pause 500
goto main
end

I did look in http://ww1.microchip.com/downloads/en/DeviceDoc/01146B.pdf but it doesn't really address this.

Heckler
- 9th March 2011, 15:57
I believe your example of defining a variable as "bin" is incorrect. Here is an excerpt from the manual...

Some examples of creating variable are:
dog VAR BYTE
cat VAR BIT
w0 VAR WORD

You might also look at the "HIGH" and "LOW" commands as they also make the given pin an output during the "high" command. BUT be careful as they can act "funny" when your code moves on and the pin goes back to an input un-expectedly. Breadboard something up and try the "high/low" command and see if it will work.

Here is a program that I wrote to interface the 12f683 to a GPS module. It does not directly address your question but it might give you some insight into working with the registers. It is just a piece if code that I had on my laptop that uses the 12f683... You might look through it for examples of defining variables and writing to the registers. It is kind of a mess in organization.

DO REALIZE that I am by no way a polished programmer!!

There is a pretty steep learning curve in getting profecient in working with these PIC's.
The Microchip PIC 12f683 documentation and the PBP manual is (should be) your friend.


'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2010 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 2/28/2010 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************

DEFINE ADC_BITS 8 ' Number of bits in ADCIN result
define ADC_CLOCK 3 'SET CLOCK SOURCE TO RC = 3
DEFINE ADC_SAMPLEUS 50

' -----[ Initialization ]------------------------------------------------

Reset:

CMCON0 = %00000111 ' Comparators off

TRISIO = %101100
ADCON0 = %00001100 ' LeftJust,VDD,x,x,AN3,x,ADCdisabled
ANSEL = %0010000 ' -001xxxx Fosc/8, -xxx0000 all pins digital not analog

IOC = %001000 'enable gpio.3 interrupt on change
'NOTE: you must also clear the CONFIG.5 fuse bit to change gpio.3 to
'an I/O instead of MCLR (its under the configuration link on the
'pickit2 programing app. This bit must be done each time before you
'program the chip.

OPTION_REG = %10111111 'b7=pullups disabled
'b6=int on falling edge

' -----[ Timer setup ]----------------------------------------------------
' T1CON = %00110001 'Enable Timer1 with 1:8 prescaler

' PIE1 = %00000001 'Enable Timer1 overflow interrupt
' 'PIR1 = %0000000
' TMR1h = 0 'reset timer1 to zero
' TMR1l = 0 'reset timer1 to zero

Xpwr var gpio.0 'Output to turn on XBee
XBrx var gpio.1 'Output serial data to XBee
XBtx var gpio.2 'Input
rst var gpio.3 'Input
Gpwr var gpio.4 'Output to turn on GPS
GPS var gpio.5 'Input serial data from GPS

symbol I = 254 'LCD prefix for Instruction
symbol clr = 1 'LCD CLEAR SCREEN
SYMBOL LINE2 = 192 'LCD ADDR FOR 1ST CHAR ON 2ND LINE
SYMBOL H = 2 'LCD HOME COMMAND

GPRMC VAR BYTE[64]

hh VAR BYTE 'hours
mm VAR BYTE 'minutes
ss VAR BYTE 'seconds
sss var word 'milliseconds
fix VAR WORD 'GPS fix
latdeg VAR BYTE 'degrees latitude
latmin VAR BYTE 'minutes latitude
latminn var word 'fractional minutes latitude
NS VAR BYTE 'north or south
londeg VAR BYTE 'degrees longitude
lonmin VAR BYTE 'minutes longitude
lonminn var word 'fractional minutes longitude
EW VAR BYTE 'east or west
Knots VAR byte 'speed in knots (units)
Knotss var byte 'speed in fractional knots
course var word 'heading
dy VAR BYTE 'day
mt VAR BYTE 'month
yr VAR BYTE 'year

speed var byte[4] 'array to hold knots & knotss
mph var word 'units of mph
mphh var byte 'fractional mph
KK var word 'this var will contain knots(12) & knotss(34) = 1234

Value VAR WORD 'AD value, Must be a WORD even though AD is 8bit

' -----[ Program Code ]----------------------------------------------------
'low lcd
'pause 1000 'allow lcd to initialize
'serout2 lcd,16780,[i,clr]
high gpwr
high xpwr
Main:
'high gpwr
serin2 gps,188,3000,tmout,[WAIT("$GPRMC,"),STR GPRMC\63\"$"] 'Data IN from GPS

arrayread gprmc,[DEC2 hh,DEC2 mm,dec2 ss,_
wait(","),fix,wait(","),DEC2 latdeg,DEC2 latmin,wait("."),dec4 latminn,_
wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait("."),dec4 lonminn,_
wait(","),EW,wait(","),dec knots,dec Knotss,dec course,_
wait(","),DEC2 dy,DEC2 mt,DEC2 yr] 'parse the GPS array into parts

'high xpwr
pause 500
if fix = "V" then nofix 'jump to "waiting for fix" display
SEROUT2 xbtx,188,[$0D,$0A,"$GPRMC,",STR GPRMC\63] 'Data OUT to XBEE
'low xpwr

pause 5000
goto main
'gosub calcmph 'convert knots.knotss to mph.h

'serout2 lcd,16780,[i,h," ",dec2 latdeg,$DF,dec2 latmin,".",dec4 latminn,"'",ns,dec2 mph,dec1 mphh]
'serout2 lcd,16780,[i,line2,dec3 londeg,$DF,dec2 lonmin,".",dec4 lonminn,"'",ew,dec3 course]


'-----------subroutines-------------------------
'CalcMPH:
' arraywrite speed,[dec2 knots,dec2 knotss] 'combine knots and knotss into 4 byte array
' arrayread speed,[dec4 kk] 'now get the 4 digit dec value of the array

' mph = kk * 9881
' mph = R0 + R2.15 + kk 'mph now contains 4 digit value of mph/tenths/hundredths

' mphh = mph//100 'isolate tenths and hundredths
' mphh = mphh/10 'eliminate the hundreths and keep tenths
' mph = mph/100 'now keep integer mph, first two digits of 4 digit value
'return

NoFix:
serout2 xbtx,188,["waiting for fix"]
goto main

tmout: 'end up here if no data from gps within 3 seconds
serout2 xbtx,188,["timeout"]
GOTO MAIN

aratti
- 9th March 2011, 18:54
Is there a way to define LEDXs' TRISIO and GPIO and then call LEDX. It would make the repeated use of individual LEDs alot easier.


Not just as you wrote it, but you can semplify this way:



LED_T_1 VAR BYTE
LED_G_1 VAR BYTE
LED_T_2 VAR BYTE
LED_G_2 VAR BYTE

LED_T_1 = %00011110
LED_G_1 = %00000001

LED_T_2 = %00011110
LED_G_2 = %00100000

main:
TRISIO = LED_T_1
GPIO = LED_G_1
pause 500
TRISIO = LED_T_2
GPIO = LED_G_2
pause 500
goto main
end


Now since you don,t need to change the TRISIO then you can write:



LED_G_1 VAR BYTE
LED_G_2 VAR BYTE

TRISIO = %00011110
LED_G_1 = %00000001
LED_G_2 = %00100000

main:
GPIO = LED_G_1
pause 500
GPIO = LED_G_2
pause 500
goto main
end


.. or in a normal way you can write:



LED1 VAR GPIO.0
LED2 VAR GPIO.6

TRISIO = %00011110

main:
LED1 = 1
LED2 = 0
PAUSE 500
LED1 = 0
LED2 = 1
PAUSE 500
GOTO MAIN

END


.. again in a more sophisticated way:



LED1 VAR GPIO.0
LED2 VAR GPIO.6

TRISIO = %00011110

main:
LED1 = !LED1
LED2 = !LED1
PAUSE 500
GOTO MAIN

END

Cheers

Al.

AvionicsMaster1
- 10th March 2011, 20:00
Hey, thanks for the reply and for showing the progression from functional to elegant. But would you mind verifying my logic?

Since I'm an unsophisticated person, I want to make sure I understand what's going on in the following snippet. Variables get declared, TRIS set and then LED1= !LED1 sets a 1, because its prior value was 0, turning on LED1. LED2= ! LED1 turns off LED2 because it's value is set to 1 in the previouse line. Then it loops and the !LED1 keeps toggling the state of LED1 and LED2.

Is that close? Is it necessary to set the gpio.0 or gpio.6 to 0 to make sure they turn off at start up?


.. again in a more sophisticated way:



LED1 VAR GPIO.0
LED2 VAR GPIO.6

TRISIO = %00011110

main:
LED1 = !LED1
LED2 = !LED1
PAUSE 500
GOTO MAIN

END

Cheers

Al.[/QUOTE]

aratti
- 10th March 2011, 21:40
Is that close?

You have got it!


Is it necessary to set the gpio.0 or gpio.6 to 0 to make sure they turn off at start up?

No, since Led1 and Led2 has been declared as alias of gpio.0 and gpio.6. So if you want set them to zero just state Led1=0 : Led2=0.

Cheers

Al.

Heckler
- 11th March 2011, 06:54
Also... don't overlook the fact that GPIO.3 can only be an INPUT. It defaults to MCLR or "Master Clear with internal pull-up". This means it will reset the chip whenever it goes low.

In order to make it a normal input pin you MUST change the "Configuration Word Register" bit 5. This register can ONLY be defined once at the time of programming. I think some refer to it as the "FUSE bits" or "configuration fuses" This special register can only be changed each time you program the chip and is not change-able during runtime of your program.

I think I lost a few hairs and much sleep trying to understand the details of configuring PIC's and the registers. I now keep the .pdf of what ever chip I am working with open and refer to it often as I am defining the functionality of my chip and the various I/O pins, analog, comparators, pulse width modulation, etc, etc.

I hope this helps and is not too basic for your level.:o

In the beginning I tried to use GPIO.3 as a normal input and could not for the life of me figure out why it kept resetting my program...

regards