|
|
View previous topic :: View next topic |
Author |
Message |
johnl
Joined: 30 Sep 2003 Posts: 120
|
PIC18F1320 Hardware RS232 Problem |
Posted: Thu Apr 20, 2006 2:57 pm |
|
|
If B0 is used for the receive pin, serial characters are received. If B4 is used, they are not. CCS version 3.214
Any ideas, anyone? Thanks.
Code: |
#include <18F1320.h>
#use delay(clock=8000000)
#fuses NOWDT, INTRC, NOFCMEN, NOBROWNOUT, NOPUT,
#fuses NOCPD, NOSTVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTC,
#fuses NOEBTR, NOEBTRB, NOPROTECT, NOCPB, NOWRTB
#use rs232(baud=9600,parity=N,xmit=PIN_B1,rcv=PIN_B4)
// If B0 is used for the receive pin, then it works.
void main()
{
char number; //variable used to send number to chip-B
setup_adc_ports(0); //no analog
setup_oscillator(osc_8mhz); //internal oscillator
set_tris_a(0x00);
set_tris_b(0x10); //input is PIN_B4 for RCV
//set_tris_b(0x01); //input is PIN_B0 for RCV
output_a(0b00000000);
output_b(0b00000000);
while (1)
{
number = getc();
output_toggle(pin_b6); //toggles LED when receiving
// otherwise gets stuck in getc().
// Only works if B0 is used for the receive pin.
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 20, 2006 3:29 pm |
|
|
If you use Pin B4 for receive (and B1 for xmit), the compiler will
generate code for the hardware UART.
In the EUSART section of the 18F1320 data sheet, it says that to
setup the UART, you must do the following with regard to TRIS:
Quote: | • TRISB<4> bit must be set ( = 1) and
• TRISB<1> bit must be set ( = 1). |
But in your program, you have got this statement:
Code: | output_b(0b00000000); |
If you look at the generated code in the .LST file, you'll see that
the output_b() function sets the TRIS for Port B to all zeros, which
means all outputs. This violates the UART setup requirement
as stated above.
Quote: | ... output_a(0b00000000);
0086: MOVLW 00
0088: MOVWF TRISA
008A: CLRF LATA
... output_b(0b00000000);
008C: MOVWF TRISB
008E: CLRF LATB |
You're using CCS's "standard i/o" mode. This is the default mode
of the compiler. In that mode, if you use the CCS port and pin i/o
functions, the compiler will automatically set the TRIS for you.
I would revise your program as shown below.
1. Move the setup_oscillator() function to the first line in the program.
You're setting up the oscillator, so it makes sense to do this immediately.
2. Use the proper CCS constants for the setup_adc_ports() function.
Don't use "magic numbers", such as 0, as a parameter.
3. Get rid of all the TRIS stuff. You don't need it. The CCS library
code will handle setting up the TRIS for the UART.
4. Since you're using toggle_pin() later in the program, you need
to initialize that one pin. So just use "output_low(PIN_B6)" to do this.
5. It's the custom in the C language to use all caps for constants.
You should follow this.
Code: | void main()
{
char number;
setup_oscillator(OSC_8MHZ);
setup_adc_ports(NO_ANALOGS);
output_low(PIN_B6);
while (1)
{
number = getc();
output_toggle(PIN_B6);
}
} |
|
|
|
Storic
Joined: 03 Dec 2005 Posts: 182 Location: Australia SA
|
|
Posted: Thu Apr 20, 2006 6:15 pm |
|
|
I have been using the 18F1320 micro and I let the software do the work, (no tris).
Code: | #use rs232(Stream=RS485,baud=9600,xmit=PIN_B1,rcv=PIN_B4,bits=8,enable=PIN_A7)
#use rs232(Stream=Term,baud=9600,xmit=PIN_B7,rcv=PIN_B6,bits=8,DISABLE_INTS)
...
setup_adc_ports(0);
...
setup_oscillator(OSC_8MHZ|OSC_INTRC);
|
I am using 2 comms (RS485 LAN and a PC interface).
I have not setup the PC coms to recieve only to display on PC via hyperterminal Code: | fprintf(Term,"Unit %u>...........",...... );
|
I am still working on my RS485 LAN.
Andrew _________________ What has been learnt if you make the same mistake? |
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
|
Posted: Sun Apr 23, 2006 7:06 pm |
|
|
PCM Programmer,
Yes, it was the output instruction causing the pin direction to change. What threw me was the fact that it wasn't a problem when the software serial connnection was used.
Storic,
Your idea of letting the compiler do the tris work is helpful.
Thanks to both.
Problem solved.
Johnl |
|
|
rina_1220
Joined: 02 Oct 2007 Posts: 20
|
|
Posted: Tue Nov 20, 2007 10:06 am |
|
|
I have tested the following code
Code: |
#include <18f1320.h>
#FUSES INTRC_IO, NOWDT, NOPROTECT, PUT, NOBROWNOUT, NOLVP, NOMCLR, NOFCMEN, NOSTVREN, DEBUG
#use delay(clock=4000000)
#use rs232(baud=9600, bits=8, parity=N, xmit=PIN_B1, rcv=PIN_B4)
void main()
{
char number;
setup_oscillator(OSC_4MHZ);
output_low(PIN_B3);
while (1)
{
//number = getc();
while(!kbhit());
output_toggle(PIN_B3);
}
}
|
but it only works when i use "getc()" instead of kbhit(). kbhit never works. Or it gets stuck or it always returns 1, no matter if i've pressed the keyboard or not.
But when I change the TX pin OR the RX pin, instead of usin the hardware ones it works fine. why's that?
I need to use kbhit, cause i have to do a timed-out getc (actually i have it working for pic16F876A, but i need to use it in pic18f1320), so the program must not be stuck on that line forever |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 20, 2007 11:22 am |
|
|
I'll show you how to research this.
Put both lines of code into the program. In the Project Options, set
the .LST file to be in Symbolic format. Compile the program. Then
look at the .LST file.
You immediately see that getc() includes doing a call to kbhit().
But it does one thing more. It actually gets the character from
the UART. This will clear the "character ready" flag inside the UART.
(Assuming there is only one character in the UART's receive fifo).
Simply doing a kbhit() does not do this. This behavior is described
in the PIC data sheet.
Code: |
... while (1)
... {
... number = getc();
0036: BTFSS PIR1.RCIF
0038: BRA 0036
003A: MOVFF RCREG,number
... while(!kbhit());
003E: BTFSS PIR1.RCIF
0040: BRA 003E
.................... output_toggle(PIN_B3);
0042: BCF TRISB.3
0044: BTG LATB.3
.................... }
0046: BRA 0036
.................... } |
|
|
|
rina_1220
Joined: 02 Oct 2007 Posts: 20
|
|
Posted: Tue Nov 20, 2007 12:37 pm |
|
|
is this just PIC18 family that has this behavior? I have never seen it happen with PIC16F |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 20, 2007 12:41 pm |
|
|
Just research it in the same way. |
|
|
rina_1220
Joined: 02 Oct 2007 Posts: 20
|
|
Posted: Thu Nov 22, 2007 6:08 am |
|
|
I think I did understand.
Thanks |
|
|
Ttelmah Guest
|
|
Posted: Thu Nov 22, 2007 8:12 am |
|
|
It is worth perhaps explaining what is happening 'below the skin'.
First start with what async serial data 'is'.
The line idles 'high', and drops to signal a 'start'.
The hardware serial, when it sees this 'low', will automatically start clocking in the data, and (depending on the word length selected), typically 9 bit times latter, will set it's 'buffer full' flag, to say that it has received a character.
Kbhit, reflects this flag. This flag will _remain_ set, _till the character is read_.
This flag will typically be set soon after the chip wakes up (since if you use a MAX232 chip, it takes a little while to raise the line). Hence it is worth performing a 'if kbhit' test near the start of the program, and receiving the 'garbage' first character, to clear the buffer.
For software serial, all 'kbhit' reflects, is the level of the line. If it is high, kbhit will return 'false', while if it is low, kbhit will return 'true'. If you repeatedly call kbhit, on a software serial line, without calling getc, eventually the line will go high, and kbhit will switch to returning 'false'. On the hardware serial, this _will not happen_, till the character is read.
Getc, on the hardware serial, will return a character if one is waiting, and then exit immediately. If one is not waiting, it'll wait till one arrives.
Getc, on the software serial, will wait till the line goes low, and then clock in a character, and return.
Now, on the 'TRIS', the key is that both kbhit, and getc, actually read the I/O pin. In CCS, if you read a pin, and standard_io mode is selected, the compiler automatically sets the TRIS. For the hardware UART, it set the TRIS during the chip's initialisation, and then the original code overrode this...
Best Wishes |
|
|
|
|
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
|