CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

input_state() With A Variable?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Geps



Joined: 05 Jul 2010
Posts: 129

View user's profile Send private message

input_state() With A Variable?
PostPosted: Mon Sep 26, 2011 3:46 pm     Reply with quote

Hi,

I have a subroutine that is designed to check a Pin can go to 5V and 0V as follows:

Code:
int1 test_pin(int16 PinToTest) {
   int1 PinState = 0;

   // first drive pin to 5 volts
      output_high(PinToTest);
   // wait briefly
      delay_us(100);
   // get state:
      PinState = input_state(Pin_c4);
   // Check if went to 5 volts
      if (!PinState) {return (1);}
   // Now drive to 0V
      output_low(PinToTest);
   // wait briefly
      delay_us(100);
   // get state:
      PinState = input_state(PinToTest);
   // Check if went to 5 volts
      if (!PinState) {return (0);}
      else {return (1);}
}



However it won't compile as it needs a constant for the input_state() function. Is there a tidy work around or do I have to use a large switch with hard coded pin values?

Cheers,
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Sep 26, 2011 4:35 pm     Reply with quote

You could read the manual(press F11 when your project is open) and lookup bit_test(...).... and checkout the examples CCS gives either onscreen(F11) or in the examples folder....
Geps



Joined: 05 Jul 2010
Posts: 129

View user's profile Send private message

PostPosted: Tue Sep 27, 2011 9:12 am     Reply with quote

I think you misunderstood me - _with_ a variable not _on_ a variable.

The variable should contain the pin to be passed as a parameter of the input_state().

I think I'll just disable fast_io, manually set the TRIS and then use input() instead.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Sep 27, 2011 9:44 am     Reply with quote

If you are attempting to do readback of outputs then yes, you have no option other than to *enable" fast_io mode and do the TRIS stuff yourself. The reason for this is that any CCS input function will set the bit/port to input mode and any output function set them to output automatically. If I understand what you're tryin to do, then you need to set the direction to output and then set the output to set the state and input to read it back.

Note that if the readback is ever different from the drive then your PIC is in a state where it may be damaged. At the very least its functioning may be impaired, such as inaccurate ADC readings. You should treat a bad readback as a fatal fault and stop driving the pin immediately and shut everything down to a safe state.

By the way, as all the ports are memory mapped, then they are just variables. Variables that are absolutely addressed and vary with external influence. In otherwords they are volatile in C terms.

Also while your comments state the PIC waits "briefly", 100us is a pretty long time in hardware terms. Certainly enough for damage to occur in many case. It depends on what you are hanging of the output of course, but for any load that the PIC can reliably drive it will be a looooooong time.

And finally, you cannot prove the pin goes to 5V or 0V, or indeed anywhere close. All the input shows is that the output went beyond the Vil or Vih threshold. That may be good enough for the PIC, but it doesn't mean any device driven by the PIC will see good logic levels. If you *really* want to know the voltage then you'll have to read back with an analogue input. In short readbacks don't live up to their promise in many practical situations.

RF Developer.


Last edited by RF_Developer on Tue Sep 27, 2011 9:52 am; edited 1 time in total
Geps



Joined: 05 Jul 2010
Posts: 129

View user's profile Send private message

PostPosted: Tue Sep 27, 2011 9:49 am     Reply with quote

Thanks RF,

You can use the input_state() function though to read a pin without changing it's direction but I can't seem to get it to work without explicitly saying which pin it should check.

Unless there is a work around I'm missing?
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Sep 27, 2011 9:58 am     Reply with quote

Oh yes, so it does! Oops. Cool

The pin constants should work for it as normal. Maybe there are are some ports on some PICs that don't work with input_state()... maybe. What PIC are you using?

Ah! It appears that the defintion of input_state() is something like:

int1 input_state(const int16 pin)

