View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 16, 2009 6:00 pm |
|
|
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
|
|
Posted: Wed Sep 16, 2009 7:09 pm |
|
|
Thanks. It's working now after setting ANSEL and ANSELH to 0x00. |
|
|
boulder
Joined: 15 Mar 2008 Posts: 53
|
|
Posted: Thu Sep 17, 2009 2:12 pm |
|
|
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
|
|
Posted: Thu Sep 17, 2009 2:31 pm |
|
|
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
|
|
Posted: Thu Sep 17, 2009 2:53 pm |
|
|
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
|
|
Posted: Thu Sep 17, 2009 3:00 pm |
|
|
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
|
|
Posted: Thu Sep 17, 2009 3:33 pm |
|
|
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
|
|
Posted: Thu Sep 17, 2009 4:10 pm |
|
|
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
|
|
Posted: Thu Sep 17, 2009 4:19 pm |
|
|
I already tried this method, it works. However, Interrupt method does not work well. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 17, 2009 4:43 pm |
|
|
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
|
|
Posted: Thu Sep 17, 2009 5:44 pm |
|
|
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
|
|
Posted: Fri Sep 18, 2009 1:20 pm |
|
|
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
|
|
Posted: Fri Sep 18, 2009 4:37 pm |
|
|
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
|
|
Posted: Fri Sep 18, 2009 5:04 pm |
|
|
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
|
|
Posted: Fri Sep 18, 2009 6:03 pm |
|
|
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) |
|
|
|
|