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

PIC18F14K22 UART
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
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 16, 2009 6:00 pm     Reply with quote

The setup_adc_ports() function is not working correctly for the 18F14K22
in vs. 4.099. It writes to ADCON1, but it should write to ANSEL and
ANSELH.

For a work-around, you can write to the registers directly, and set the
analog pins to be all digital. Example:
Code:

#include <18F14K22.h>
#fuses XT, NOWDT, PUT, NOPLLEN, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_B7, rcv=PIN_B5, ERRORS)

#byte ANSEL  = 0xF7E
#byte ANSELH = 0xF7F

//==============================
void main(void)
{
char c;

// Set i/o pins to be all digital.
ANSEL  = 0x00;
ANSELH = 0x00;


while(1)
  {
   c = getc();
   putc(c);
  }
 
}


I'll report this bug to CCS support.
Guest








PostPosted: Wed Sep 16, 2009 7:09 pm     Reply with quote

Thanks. It's working now after setting ANSEL and ANSELH to 0x00.
boulder



Joined: 15 Mar 2008
Posts: 53

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 2:12 pm     Reply with quote

Hi,
Now I have a new issue with UART. If I use polling method, it has no problem to receive a whole packet, but if I use interrupt, it receives 8 bytes data correctly, the 9th and 10th bytes are incorrect, and the rest of packet is not received. The below is my test code, please tell me if I miss anything.
Code:

#use delay(clock=3686400, crystal)
#use rs232(baud=115200, xmit=PIN_B7, rcv=PIN_B5)
#fuses  XT, NOPLLEN, NOWDT, PUT, MCLR, NOPROTECT, NOCPD, BROWNOUT, IESO, FCMEN

#byte ANSEL  = 0xF7E
#byte ANSELH = 0xF7F 
#byte RCREG = 0xFAE
#byte RCSTA = 0xFAB
#bit  OERR =  RCSTA.1
#bit  CREN =  RCSTA.4

#define RX_BUFFER_SIZE      20

unsigned int8 WriteIndex = 0;
unsigned int8 Count = 0;

#INT_RDA
void RDA_ISR(void)
{
  RxBuffer[WriteIndex] = RCREG;                                 
  WriteIndex++;
  Count++;
  if(WriteIndex == RX_BUFFER_SIZE) WriteIndex = 0;

  if(OERR)
  {
    CREN = 0;
    CREN = 1;
  }
}

void main()
{
  ANSEL  = 0x00;
  ANSELH = 0x00;

  setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_XMIT_L_TO_H | SPI_CLK_DIV_64);

  enable_interrupts(INT_RDA);
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);    //This timer is not used
  enable_interrupts(global);

  while(1)
  {
    if(Count > 0)
      Receive _packet();
  }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 2:31 pm     Reply with quote

Your test program is not very good. It has things in it that are not
needed, such as setup_spi() and setup_timer_1(). Also, it calls a
receive_packet() function which is not shown.
boulder



Joined: 15 Mar 2008
Posts: 53

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 2:53 pm     Reply with quote

I deleted setup_spi(), setup_timer_1() and receive_packet(). Now I read uart interrupt buffer directly through ICD2 debugger. The result is same.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 3:00 pm     Reply with quote

Make a little test program that reads a packet and then sends it to
a terminal window on your PC. Then you can see if it's working.
boulder



Joined: 15 Mar 2008
Posts: 53

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 3:33 pm     Reply with quote

The below is my new test code; the result is not good. It receives the first 8 bytes correctly; 9th and 10th bytes are incorrect, the rest of packet is not received.
Code:

#use delay(clock=3686400, crystal)
#use rs232(baud=115200, xmit=PIN_B7, rcv=PIN_B5)
#fuses  XT, NOPLLEN, NOWDT, PUT, MCLR, NOPROTECT, NOCPD, BROWNOUT, IESO, FCMEN

