|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
RS232 Receive Nightmare on PIC 18F452 with RF Serial Module |
Posted: Thu Sep 21, 2006 10:02 am |
|
|
Hi all,
This is my first post to the forum and I am not *that* experienced with PICs and CCS so please bear with me! I have the following setup:
A PIC 18F452 on strip board, all correctly configured and working fine (to the extent that I have successfully made and tested a driver for an HD44780 LCD display.) To this I have connected an RF transceiver module. The module works with TTL level UART and its important pins are Transmit, Receive, CTS (held high when the module is busy and cannot accept any more data) and RTS (which should be driven low when the PIC/PC or whatever is either ready to transmit or receive data from the RF module. I have the module set up at 9600 baud with 8 data bits, no parity, 1 start bit and one stop bit. It is linked to the PIC as follows:
RF Module Rx output pin -----> PIC Hardware USART Rx (in my case C7)
RF Module Tx input pin -----> PIC Hardware USART Tx (in my case C6)
RF Module RTS pin -----------> PIC output pin B3
RF Module CTS pin -----------> PIC input pin B2
I have a partner RF transceiver module connected through a MAX232 to my PC. These module pairs are designed to send data encoded between them. I know that my PC end RF module is working because I can set it to config mode and send/receive config data from it. I know that data can be sent from the PIC through the RF link to the PC because I have written programs with various printf lines and that text appears perfectly in HyperTerminal so no problems in that direction. However, I am unable to receive any serial data into the PIC with either getc(), gets() or even an interrupt driven serial buffer program, such as the one included as an example with CCS.
At this point you may be wondering whether it is an RTS/CTS flow control issue. I am 99% certain that this is not the case as I am able to tie RTS to ground as with my simple programs, the PIC is never 'unable to receive data'. As for reading CTS, I believe there is no need as the RF module has a 60 byte buffer that I am nowhere near to filling at the moment so I can write that off as a possible source of the fault too.
I have this program set up:
SIMPLECOMMS.C:
Code: |
#include "C:\Documents and Settings\Administrator\Desktop\radio\simplecomms\simplecomms.h"
char receive;
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_oscillator(False);
set_tris_b (0x04);
output_low (PIN_B3);
printf ("Serial routine is about to commence");
while (TRUE)
{
receive = getc();
delay_ms (500);
printf ("You typed: %c\n", receive);
delay_ms (500);
}
}
|
SIMPLECOMMS.H:
Code: |
#include <18F452.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES XT //Crystal osc <= 4mhz
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use fast_io (B)
|
When I run it, all I get in HyperTerminal on the PC is:
'Serial routine is about to commence.'
Then, when I type a character, the program does move forward to display in Hyperterminal:
'You typed:' - but where here there should be my typed character echoed back to me - there is nothing!!!!!! I am extremely confused and would be very grateful if anyone can help.
Three final notes: I have tried using %X in printf() to echo my character as a hex value but that did not work either.
I have tried to include the 'ERRORS' option in the #use rs232 as well as 'FORCE_SW' - these did not help!
Finally, and I am not sure if this will have an effect. My RF module is actually a 3.3 volt unit so its outputs are also only 3.3 volts and not 5 volts for a logical '1' - I do not think though that this is a problem as I have looked at the datasheet of the 18F452 and can see that 3.3 volts is more than enough to constitute a logical '1' when the PIC input is read.
Sorry this post was so long! |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1908
|
|
Posted: Thu Sep 21, 2006 11:11 am |
|
|
The biggest issue is the 3.3V logic from the receiver -> 5V PIC. A very recent thread on this forum mentioned that the USART actually requires at least 4V for a logic high because it's a schmitt trigger input.
If you have a couple ordinary npn BJTs (2N3904 will suffice) and some resistors at hand, you can build a 3.3V to 5V level shifter. I suck at drawing ASCII circuits, so this description will have to suffice.
The receiver's data out line connects to a series resistor, approx. 600 ohms. The other end of the resistor connects to the base of Q1. Q1's emitter is grounded, and its collector is connected to the 5V rail through a 1k series resistor. Q1's collector is also directly connected to Q2's base. Q2 also has its emitter grounded. Q2's collector is connected to the 5V rail through a 1k series resistor. Q2's collector is directly connected to the PIC's receive in pin.
Try building this level shifter and see if that fixes things. If not, you may have to up the complexity slightly to get it to work. Consult this thread for help: http://www.ccsinfo.com/forum/viewtopic.php?t=23953 |
|
|
Guest
|
Still no luck! |
Posted: Thu Sep 21, 2006 1:01 pm |
|
|
Hi newguy,
Thanks very much for your quick response! I have built and incorporated the voltage shifter which works fine. However, still no received bytes on the PIC!
I have had a look at the other forum you suggested but am still unsure how to proceed (stupidity on my part I am sure!).
Do you have any other ideas as to why my PIC is unable to receive the serial data?
Many thanks again for all your help!
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 21, 2006 1:11 pm |
|
|
Quote: |
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
I have tried to include the 'ERRORS' option.
while (TRUE)
{
receive = getc();
delay_ms (500);
printf ("You typed: %c\n", receive);
delay_ms (500);
}
|
You get one char and then you don't service the UART receiver for more
than one second. If more than two chars come in during that time,
the UART receiver will lock-up, and stay locked up. That's why you
need the ERRORS parameter in #use rs232(). You made a mistake
when you temporarily added it and then took it away. You need to
put it in there, and keep it in there. |
|
|
Guest
|
Sorted at last! |
Posted: Thu Sep 21, 2006 3:18 pm |
|
|
Hi PCM Programmer,
Thanks for that advice! I have implemented the interrupt driven RS232 routine again as well as removed the delays that were tying up my system. I am please to report that a combination of that and of newguy's suggestion has meant that I now have full RS232 communication in both directions!!!
Thank you both for all your help and advice - this is a great forum!
Summary of possible solutions for people who have the same problem I had:
1. Do not settle for anything less than a true TTL voltage to drive the PIC's Rx Pin (Logical '0' = 0v, Logical '1' = 5v).
2. Do not put needless delays in a program that reads in serial data as this will tie up the program and create a greater potential for errors.
3. Add the 'ERRORS' flag to any hardware #use rs232 statement to prevent a hang due to an overflow.
4. If possible, use an interrupt driven serial input routine that ensures the PIC pays full attention to serial input, as soon as data is available. |
|
|
PIC_Head Guest
|
|
Posted: Fri Sep 22, 2006 3:25 pm |
|
|
Hi,
Would you kindly tell us which modem you are using, and post your serial interrupt routine?
Thanks,
Tom |
|
|
Guest
|
Equipment and Code |
Posted: Fri Sep 22, 2006 5:17 pm |
|
|
Hi Tom,
Not a problem. The modem I am using is the RXQ2 from Telecontrolli. Data sheet here: www.rfsolutions.co.uk/acatalog/DS650-6.pdf
As for the interrupt code, it is simply a crib of the example interrupt routine in ex_sisr.c - I am therefore not sure if I am allowed to copy the code here as it might be a copyright infringement! If you are really stuck then let me know and I will rewrite the interrupt routine and post it in my own form!
Regards,
John |
|
|
Guest
|
Re: Sorted at last! |
Posted: Mon Mar 16, 2009 10:24 am |
|
|
Hi,
i'm trying to communicate a PIC16F877 with a telecontrolli RXQ2 module, but it's not working. Can anyone help me?
Thanks. |
|
|
|
|
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
|