which, obvioiusly, requires a constant :-((
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Sep 27, 2011 10:54 am     Reply with quote

You could dump the listing to see how CCS does it, then create your own 'check_pin_state' function that allows the pin in question to be a varible and not a constant.
Battery David



Joined: 01 Feb 2010
Posts: 25

View user's profile Send private message

PostPosted: Tue Sep 27, 2011 1:19 pm     Reply with quote

I know people on this forum (with TONS of experience) usually (always?) say to use normal IO but I have always used fast IO. I don't think I have ever had trouble because of it.

I think the code using the functions looks terrible and this looks much better:

Code:

#use fast_io(ALL)

/**********************************************************
 Port C Defn's

**********************************************************/
#bit    cbBlueLED_IO            = regPortCDataDir.0
#bit    cbPC_Connected_IO       = regPortCDataDir.1
#bit    cbRedLED_IO             = regPortCDataDir.2
#bit    cbSCL_IO                = regPortCDataDir.3
#bit    cbSDA_IO                = regPortCDataDir.4
#bit    cbTestPoint12_IO        = regPortCDataDir.5
#bit    cbRS232_TX_IO           = regPortCDataDir.6
#bit    cbRS232_RX_IO           = regPortCDataDir.7

#bit    pinBlueLED              = regPortCPins.0
#bit    pinPC_Connected         = regPortCPins.1
#bit    pinRedLED               = regPortCPins.2
#bit    pinSCL                  = regPortCPins.3
#bit    pinSDA                  = regPortCPins.4
#bit    pinTestPoint12          = regPortCPins.5
#bit    pinRS232_TX               = regPortCPins.6
#bit    pinRS232_RX             = regPortCPins.7

    cbBlueLED_IO                = PIN_OUTPUT;
    cbPC_Connected_IO           = PIN_INPUT;
    cbRedLED_IO                 = PIN_OUTPUT;
//  cbSCL_IO                    = PIN_INPUT;
//  cbSDA_IO                    = PIN_OUTPUT;
    cbTestPoint12_IO            = PIN_OUTPUT;
//  cbRS232_TX_IO               = PIN_OUTPUT;      // RX & TX are set by the compiler
//  cbRS232_RX_IO               = PIN_INPUT;      // RX & TX are set by the compiler

    pinBlueLED                   = LED_OFF;
//  pinPC_Connected               =                // Input pin, no initial value
    pinRedLED                   = LED_OFF;
//  pinSCL                       =                // Input pin, no initial value
//  pinSDA                      = PIN_LOW;
    pinTestPoint12               = PIN_LOW;
//  pinRS232_TX                   =                // RX & TX are set by the compiler
//  pinRS232_RX                   =                // RX & TX are set by the compiler


    // to check the state of a pin
    if( pinPC_Connected )
    {
        // Code
    }
   
    // to toggle a pin
    pinRedLED = !pinRedLED;
   
    // to turn the LED on
    pinRedLED = LED_ON;



This is not a full program, just the appropriate parts.

BTW, I also spent a bunch of time renaming the control registers to names that make more sense. It took a lot of work but I think it's easier to see regPortCDataDir rather than TRISC (OK, we all know what TRIS means but someone reviewing our code doesn't)

The cool part about handling the port pins this way is, if you change the logic of how an LED turns on and off, you don't have to go through your code and change all of the output_high(PIN) to output_low(PIN), you just have to change the definition of LED_ON at one place in a header file.

Just my way of doing things.

David
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Sep 27, 2011 3:06 pm     Reply with quote

David

You must know how to touchtype ! Even TRISC is a lot for me as I grew up on 2 letter variables.....early 70s...
Battery David



Joined: 01 Feb 2010
Posts: 25

View user's profile Send private message

PostPosted: Tue Sep 27, 2011 3:28 pm     Reply with quote

Actually I don't touch type (I can fake it pretty well) and, while I didn't do computers in the 70s, I did use: LET A1 = 3 and had to include line numbers.

It took a lot of self-discipline to get myself to use long variable names. I'm still working on using "Temperature" instead of "Temp" since Temp can have other meanings.

I am a work in progress!
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Sep 28, 2011 6:53 am     Reply with quote

Back to the original topic:
The v3 compiler did not support variable names in the input and output functions but v4 added this feature to the input(), output_low() and output_high() functions. Too bad the feature wasn't added to the input_state() function.

Basically the input_state() function is the same as input() but without touching the TRIS direction register. This behaviour is easy to simulate by setting the fast_io pragma in combination with input():
Code:
int16 read_pin = PIN_D0;

#use FAST_IO(D)
    i = input(read_pin);
#use STANDARD_IO
This works fine except when you don't know which port you are going to read from and/or you don't know what IO-mode the port was using beforehand.

In the old times, before the v4 compiler, PCM Programmer posted a function to read and write from variable pins:
For 16F: http://www.ccsinfo.com/forum/viewtopic.php?t=25280&start=4
For 18F: http://www.ccsinfo.com/forum/viewtopic.php?t=27723&start=3

Based on those functions I came up with the following simplified function:
Code:
#include <18F458.H>
#fuses HS,NOWDT,NOLVP
#use delay(clock=16000000)


// input_pin_state() --
// This function reads the level of a pin without changing the direction of the
// pin as input() does. It is identical to the CCS function input_state() but
// will accept variables as parameter as well.
// The ccs_pin parameter must be a value defined in the .H file for your PIC,
// such as PIN_B0, PIN_C5, etc.
//
// Note that this function takes more memory space and code cycles than the
// original CCS function, so only use this when you need the variable PIN name
// functionality.
//
// This function should work for the 12F, 16F and 18F series PICs.
int8 input_pin_state(int16 ccs_pin)
{
    int16 io_port;
    int8 bitmask;
    int8 retval;

    io_port = ccs_pin >> 3;                  // Get the i/o port address     
    bitmask = 1 << (ccs_pin & 7);            // get mask
    retval = (*io_port & bitmask) ? 1 : 0;   // Read pin (ret. 0 or 1)

    return retval;
}

void main()           
{
   int8  i;
   int8  state;

   for(i=0; i<8; i++)
   {
      state = input_pin_state(PIN_D0 + i);
      delay_ms(500);                 
   }

#ignore_warnings 203
    while(1);
#ignore_warnings none
}
Geps



Joined: 05 Jul 2010
Posts: 129

View user's profile Send private message

PostPosted: Fri Sep 30, 2011 9:33 am     Reply with quote

Thanks alot ckielstra.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group