#byte ANSEL  = 0xF7E
#byte ANSELH = 0xF7F 
#byte RCREG = 0xFAE
#byte RCSTA = 0xFAB
#bit  OERR =  RCSTA.1
#bit  CREN =  RCSTA.4

#define RX_BUFFER_SIZE      20

unsigned int8 WriteIndex = 0;
unsigned int8 Count = 0;
unsigned int8 ReadIndex = 0;

#INT_RDA
void RDA_ISR(void)
{
  RxBuffer[WriteIndex] = RCREG;                                 
  WriteIndex++;
  Count++;
  if(WriteIndex == RX_BUFFER_SIZE) WriteIndex = 0;

  if(OERR)
  {
    CREN = 0;
    CREN = 1;
  }
}

void main()
{
  ANSEL  = 0x00;
  ANSELH = 0x00;

  enable_interrupts(INT_RDA);
  enable_interrupts(global);

  while(1)
  {
    if(Count > 0)
       putc(RxBuffer[ReadIndex]);
       Count--;
       ReadIndex++;
    }
    if (ReadIndex == RX_BUFFER_SIZE) ReadIndex = 0;
  }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 4:10 pm     Reply with quote

Try a very simple program:
Code:
#include <18F14K22.h>
#fuses XT, NOWDT, PUT, NOPLLEN, NOLVP
#use delay(clock=3686400, crystal)
#use rs232(baud=115200, xmit=PIN_B7, rcv=PIN_B5)

#byte ANSEL  = 0xF7E
#byte ANSELH = 0xF7F 

//==================================
void main()
{
int8 c;
 
ANSEL  = 0x00;
ANSELH = 0x00;

while(1)
  {
   c = getc();
   putc(c);
  }

}
boulder



Joined: 15 Mar 2008
Posts: 53

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 4:19 pm     Reply with quote

I already tried this method, it works. However, Interrupt method does not work well.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 4:43 pm     Reply with quote

Try using a standard circular buffer, such as the Ex_Sisr.c example,
instead of your #int_rda routine.
boulder



Joined: 15 Mar 2008
Posts: 53

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 5:44 pm     Reply with quote

I tried Ex_Sisr.c example, and it acts the same way. However, there is a good news that it works fine with my test code and example code if I use the other baudrates instead of 115200. Could anyone explain it to me? My project requests 115200 baudrate.

Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 18, 2009 1:20 pm     Reply with quote

Earlier, I did a count of the number of instruction cycles needed to
process the interrupt, and compared it to the time required to receive
or transmit a byte. I found that the isr execution time was lower,
so it should work. But, I could have overlooked something.
Easy answer:

Increase your crystal frequency to 7.3728 MHz (2x your existing freq).
This may fix the problem. Change the #use delay statement and
use the HS fuse for this frequency.
boulder



Joined: 15 Mar 2008
Posts: 53

View user's profile Send private message

PostPosted: Fri Sep 18, 2009 4:37 pm     Reply with quote

I think that it's too late to change crystal. Is it okay to enable 4xPLL in #fuse?
boulder



Joined: 15 Mar 2008
Posts: 53

View user's profile Send private message

PostPosted: Fri Sep 18, 2009 5:04 pm     Reply with quote

I enabled PLL in #fuses and changed baudrate to 28800 in #use rs232 since frequency is 4 times faster, now uart interrupt is working very well with the actual 115200 baudrate.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 18, 2009 6:03 pm     Reply with quote

You shouldn't use incorrect rates for the baud rate. Change the #use
delay() statement so it fits the new 4x oscillator frequency. The
compiler will setup everything correctly, provided that you set the
#use delay() to match the actual speed of the oscillator. In the case
of a 3.6864 MHz crystal with a 4x PLL, the oscillator freq is 14.74564 MHz.
See below:
Quote:

#include <18F14K22.h>
#fuses XT, NOWDT, PUT, PLLEN, NOLVP
#use delay(clock=14745600)
#use rs232(baud=115200, xmit=PIN_B7, rcv=PIN_B5, ERRORS)
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