View previous topic :: View next topic |
Author |
Message |
Ringo42
Joined: 07 May 2004 Posts: 263
|
using variable with output_low |
Posted: Sun Nov 27, 2005 8:42 pm |
|
|
Using CCS PCM C Compiler, Version 3.225 and a pic16f877a.
I have a project where the user talks to the pic via rs232 and sends commands to set or read individual pins. I'm doing it like this;
switch(PINN)
{
case 0:
if(state==0)
output_low(PIN_d2);
else if(state==1)
output_high(PIN_d2);
else if(state==2)
{
return_value=input(PIN_d2);
printf("%u\r",return_value);
}
break;
case 1: ....
The problem is that this takes up a lot of ROM (of which I'm almost out) when I do this for 10 different pins. The pins are not laid out on the pcb sequentially numbered like they are in the pic16f877a.h file. If there was a way I could set pinNumber to a value then do an output_low(PinNumber) I think I could reduce the program a little. Any ideas here?
Thanks
Ringo _________________ Ringo Davis |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 27, 2005 9:30 pm |
|
|
You'll have to check and see if the method shown below will
save ROM, compared to your method.
Code: | #include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// These macros allow accessing a CCS pin number which
// is passed as a variable. Note: These use a lot of ROM.
#define set_bit_var(x) bit_set(*(int8 *)(x >> 3), x & 7)
#define clear_bit_var(x) bit_clear(*(int8 *)(x >> 3), x & 7)
#define read_bit_var(x) bit_test(*(int8 *)(x >> 3), x & 7)
int8 pin_table[] = {PIN_D2, PIN_E0, PIN_B5, PIN_A1, PIN_C3,
PIN_A0, PIN_D6, PIN_B2, PIN_C1, PIN_E1};
//======================================
void main()
{
int8 pinn;
int8 state;
int8 ccs_pin;
int8 value_read;
// Put code here to get the "pinn" value.
// Also do a size check on it, to make sure
// it's within the range 0 to 9.
// Convert a pin number from 0-9 to a CCS-style pin number.
ccs_pin = pin_table[pinn];
// Based on the state command, perform an action
// on the CCS pin number.
switch(state)
{
case 0:
clear_bit_var(ccs_pin);
break;
case 1:
set_bit_var(ccs_pin);
break;
case 2:
value_read = read_bit_var(ccs_pin);
break;
}
while(1);
} |
|
|
|
Ringo42
Joined: 07 May 2004 Posts: 263
|
|
Posted: Sun Nov 27, 2005 9:45 pm |
|
|
Thanks, That is perfect. My way was taking 11% of my rom, this way take 1%.
Thanks Again.
Ringo _________________ Ringo Davis |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 28, 2005 1:12 am |
|
|
Actually there's a problem with the code I posted. It doesn't set the TRIS.
Because you're either reading or writing the pins based on the state
command, the TRIS must be set within each switch-case statement.
I'll post a revised version of the code on Monday, hopefully, that
will take care of that. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 29, 2005 12:45 pm |
|
|
Here's a revised function which works better. It now sets the TRIS.
Also you don't need the switch-case statement shown in the previous
code. Just give this function the CCS pin value and the state, and
it handles everything.
Code: |
// do_pin_io() --
// This function will perform an i/o action on a CCS pin.
// The ccs_pin parameter must be a value defined in the .H
// file for your PIC, such as PIN_B0, PIN_C5, etc.
// The CCS pin value and state can be passed in variables.
//
// The action must be as follows:
// Action = 0: Set the specified pin = 0
// Action = 1: Set the specified pin = 1
// Action = 2: Read the specified pin and return
// its value (0 or 1).
// Any action value > 2 will be treated as 2. For actions
// 0 and 1, the return value has no meaning (but 0 is
// returned).
// This function only works for the 16F series PICs, in
// which the i/o ports are at addreses 5 to 9, and the
// corresponding TRIS registers are known to be at
// 0x85 to 0x89, respectively.
int8 do_pin_io(int8 ccs_pin, int8 action)
{
int8 io_port;
int8 bitmask;
int8 retval;
int8 const bitmask_table[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
retval = 0;
io_port = ccs_pin >> 3; // Get the i/o port address
bitmask = bitmask_table[ccs_pin & 7];
if(action < 2) // Is this an output action ?
{
*(io_port | 0x80) &= ~bitmask; // Set TRIS = output
if(action)
{
*io_port |= bitmask; // Set pin = 1
}
else
{
*io_port &= ~bitmask; // Set pin = 0
}
}
else // If not, we will read the pin (action = 2)
{
*(io_port | 0x80) |= bitmask; // Set TRIS = input
retval = !!(*io_port & bitmask); // Read pin (ret. 0 or 1)
}
return(retval); // This only has meaning if action = 2
}
|
|
|
|
Ringo42
Joined: 07 May 2004 Posts: 263
|
|
Posted: Wed Jan 18, 2006 10:30 pm |
|
|
I need help again, I ported my program over to an 18f452 because I needed the code space but didn't catch the comments about this code only working on 16f parts. Is it possible to modify it so it will work on the 18f series?
Thanks
Ringo _________________ Ringo Davis |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ringo42
Joined: 07 May 2004 Posts: 263
|
|
Posted: Thu Jan 19, 2006 7:53 am |
|
|
Thank you very much.
Ringo _________________ Ringo Davis |
|
|
Christophe
Joined: 10 May 2005 Posts: 323 Location: Belgium
|
|
Posted: Thu Jun 01, 2006 5:26 am |
|
|
How can I replace output_float ( PIN_A0)?
is that do_pin_io ( PIN_A0 , 2 )? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 01, 2006 10:21 am |
|
|
Yes, that would set the pin to be an input. |
|
|
Christophe
Joined: 10 May 2005 Posts: 323 Location: Belgium
|
|
Posted: Fri Jun 02, 2006 8:39 am |
|
|
I'm sorry to say, but I think your software is buggy as it does strange things to my program. I am sure the adding of that function is the reason.
The phenomenon I have is that when I use
Code: | //********************** E3 AAN OF UIT SCHAKELEN *****************************//
//Het E3 bord kan aan- of uitgeschakeld worden door de lijn 100uS laag te
//trekken.
void TOGGLE_E3 ()
{
int8 j;
output_low (EXP_ONOFF); // Zet hem uit door laag te trekken
//do_pin_io (EXP_ONOFF, 0);
delay_ms (1000);
//do_pin_io (EXP_ONOFF, 1);
output_high (EXP_ONOFF); // Maak de pin open drain
} |
that function, the Pic is toggling some pins, hard to say what is going wrong. Perhaps the delay function is the problem... strange ..
edit: delay_ms (x) is not the problem. Just seems to be the use of the do_io_pin() function AND when a special thing happens in my program. I think the toggle() function is ok though. If you desire full details, I'll PM you my full program. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 02, 2006 10:51 am |
|
|
1. The do_pin_io program posted in this thread is only intended for
the 16F series PICs, which have the TRIS registers at specific
addresses (PORT register address + 0x80). This program won't
work with a PIC that has the TRIS registers at a different offset.
What PIC are you using ? Are you using an 18F pic ?
2. The do_pin_io program is intended to be used with a variable
as the parameter that holds the CCS pin number. You are
using it with constants. There's no reason to use do_pin_io()
in that case. Just use the CCS pin functions, such as:
output_low()
output_high()
output_float()
3. If you post or PM me a program, don't send me a large program.
Post a very small program that demonstrates the problem, such as
20 lines of code at most. Show your #include statement, and also
the #fuses and #use statements. Show all necessary variable
declarations and #define statements. The program should be
compilable. I should be able to copy and paste it into MPLAB and
click the compile button, and it should compile with no errors. |
|
|
Christophe
Joined: 10 May 2005 Posts: 323 Location: Belgium
|
|
Posted: Tue Jun 06, 2006 3:38 am |
|
|
1. PIC16LF877A
2. Somewhere else in my program, I do use do_pin_io(). That works fine. Only when I receive "SLEE" command and go to function TOGGLE_E3 () an error happens.
3. I'll try to do that. |
|
|
jeeshenlee
Joined: 15 Apr 2011 Posts: 3
|
Reading pin state without changing the direction/tris of pin |
Posted: Fri Apr 15, 2011 11:14 pm |
|
|
Hello,
Thanks for the code snippet. I'm trying to use your code snippet to read the state (like input_state(pin)) without changing the direction of the pin. How to do i modify your code snippet to do so?
Thanks.
Regards,
Jeeshen Lee |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Apr 15, 2011 11:23 pm |
|
|
Why do you need that code ? It's for version 3.xxx of the compiler.
Version 4.xxx can accept a variable to hold the CCS pin value for
the i/o functions. What's your version of the compiler ? |
|
|
|