+ Reply to Thread
Results 1 to 10 of 10
  1. #1
    Desterline's Avatar
    Desterline Guest

    Default Accessing pins with a variable

    Hello all,

    I've been working on a project that uses a 16f877a to display some data on some multiplexed 5x7 matrix displays. It's working OK, but I was hoping there was a better way of doing this.

    Right now I have the rows driven with bits 0..6 of port B and D (bi-color displays), but the columns are driven with all the leftover pins:
    ColA var portd.7
    ColB var porte.0
    ColC var porta.5
    ColD var portc.5
    ColE var portc.3
    ColF var portc.4
    ColG var portb.7
    ColH var portc.0
    ColI var porte.2
    ColJ var porte.1

    I'm using a timer interrupt to handle the actual multiplexing:
    ISR:

    branch currentcol, [INT0,INT1,INT2,INT3,INT4,INT5,INT6,INT7,INT8,INT9]
    INT0: 'activate colA only
    high colj 'turn off the last column
    portb = greendata[0] | %10000000 'mask out the high bit, it controls a colunm drive
    portd = reddata[0] | %10000000 'mask out the high bit, it controls a colunm drive
    low colA ' turn on new column
    currentcol = 1
    GOTO INTEND

    INT1: 'activate colB only
    high cola 'turn off the last column
    portb = greendata[1] | %10000000
    portd = reddata[1] | %10000000
    low colb
    currentcol = 2
    goto intend

    >eight more snipped, you get the idea<

    INTEND:
    tmr0 = 57
    intcon.2 = 0

    Resume

    Originaly I tried a select case structure for this, but I found that the different cases took different amounts of time to proccess. That led to a very noticable brightness variation accross the display. To counter that I added a different size pause to each case. (as much as 70us). Not suprisingly, performance was kinda crappy :-)

    Eventualy I turned to this branch structure, it doesn't have the brightness problem, it runs faster (about 40us, for all cases) and took less code (>80 words less), but it's still ugly. I was hoping for somthing more like:

    ISR:
    CurrentColumn = CurrentColumn + 1
    'add some if-then bounds checking here...

    HIGH (CurrentColumn - 1 )
    portb = greendata[CurrentColumn] | %10000000
    portd = reddata[CurrentColumn] | %10000000
    LOW CurrentColumn

    tmr0 = 57
    intcon.2 = 0

    Resume

    I know it doesn't work exactly like this, but I was hoping someone might have a way of grouping various pins into an array or something such? (or some other better way to solve this)

    Thanks,
    -Denny

  2. #2
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    2,915

    Default

    First of all you may replace the High and Low commands with:

    variable=1 or variable=0

    Memory and speed gain with this trick.


    Now for the pin addressing (this was posted long ago by Dennis Saputelli):

    pin_index var byte

    pin_index=12

    porta.0[pin_index]=1 'Sets PortB.4 high.

    for a PIC 16F877 pin_index values are:

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 pin_index
    0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 port bit
    Port A Port B


    16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 pin_index
    0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 port bit
    Port C Port D


    32 33 34 pin_index
    0 1 2 port bit
    Port B


    Note that even though the Port A register does not have the upper bits physically, they do count.


    Hope that helps,
    Ioannis

  3. #3
    Join Date
    Jul 2003
    Posts
    2,358

    Default

    I don't think this works in all cases... I posted a similar thread earlier and had to withdraw the posting after heaps of anomalies... more thorough investigation is needed on this one...

  4. #4
    Desterline's Avatar
    Desterline Guest

    Default

    Originally posted by Ioannis
    First of all you may replace the High and Low commands with:

    variable=1 or variable=0

    Memory and speed gain with this trick.
    Why didn't I think of that. Seems obvious enough knowing that HIGH X also sets the relevant TRIS bit, but I hadn't considered it takes time and code to do that...

    This got me thinking so I did a little test. Just a little programm that blinks an LED

    define LOADER_USED 1
    define OSC 4
    ADCON1 = 7 ' Set PORTA and PORTE to digital

    Pin_Index var byte

    trisa = 0 'all outputs
    trise = 0 'all outputs
    pin_index = 0
    Main:

    'high porta.0
    'porta.0 = 1
    porta.0[pin_index] = 1 'Sets PortB.4 high

    pause 500

    'porta.0 = 0
    'low porta.0
    porta.0[pin_index] = 0

    pause 500
    goto main

    Using the HIGH/LOW comands (others commented out) this compiled to 75 words. But using the PORTA.0 = X it compled to 69 words. (looks like a savings of three words for every HIGH or LOW)
    Then I tested the PIN_INDEX method, 115 words. It worked, but it seems to be a lot larger.

    Then just for fun I tried compiling them with MPASM instead, I don't understand why (yet ) but in all cases MPASM compiled to three words less than PM. Anyone know why?

    Originally posted by Melanie
    I don't think this works in all cases... I posted a similar thread earlier and had to withdraw the posting after heaps of anomalies... more thorough investigation is needed on this one...
    Melanie, could you be a little more specific about the anomalies? Was it certain pics, code sequences, phase of the moon, was Mercury in retrograde? ;-)

    -Denny

  5. #5
    RossW's Avatar
    RossW Guest

    Default

    If I do this on a 12f629:

    CMCON = 7
    TRISIO = 0

    LED_0 = GPIO.0

    LED_0 = 1


    ... it doesn't work.

  6. #6
    Join Date
    Dec 2003
    Location
    Wichita KS
    Posts
    517

    Default

    Hello Ross,

    Ross>>CMCON = 7
    TRISIO = 0

    LED_0 = GPIO.0

    LED_0 = 1
    <<

    Better Assign LED_0 to a value!

    Something like LED_0 var byte

    Dwayne
    Ability to Fly:
    Hurling yourself towards the ground, and missing.

    Engineers that Contribute to flying:
    Both optimists and pessimists contribute to the society. The optimist invents the aeroplane, the pessimist the parachute

    Pilots that are Flying:
    Those who know their limitations, and respect the green side of the grass...

  7. #7
    Join Date
    Jul 2003
    Posts
    2,405

    Default

    > If I do this on a 12f629:

    > CMCON = 7
    > TRISIO = 0

    > LED_0 = GPIO.0

    > LED_0 = 1


    > ... it doesn't work.

    Try this and see how it works.

    ANSEL = 0 ' Set all digital
    CMCON = 7 ' Analog comparators off
    TRISIO = 0
    LED_0 VAR GPIO.0

    Loop:
    LED_0 = 1
    PAUSE 250
    LED_0 = 0
    PAUSE 250
    GOTO Loop
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  8. #8
    RossW's Avatar
    RossW Guest

    Default

    My post had a mistake, but in my code I had LED_0 var GPIO.0, and it didn't work setting LED_0 = 1

    Ross

  9. #9
    Join Date
    Jul 2003
    Posts
    2,358

    Default

    That's because you forgot about initialising the ANSEL register. see Bruce's example.

  10. #10
    RossW's Avatar
    RossW Guest

    Default

    I didn't think there was an ANSEL register on the 12f629, only CMCON ?!?

Similar Threads

  1. EEPROM Variables (EE_Vars.pbp)
    By Darrel Taylor in forum Code Examples
    Replies: 79
    Last Post: - 26th October 2012, 00:06
  2. Change On Interrupt, PIC16F884
    By elec_mech in forum mel PIC BASIC Pro
    Replies: 17
    Last Post: - 14th November 2008, 17:25
  3. accessing ports pins using an index variable
    By xnihilo in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 19th March 2008, 20:36
  4. Help with sound command in 2 programs
    By hyperboarder in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 5th July 2007, 20:36
  5. Assigning a variable to only a few pins?
    By Dayaks in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 28th August 2006, 00:21

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts