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 support@ccsinfo.com

replacement output_low/high(VARIABLE) code issues...
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
KamPutty
Guest







replacement output_low/high(VARIABLE) code issues...
PostPosted: Thu Jan 05, 2006 9:49 pm     Reply with quote

Hi all,

I was looking for a way to replace the "output_x(CONST)" methods with something that can take a variable. I was given code to do this by someone from this board (thanks if I forgot to thank you).

I have changed the code to make work for the pic18f452 chip (possibly all the 18's?).

I have expanded the one method to 2, where one is for specific pin changes, and one that is for the whole port. Saves me from goiing thru each pin, and instead just providing a 8 bit value to be ALL the pins for a given port.

The issue that I am having is that when I do a PORT update (all 8 bits), the highest bit, RC7, in my case is ALWAYS active/on. If I do a single pin deactive of RC7 RIGHT after the port update it's okay....

Here's the code...

Code:


#include <18F452.h>

#device *=16
#device adc=10
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 4000000)
//#use rs232(stream=SERIAL, baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
//#zero_ram
#case
#fill_rom 0xdead
#id   checksum

#define PORT_A  PIN_A0
#define PORT_B  PIN_B0
#define PORT_C  PIN_C0
#define PORT_D  PIN_D0
#define PORT_E  PIN_E0
#define TRIS_OFFSET 0x12

// 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 18F series PICs, in
// which the i/o ports are at addreses 0xf80 ~ 0xf84, and the
// corresponding TRIS registers are known to be at
// 0xf92 ~ f96, respectively.
int8 do_pin_io(int16 ccs_pin, int8 action)
{
    int16 io_port;
    int16 io_tris;

    int16 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];   // get mask
    io_tris=io_port+TRIS_OFFSET;            // 0x12 is the offset

    if(action < 2)  // Is this an output action ?
    {
        *(io_tris) &= ~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_tris) |= bitmask;     // Set TRIS = input
        retval = !!(*io_port & bitmask);  // Read pin (ret. 0 or 1)
    }

    return(retval);   // This only has meaning if action = 2
}

void do_port_io(int16 port, unsigned int8 value)
{
    unsigned int16 io_port;
    unsigned int16 io_tris;

    io_port=port >> 3;                 // Get the i/o port address     
    io_tris=io_port+TRIS_OFFSET;       // 0x12 is the offset

    *io_tris = ~value;
    *io_port = value;   
}

void testLEDs()
{
    int digit;
    int LEDCount=8; // base 1
    int8 x;
    int8 y=0;
    //                     1   2    3    4    5    6    7    8
    int8 const mask[] = {0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f};

    setup_adc_ports(NO_ANALOGS);

    while(1)
    {
        for(x=0; x<LEDCount; x++)
        {
            do_port_io(PORT_C, mask[x]);    // Set the segments
//            do_pin_io(PIN_C7, 0);           // unless I do this, C7 is ALWAYS active!
            do_pin_io(PIN_D0+x, 0);         // turn on digit (using Common Cathode LED's)
            delay_ms(500);                 
            do_pin_io(PIN_D0+x, 1);         // turn off digit
        }
    }
}


