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

Compiler Issue w/ UART

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








Compiler Issue w/ UART
PostPosted: Thu Oct 12, 2006 10:54 pm     Reply with quote

I am having a strange issue with RS232 and CCP1. I detect data with my CCP and then store it in an array and convert the read in bits into hex and it works fine and dandy. The kicker is that when I add in a single fprintf statement to print out a newline (\r\n) or a > symbol to signal the end of transmission, it no longer appears to even acquire the data and this boggles my mind. Code listed below:

Code:

#include <18F2580.h>
#fuses NOWDT,NOPROTECT,NOLVP,NOMCLR,INTRC_IO
#use delay(clock=20000000)
#use fast_io(A)
#use fast_io(B)
#use standard_io(C)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=talk)

boolean txcomplete = false;
unsigned long data[90];
short dataBits[88];
char dataBytes[11];
int datalength = 0;
unsigned long pastval = 0;
unsigned long pulse = 0;
int bitpos = 0;
int length;

int convertPWMToBits();
void implodeToBytes();

#int_ccp1
void ccp_isr()
{
    set_timer0(0);
   
    data[bitpos] = CCP_1;
   
    bitpos++;
}

#int_rtcc
void rtcc_isr()
{
    txcomplete = true;
}

void main()
{
    int i;
   
    set_tris_a(0b10111001);
    set_tris_c(0b10111111);
   
    setup_ccp1(CCP_CAPTURE_RE);
    setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_1);
    setup_timer_1(T1_INTERNAL);
    enable_interrupts(GLOBAL);
   
    while(true)
    {
   
    setup_ccp1(CCP_CAPTURE_RE);
    enable_interrupts(INT_CCP1);
    bitpos = 0;
    txcomplete = false;
   
    while(input(PIN_C2));
   
    set_timer0(0);
    enable_interrupts(INT_RTCC);
   
    while(!txcomplete);
       
    disable_interrupts(INT_RTCC);
    setup_ccp1(CCP_OFF);
    disable_interrupts(INT_CCP1);
       
    length = convertPWMToBits();
    implodeToBytes();
   
    for(i = 0; i < length/8; i++)
    {
        fprintf(talk,"%X", dataBytes[i]);
    }
   
    fprintf(talk,"\r\n"); //Problem occurs here
    }

/*---------------------------------------------------------------------------*/
int convertPWMToBits()
{
    long pastval = 0;
    short skinny = 1;
    int pulsewidth = 0;
    int i,bitindex;
   
    bitindex = 0;
   
    for(i = 1; i < bitpos; i++)
    {
        pastval = data[i-1];
        pulsewidth = data[i] - pastval;
       
        if (pulsewidth <100>= 140)
        {
            skinny = 0;
        }
       
        dataBits[bitindex] = skinny;
       
        bitindex++;
    }
   
    return bitindex;
}
/*---------------------------------------------------------------------------*/
void implodeToBytes()
{
    char hold=0;
    int i, j;
   
    for (i=0; i<length/8; i++)
    {
        hold = 0;
       
        for (j=0; j<7; j++)
        {
            hold += dataBits[i*8 + j];
            hold <<= 1;
        }
       
        hold += dataBits[i*8 + 7];
       
        dataBytes[i] = hold;
    }
}

}


When the final fprintf statement is included (I commented it out for testing) it is the only thing that prints (I also tested various characters with the same results) because the rest of the code doesn't appear to execute (the value of the variables bitpos and length have been verified to be 0). If this fprintf statement is left out the code executes flawlessly. Any clues on why this might be happening?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 12, 2006 11:32 pm     Reply with quote

Quote:
#include <18F2580.h>
#fuses NOWDT,NOPROTECT,NOLVP,NOMCLR,INTRC_IO
#use delay(clock=20000000)


The 18F2580 data sheet says (in section 2.6, on the Internal Osc.):
Quote:
The main output (INTOSC) is an 8 MHz clock source

So with the INTRC_IO, the highest value you can put into the
#use delay() statement is 8 MHz.

Normally, the compiler will setup the OSCCON register to the
correct value automatically for you, by inserting start-up code
at the beginning of main(). However, because you put in an
illegal value for the internal oscillator (20 MHz), the compiler
doesn't initialize the OSCCON register. Also, it doesn't warn
you that it's not doing this.

So OSCCON is left in the power-on reset default state, which is
for 1 MHz. But because your #use delay() is set for 20 MHz,
all the timing parameters calculated by the compiler for the
various library routines, etc., are completly wrong. That's
why nothing works very well.

You need to change your #use delay() to 8 MHz.

Also, if you still need help, you need to fix the posting of your
code. You posted it with HTML enabled, so parts of it got
clobbered. Edit the post, delete all the code. Paste in new
code, and select the checkbox, which is right below the posting
window, and select "Disable HTML in this post".
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Thu Oct 12, 2006 11:59 pm     Reply with quote

