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

RS232 between 5v and 3.3v systems, FGETS() problem
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Wed Dec 07, 2005 4:52 am     Reply with quote

RS232 issues are a frequent topic on this forum. The solution (if it isn't fixing the hardware interface) often comes from the programmer finally understanding that the communications are asynchronous. That means no matter which line of your code you are looking at there is the potential of a character being received at that very exact instant. Printf is classic ...while the pic is executing a printf ..a character could be received and probably was unless there is some external handshake to make things synchronous. What is needed is a circular input buffer that is fed one character per call by the smallest ( in terms of code size) RDA ISR that you can write. The circular buffer has to be large enough to catch all the characters that you could receive while doing other things like printf. A search of this forum will turn up any number of good examples of circular buffers. A verbose printf like printf(" hi my extra special even wrote itmyself code has just received an inbound character") will require and equally expansive input buffer to avoid losing the very character of interest.
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Dec 07, 2005 9:10 am     Reply with quote

Your code needs to be reworked. You are modifying and/or processing complex variables both inside and outside the interrupt handler. For example, if you want to be able to process replyStr in the mainline code then you should surround each instance in an enable/disable interrupt sequence.

I suggest you rewrite the interrupt handler to get rid of the FGETS() by using a circular ring buffer or get rid of the handler completely.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
UFAnders



Joined: 13 Apr 2005
Posts: 36
Location: Michigan

View user's profile Send private message Send e-mail Visit poster's website AIM Address

PostPosted: Sat Dec 17, 2005 5:13 pm     Reply with quote

OK folks, here is the code I've been using since my fifth post-->

Code:
//Begin pre-processor directives//
#include <18F2520.h>
#include <string.h>
#fuses INTRC_IO, NOWDT, NOLVP, PUT, NOPROTECT, WDT64
#use delay(clock=8000000)
//#use i2c(MASTER, FORCE_HW, FAST, SCL=PIN_C3, SDA=PIN_C4)
#use rs232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_B0, RCV=PIN_B1, STREAM=hwrs232/*, ERRORS, force_sw*/)
#use rs232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_A0, RCV=PIN_A1, STREAM=swrs232, INVERT)

#DEFINE UUID "1101"
#DEFINE COD "00000001"
#DEFINE RTS PIN_C0
#DEFINE CTS PIN_C1
#DEFINE RESET PIN_C2

#ZERO_RAM
//End pre-processor directives//

int1 replyFlag=0;
signed int8 replyCounter=0;
int8 i,j,k;
int16 i16,j16,k16;
char replyStr[64], strTemp[16];

int8 processReplies(int8);

void main()
{
   //Begin startup routine//
   SETUP_ADC_PORTS(NO_ANALOGS);
   setup_oscillator(OSC_8MHZ);
   output_low(PIN_C2);
   delay_ms(250);
      
   output_high(PIN_C2);   //reset the BT module
   delay_ms(10);
   output_low(PIN_C2);
   delay_ms(500);
   
   //enable_interrupts(INT_RDA);
   //enable_interrupts(GLOBAL);
   disable_interrupts(GLOBAL);
   
   fprintf(swrs232, "\r\n\n<Program started>\r\n\n");
   
   fprintf(hwrs232, "AT\r");

   fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   processReplies(1);
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATSN,Eros123\r");
      
   fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   processReplies(1);
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATSI,2\r");
   
   fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   processReplies(1);
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATSC,00000001\r");
   
   fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   processReplies(1);
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATUCL\r");
   
   fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   processReplies(1);
   replyFlag=0;
   
   delay_ms(250);
   fprintf(hwrs232, "ATDI,1,00000000\r");
      
   fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   processReplies(1);
   replyFlag=0;
   
   //while(replyFlag == 0);
   fgets(replyStr, hwrs232);
   //output_B(processReplies(2));
   processReplies(2);
   replyFlag=0;
   
   fgets(replyStr, hwrs232);
   fprintf(swrs232, "%s\r\n", replyStr);
   processReplies(2);
   replyFlag=0;
   
   //End startup routine//
   
   fprintf(swrs232, "\r\n\n<Program finished>\r\n\n");
   
   while(1)
   {
      output_high(PIN_A4);
      delay_ms(250);
      output_low(PIN_A4);
      delay_ms(250);
   }
}

int8 processReplies(int8 expected)
{
   signed int8 temp;
   
   if(expected == 1)
   {
      strcpy(strTemp, "OK");
      //fprintf(swrs232, "%s\r\n", strTemp);
      temp = strncmp(strTemp, replyStr, 2);
      fprintf(swrs232, "%d\r\n", temp);
   }
   else if(expected == 2)
   {
      strcpy(strTemp, "DONE");
      //fprintf(swrs232, "%s\r\n", strTemp);
      temp = strncmp(strTemp, replyStr, 4);
      fprintf(swrs232, "%d\r\n", temp);
   }
   return temp;
}


As you can see, I am only using FGETS() and the PIC is returning strings of either "O" or nothing, both of which should be "OK". I have tried everything in regards to level shifting that I know of, even though I am running both the PIC and the BT module at 3.3v, from the same regulator capable of supplying 500mA. I even ran the TX of the BT module through a MAX232 running at 5v looped back into the MAX232 and out to the PIC with the same results.

I'm getting close to jumping to ATMEL or another platform so I can read strings properly from this module!

SOME IMPORTANT NOTES:

1. I have moved the PIC-side rs232 pins to TTL I/O pins, in response to a user speaking about ST pins being less sensitive.

2. When I run the TX on the BT module to HyperTerminal via a MAX232, I get all strings perfectly.

3. The BT module always responds correctly to the PIC or HyperTerminal issued modem commands.

4. I am about to set myself ablaze.

Please lend me your suggestions, I simply cannot figure this out on my own. Thank you so much for your support!
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 Previous  1, 2
Page 2 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