void main()           
{
    testLEDs();

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



Any thoughts? Replacement code?

~Kam (^8*
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 05, 2006 10:50 pm     Reply with quote

Is this the exact code that you tested ? Are you certain that you
had the #use rs232() statement commented out when you did the test ?
KamPutty
Guest







yup...
PostPosted: Fri Jan 06, 2006 12:38 am     Reply with quote

PCM programmer wrote:
Is this the exact code that you tested ? Are you certain that you
had the #use rs232() statement commented out when you did the test ?


Sadly, yes, it was commented out. What's strange is regardless on what I do in the "do_port_io" method, RC7 is high (I know this since the DP led it on). BUT, if I call the do_pin_io method right after on RC7 set to "0", the DP goes off!

BTW, I am prototyping on a PicDem 2 Plus board, and RC6 and RC7 are wired to the on board MAX232. There is nothing plugged into the DB9 (ie. no serial).

I thought that this may be it, but why would setting the bit (rc7) after the port _io method make a difference? Am I bypassing something and it's resetting to "default" when a port change happens, but the pin level overrides that?....

~Kam (^8*
KamPutty
Guest







Replacement code?
PostPosted: Fri Jan 06, 2006 11:05 am     Reply with quote

Hi all,

I'm still stumped! Does anyone one have some code to just update a port, all 8 bits using a user sent variable?

ie. updatePort(int8 port, unsigned int8 value);

I want to replace my port update method (it's the one that always has a high RC7)...

Thanks all,

~Kam (^8*
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jan 06, 2006 11:35 am     Reply with quote

Quote:
BTW, I am prototyping on a PicDem 2 Plus board, and RC6 and
RC7 are wired to the on board MAX232
. There is nothing plugged into
the DB9 (ie. no serial).

Quote:
What's strange is regardless on what I do in the "do_port_io" method, RC7 is high

The MAX232 is driving Pin C7 high. MAX232 does an inversion.
There is a pull-down resistor built-in on the Rx input of the MAX232.
So that puts a logic-low into the Rx side, and it is inverted to become
a logic high level going to pin C7 on the PIC.

According to the MAX232 data sheet, the TTL/CMOS output of the
MAX232 can typically source 30 ma if the output is shorted.

You should not be trying to make pin C7 into a PIC output pin.
It conflicts with the output pin of the MAX232.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Thu Jan 19, 2006 9:42 pm     Reply with quote

I'm trying to use the code above but I can't get it to work. I copied it exactly and got nothing. So I shrunk it down a little to post here. When the pic boots it flashes the leds once, then just keeps printing "Working" but no more leds flash. There are a couple lines that my olod compiler does not like, but I don't think they should kill it.

What am I missing?
Thanks
Ringo

#include "18f452.h"
//using CCS PCW C Compiler, Version 3.050
#fuses hs,nowdt,noprotect,put,lvp
#device *=16
#device adc=10
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
//#zero_ram --this does not work with my old compiler version
//#case
//#fill_rom 0xdead--this does not work with my old compiler version
#define TRIS_OFFSET 0x12

int8 do_pin_io(int16 ccs_pin, int8 action)
{
int16 io_port;
int16 io_tris;

int16 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]; // get mask
io_tris=io_port+TRIS_OFFSET; // 0x12 is the offset

if(action < 2) // Is this an output action ?
{
*(io_tris) &= ~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_tris) |= bitmask; // Set TRIS = input
retval = !!(*io_port & bitmask); // Read pin (ret. 0 or 1)
}

return(retval); // This only has meaning if action = 2
}

void testLEDs()
{
int digit;
int LEDCount=8; // base 1
int8 x;
do_pin_io(PIN_D2, 1); // turn on digit (using Common Cathode LED's)
do_pin_io(PIN_D4, 1); // turn on digit (using Common Cathode LED's)
do_pin_io(PIN_D5, 1); // turn on digit (using Common Cathode LED's)
do_pin_io(PIN_D6, 1); // turn on digit (using Common Cathode LED's)
do_pin_io(PIN_D7, 1); // turn on digit (using Common Cathode LED's)
delay_ms(250);
do_pin_io(PIN_D2, 0); // turn off digit
delay_ms(250);
do_pin_io(PIN_D4, 0); // turn off digit
delay_ms(250);
do_pin_io(PIN_D5, 0); // turn off digit
delay_ms(250);
do_pin_io(PIN_D6, 0); // turn off digit
delay_ms(250);
do_pin_io(PIN_D7, 0); // turn off digit
delay_ms(250);
}


void main()
{
//just to prove the leds work
printf("workingabcd\r\n");

output_high(PIN_D2);
output_high(PIN_D4);
output_high(PIN_D5);
output_high(PIN_D6);
output_high(PIN_D7);
delay_ms(500);
output_low(PIN_D2);
output_low(PIN_D4);
output_low(PIN_D5);
output_low(PIN_D6);
output_low(PIN_D7);
delay_ms(500);

//#ignore_warnings 203--this does not work with my old compiler version
while(1)
{
printf("working\r\n");
testLEDs();
}
//#ignore_warnings none --this does not work with my old compiler version
}
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 19, 2006 10:03 pm     Reply with quote

I don't have PCH vs. 3.050. The oldest version I have is 3.148.
Your code worked with that version. I tested it on a PicDem2-Plus,
and I changed the LED pins to B0-B3 to fit that board.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Thu Jan 19, 2006 10:15 pm     Reply with quote

Damn, I guess that means it is a compiler thing. I'm printing out the values calculated for IO_port and IO_Tris and they are correct so it must be the pointer operation that is failing. Is there a way to do it without pointers?
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 19, 2006 10:29 pm     Reply with quote

Post the ASM code from your .LST file for the do_pin_io() function.
Don't post the whole list file -- just that function.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Thu Jan 19, 2006 10:42 pm     Reply with quote

.................... int8 do_pin_io(int16 ccs_pin, int8 action)
.................... {
.................... int16 io_port;
.................... int16 io_tris;
....................
.................... int16 bitmask;
.................... int8 retval;
.................... int8 const bitmask_table[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
*
0004: ADDLW 16
0006: MOVWF FF6
0008: MOVLW 00
000A: MOVWF FF7
000C: BTFSC FD8.0
000E: INCF FF7,F
0010: TBLRD*
0012: MOVF FF5,W
0014: RETURN 0
0016: DATA 01,02
0018: DATA 04,08
001A: DATA 10,20
001C: DATA 40,80
....................
.................... retval = 0;
*
008C: CLRF 0F
.................... // printf("ccspin=%ld\r\n",ccs_pin);
.................... io_port = ccs_pin >> 3; // Get the i/o port address
008E: BCF FD8.0
0090: RRCF 07,W
0092: MOVWF 0A
0094: RRCF 06,W
0096: MOVWF 09
0098: RRCF 0A,F
009A: RRCF 09,F
009C: RRCF 0A,F
009E: RRCF 09,F
00A0: MOVLW 1F
00A2: ANDWF 0A,F
.................... // printf("IO_PORT=%ld\r\n",io_port); //3971=f83 for D
.................... bitmask = bitmask_table[ccs_pin & 7]; // get mask
00A4: MOVF 06,W
00A6: ANDLW 07
00A8: MOVWF 10
00AA: MOVF 07,W
00AC: ANDLW 00
00AE: MOVWF 11
00B0: MOVF 10,W
00B2: CALL 0004
00B6: MOVWF 01
00B8: CLRF 0E
00BA: MOVFF 01,0D
.................... io_tris=io_port+TRIS_OFFSET; // 0x12 is the offset
00BE: MOVLW 12
00C0: ADDWF 09,W
00C2: MOVWF 0B
00C4: MOVLW 00
00C6: ADDWFC 0A,W
00C8: MOVWF 0C
.................... // printf("IO_tris=%ld\r\n",io_tris); //3989=f95 for D
....................
.................... if(action < 2) // Is this an output action ?
00CA: MOVF 08,W
00CC: SUBLW 01
00CE: BTFSS FD8.0
00D0: GOTO 0130
.................... {
.................... *(io_tris) &= ~bitmask; // Set TRIS = output
00D4: MOVF 0B,W
00D6: MOVWF FE9
00D8: MOVFF 0C,FEA
00DC: MOVF 0E,W
00DE: MOVWF 03
00E0: COMF 03,F
00E2: MOVF 0D,W
00E4: XORLW FF
00E6: ANDWF FEF,W
00E8: MOVWF 00
00EA: MOVLW 00
00EC: ANDWF 03,F
00EE: MOVWF FEF
....................
.................... if(action)
00F0: MOVF 08,F
00F2: BTFSC FD8.2
00F4: GOTO 0110
.................... {
.................... *io_port |= bitmask; // Set pin = 1
00F8: MOVF 09,W
00FA: MOVWF FE9
00FC: MOVFF 0A,FEA
0100: MOVF FEF,W
0102: IORWF 0D,W
0104: MOVWF 00
0106: MOVF 0E,W
0108: MOVWF 03
010A: MOVWF FEF
.................... }
.................... else
010C: GOTO 012C
.................... {
.................... *io_port &= ~bitmask; // Set pin = 0
0110: MOVF 09,W
0112: MOVWF FE9
0114: MOVFF 0A,FEA
0118: MOVF 0E,W
011A: MOVWF 03
011C: COMF 03,F
011E: MOVF 0D,W
0120: XORLW FF
0122: ANDWF FEF,W
0124: MOVWF 00
0126: MOVLW 00
0128: ANDWF 03,F
012A: MOVWF FEF
.................... }
.................... }
.................... else // If not, we will read the pin (action = 2)
012C: GOTO 0162
.................... {
.................... *(io_tris) |= bitmask; // Set TRIS = input
0130: MOVF 0B,W
0132: MOVWF FE9
0134: MOVFF 0C,FEA
0138: MOVF FEF,W
013A: IORWF 0D,W
013C: MOVWF 00
013E: MOVF 0E,W
0140: MOVWF 03
0142: MOVWF FEF
.................... retval = !!(*io_port & bitmask); // Read pin (ret. 0 or 1)
0144: MOVF 09,W
0146: MOVWF FE9
0148: MOVFF 0A,FEA
014C: MOVF FEF,W
014E: ANDWF 0D,W
0150: MOVWF 00
0152: MOVF 0E,W
0154: ANDLW 00
0156: MOVWF 03
0158: IORWF 03,W
015A: MOVLW 00
015C: BTFSS FD8.2
015E: XORLW 01
0160: MOVWF 0F
.................... }
....................
.................... return(retval); // This only has meaning if action = 2
0162: MOVF 0F,W
0164: MOVWF 01
0166: RETLW 00
.................... }
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jan 21, 2006 1:52 am     Reply with quote

I think I see the problem. When he converted my code for the 18F
series PICs, he changed "bitmask" into a 16-bit variable. That's wrong.
It should be int8. For later versions of the compiler, this doesn't hurt
anything. But for your version, PCH 3.050, it causes a problem.
It generates incorrect code. Try changing the declaration of "bitmask",
shown below in bold, back to an "int8". See if that fixes the problem.

I don't have your version of the compiler, or anything close to it, so I
can't test this. But I think there's a good chance that it might fix it.
Quote:
int8 do_pin_io(int16 ccs_pin, int8 action)
{
int16 io_port;
int16 io_tris;

int16 bitmask; // Change this to an int8
int8 retval;
int8 const bitmask_table[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Sun Jan 22, 2006 10:41 pm     Reply with quote

Thanks, That fixed the problem in the simple example, now I have another question.
Why does this work;

int16 ccs_pin;
ccs_pin=PIN_D2;

but this does not;

int return_value,pinn,state;
int16 ccs_pin;
int16 pin_table[] = {PIN_D2, PIN_C3, PIN_C4, PIN_C5, PIN_D4,
PIN_D5, PIN_D6, PIN_D7, PIN_B2, PIN_E1};
ccs_pin = pin_table[pinn];

It worked fine in the 877 version when everythig above was 8 bit, but not in the 18f version.

Thanks
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 23, 2006 12:25 am     Reply with quote

Quote:
That fixed the problem in the simple example, now I have another question.

Can you post the code for the "non-simple" example ? Except don't post
the do_ccs_pin() function. I'll assume you're using the working version.

If you post the example code, then I can compile it and look at it.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Mon Jan 23, 2006 10:11 am     Reply with quote

Here is the entire function. the main difference between the simple example is that I don't pass teh pin and state into teh function, I grab them from a serial buffer and do the look-up table there.
If I use the line //ccs_pin=PIN_D2; then that pin works, so the problem is narrowed down to teh ccs_pin = pin_table[pinn]; line.
Thanks
Ringo


int GPIO(void)
{
int return_value,pinn,state;
int16 pin_table[] = {PIN_D2, PIN_C3, PIN_C4, PIN_C5, PIN_D4,
PIN_D5, PIN_D6, PIN_D7, PIN_B2, PIN_E1};
int16 ccs_pin;
int16 io_port;
int16 io_tris;

int8 bitmask;
int8 retval;
int8 const bitmask_table[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int p,s;
p=2;
s=3;

do
{
p+=3;
s=p+1;

pinn=SERIAL_BUFFER[p]-0x30;
state=SERIAL_BUFFER[s]-0x30;
printf("pinn=%d\r\n",pinn);
printf("state=%d\r\n",state);

if(serial_buffer[p+1]=='\r')
state=2;
if(serial_buffer[s-1]=='\r')
{
NACK();
return;
}
ccs_pin = pin_table[pinn];
// ccs_pin=PIN_D2;
retval = 0;
io_port = ccs_pin >> 3; // Get the i/o port address
bitmask = bitmask_table[ccs_pin & 7];
io_tris=io_port+TRIS_OFFSET; // 0x12 is the offset
if(state < 2) // Is this an output action ?
{
*(io_tris) &= ~bitmask; // Set TRIS = output

if(state==1)
{
printf("setting a 1\r\n");
*io_port |= bitmask; // Set pin = 1
}
else
{
printf("setting a 0\r\n");
*io_port &= ~bitmask; // Set pin = 0
}
}
else // If not, we will read the pin (state = 2)
{
*(io_tris) |= bitmask; // Set TRIS = input
retval = !!(*io_port & bitmask); // Read pin (ret. 0 or 1)
printf("%d",retval);
return(retval);
}
} while(SERIAL_BUFFER[s+1] !='\r');


}
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 23, 2006 2:27 pm     Reply with quote

Make a complete test program that just tests the serial buffer problem.
The pin i/o function doesn't have anything to do with that problem.
You can cut that code out completely. You also need to explain your
serial format. You have offsets into your data stream called s and p.
You should post an example of your full data stream. Post why you
have these offsets in there. Focus in on the serial protocol problem.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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