Sorry, forgot to log in before. I tried changing the INTRC_IO, but this was not the issue - I think this is because I am using the EPIC programmer and you set the clocktype in the programmer configuration settings. I set this to HS and it has worked (I tested it with a timer toggling a bit and the calculations hold up for a 20 MHz). Here is the adjusted code as you requested:

Code:

#include <18F2580.h>
#fuses NOWDT,NOPROTECT,NOLVP,NOMCLR,HS
#use delay(clock=20000000)
#use fast_io(A)
#use fast_io(B)
#use standard_io(C)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=talk)

boolean txcomplete = false;
unsigned long data[90];
short dataBits[88];
char dataBytes[11];
int datalength = 0;
unsigned long pastval = 0;
unsigned long pulse = 0;
int bitpos = 0;
int length;

int convertPWMToBits();
void implodeToBytes();

#int_ccp1
void ccp_isr()
{
    set_timer0(0);
   
    data[bitpos] = CCP_1;
   
    bitpos++;
}

#int_rtcc
void rtcc_isr()
{
    txcomplete = true;
}

void main()
{
    int i;
   
    set_tris_a(0b10111001);
    set_tris_c(0b10111111);
   
    setup_ccp1(CCP_CAPTURE_RE);
    setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_1);
    setup_timer_1(T1_INTERNAL);
    enable_interrupts(GLOBAL);
   
    while(true)
    {
   
    setup_ccp1(CCP_CAPTURE_RE);
    enable_interrupts(INT_CCP1);
    bitpos = 0;
    txcomplete = false;
   
    while(input(PIN_C2));
   
    set_timer0(0);
    enable_interrupts(INT_RTCC);
   
    while(!txcomplete);
       
    disable_interrupts(INT_RTCC);
    setup_ccp1(CCP_OFF);
    disable_interrupts(INT_CCP1);
       
    length = convertPWMToBits();
    implodeToBytes();
   
    for(i = 0; i < length/8; i++)
    {
        fprintf(talk,"%X", dataBytes[i]);
    }
   
    fprintf(talk,"\r\n"); //Problem occurs here
    }

/*---------------------------------------------------------------------------*/
int convertPWMToBits()
{
    long pastval = 0;
    short skinny = 1;
    int pulsewidth = 0;
    int i,bitindex;
   
    bitindex = 0;
   
    for(i = 1; i < bitpos; i++)
    {
        pastval = data[i-1];
        pulsewidth = data[i] - pastval;
       
        if (pulsewidth <100>= 140)
        {
            skinny = 0;
        }
       
        dataBits[bitindex] = skinny;
       
        bitindex++;
    }
   
    return bitindex;
}
/*---------------------------------------------------------------------------*/
void implodeToBytes()
{
    char hold=0;
    int i, j;
   
    for (i=0; i<length/8; i++)
    {
        hold = 0;
       
        for (j=0; j<7; j++)
        {
            hold += dataBits[i*8 + j];
            hold <<= 1;
        }
       
        hold += dataBits[i*8 + 7];
       
        dataBytes[i] = hold;
    }
}

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 13, 2006 12:11 am     Reply with quote

Quote:
if (pulsewidth <100>= 140)

When you reposted your code, I don't think you disabled HTML.
Or you didn't do a fresh copy and paste from your editor.

Also I notice you're using an array of bits (shorts). That means
you're using vs. 4.xxx. I don't have that version installed on my
computer because I consider it Beta, and I don't want to deal with it.
If you can edit your 2nd post and get it to display the correct code,
I can look at it for problems, but I can't compile and test it.
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Fri Oct 13, 2006 5:48 pm     Reply with quote

Finally solved the problem - It turns out that this statement was messing with the compiler:

Code:

#use rs232(baud=9600, rcv=PIN_C7, stream=blueout)


This line worked correctly:

Code:

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, stream=blueout)


Apparently the PIC needs a receive and transmit pin set even if all the user is doing is receiving to work properly. Any thoughts on why this might be the case?
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Oct 13, 2006 6:09 pm     Reply with quote

Yes - if you onoly specify one pin you are using a software UART. If you define both and they both map to the respective UART pins then you are using the hardware UART.

So you problem is actually related to how you aer using the software UART.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 13, 2006 6:13 pm     Reply with quote

Your posts didn't show that code.

But anyway, the answer is that you must specify both hardware UART
pins in the #use rs232() statement, to get the compiler to generate
code for a hardware UART.

If you only specify one pin , it will generate code for a software UART.
The soft UART is much more sensitive. It can't be interrupted, or it will
lose an incoming character. Also, #int_rda only works with a hardware
UART. You can't use it with a soft UART.

---------

Edit: Oops, you beat me to it, asmallri.
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Oct 13, 2006 6:49 pm     Reply with quote

PCM programmer wrote:

Oops, you beat me to it, asmallri.


And about time too :-)
Ttelmah
Guest







PostPosted: Sat Oct 14, 2006 5:18 am     Reply with quote

It is worth adding though, that if you want to just use one pin on the hardware, specify both, and then just use the other pin as normal. Code to actually send/receive the bytes is only generated when you perform these operations, and normal I/O, will override the hardware. Smile

Best Wishes
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