View previous topic :: View next topic |
Author |
Message |
boulder
Joined: 15 Mar 2008 Posts: 53
|
PIC18F14K22 UART |
Posted: Wed Sep 16, 2009 4:58 pm |
|
|
Hi,
The original MCU was PIC16F689 on my PCB, it worked very well. Since my project needs more memory, I replaced it to PIC18F14K22 without any external circuits changes. Now, I have no problem to send data with UART, but I cannot receive data. I tested it with a very simple code. Could anybody tell me if my configuration is wrong on UART or not? I am sure that hardware connection is fine. Thanks.
Code: |
#include <18F14K22.h>
#include <stdio.h>
#include <stdlib.h>
#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
char a;
while(1)
{
if(kbhit())
a = getc();
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 16, 2009 5:13 pm |
|
|
Always post your compiler version. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Wed Sep 16, 2009 5:23 pm |
|
|
According to the data sheet pin RB5 defaults to analog rather than digital. Try turning off the analog function.
From the datasheet:
Quote: | On a Power-on Reset, RB<5:4> are
configured as analog inputs by default and
read as ‘0’. |
_________________ Google and Forum Search are some of your best tools!!!!
Last edited by dyeatman on Wed Sep 16, 2009 5:26 pm; edited 1 time in total |
|
|
boulder
Joined: 15 Mar 2008 Posts: 53
|
|
Posted: Wed Sep 16, 2009 5:25 pm |
|
|
The compiler is 4.099. I am going to try dyeatman's suggestion. |
|
|
boulder
Joined: 15 Mar 2008 Posts: 53
|
|
Posted: Wed Sep 16, 2009 5:45 pm |
|
|
Which register does allow me to turn off the analog function on RB5? Thanks. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Wed Sep 16, 2009 5:52 pm |
|
|
Use the setup_adc() function. See the header file for the available options. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
boulder
Joined: 15 Mar 2008 Posts: 53
|
|
Posted: Wed Sep 16, 2009 5:59 pm |
|
|
It still does not work after adding setup_adc(ADC_OFF) before the while loop. |
|
|
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);
}
} |
|
|
|
|