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

Can't receive '\0' null character in serial(rs232)

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
isv10



Joined: 29 Aug 2010
Posts: 15

View user's profile Send private message

Can't receive '\0' null character in serial(rs232)
PostPosted: Tue Jul 17, 2018 5:13 am     Reply with quote

Hello. My project with pic16f1829.
Receiving string with int_rda but can't detect null \0 char.
Someone has a comment ?



#define BUFFER_SIZE 32
int1 have_string=FALSE;
char string[BUFFER_SIZE];
int index=1;



#int_rda
void serial_isr() {
char c;
c=getc();

if(c=='\0')
{
have_string=true;
string[index]=c;
return;
}
string[index]=c;
if(index >= BUFFER_SIZE)
index=index-1;
else
index++;
printf("H");
}





void main()
{
setup_wdt(WDT_1S); //~2.0 ms reset
restart_wdt();
// setup_adc_ports(sAN2|sAN4|sAN5);
// setup_adc(ADC_CLOCK_DIV_2);
//setup_timer_2(T2_DIV_BY_1,4,1); //1.0 us overflow, 1.0 us
enable_interrupts(global);
enable_interrupts(int_rda);
restart_wdt();
output_high(PIN_C7);
delay_ms(500);
output_low(PIN_C7);
delay_ms(500);
output_low(PIN_C7);
//printf("test code");
restart_wdt();

while(TRUE)
{
restart_wdt();
if(have_string)
{
puts(string);
have_string=FALSE;
}
}
}[/b]
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 5:31 am     Reply with quote

general comments..
1) no #use RS232(...options...) Pre prosessor directive. That's kinda important

2) delete all the WDT related code. NOT required

3) no #include device header. That's kinda required too !

4) use the [code] button( top center of this page) when posting code. Really helps us 'see' the code !

5) you'll need to add 'ERRORS' to the missing #Use RS232(...) options

Probably more but coffee's ready !
Jay
isv10



Joined: 29 Aug 2010
Posts: 15

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 5:48 am     Reply with quote

Thanks for your reply.
This code works fine but can't detect '\0' null char. When i send test string with PC and return it with puts() in int_rda it works good. But when i want to control string with the following code it can't detect '\0'.
Code:

#include <16F1829.h>
#device ADC=10
#include <string.h>
#include <stdlib.h>

#FUSES WDT                      //Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(internal=16MHZ,restart_wdt)
#use rs232(baud=9600,xmit=PIN_B7,rcv=PIN_B5,UART1,RESTART_WDT)

#use pwm(CCP1,FREQUENCY=40000)

#define BUFFER_SIZE 32
int1 have_string=FALSE;
char string[BUFFER_SIZE];
int index=1;



#int_rda
void serial_isr() {
   char c;
   c=getc();
   
   if(c=='\0')
   {
   have_string=true;
   string[index]=c;
   return;
   }
   string[index]=c;
   if(index >= BUFFER_SIZE)
   index=index-1;
   else
   index++;
   printf("H");
}
   




void main()
{
   //setup_wdt(WDT_1S);      //~2.0 ms reset
   restart_wdt();
  // setup_adc_ports(sAN2|sAN4|sAN5);
  // setup_adc(ADC_CLOCK_DIV_2);
  // setup_timer_2(T2_DIV_BY_1,4,1);   //1.0 us overflow, 1.0 us interrupt
   enable_interrupts(global);
   enable_interrupts(int_rda);
   restart_wdt();
   
output_high(PIN_C7);// for test
delay_ms(500);
output_low(PIN_C7);
delay_ms(500);
output_low(PIN_C7);

  restart_wdt();
 
  while(TRUE)
   {
  restart_wdt();
  if(have_string)
     {
       puts(string);
       have_string=FALSE;
     }
   }
  }
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 6:26 am     Reply with quote

OK, now get rid of the WDT AND add 'errors' to the USE RS232.

The WDT is 'about 2ms', probably +-50-100%, so it could be tripping at 1ms...
hmm...9600 baud is 'about' 1 character per 1ms
so it is possible the WDT is resetting the PIC.

Without the 'ERRORS' option, the HW UART will lockup after the 2-3 characters. Now I don't use that PIC and don't know IF the HW UART is being used. If it is a 'software' UART, then the ISR won't work....

Jay
isv10



Joined: 29 Aug 2010
Posts: 15

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 6:46 am     Reply with quote

Thanks for your help. I test WDT change.
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 6:49 am     Reply with quote

First, learn to use the code buttons....
Code:

#define BUFFER_SIZE 32
int1 have_string=FALSE;
char string[BUFFER_SIZE];
int index=1; //This is wrong. Remember your array starts at 0....

#int_rda
void serial_isr(void) {
   char c;
   c=getc();

   if(c=='\0')
   {
       have_string=true;
       string[index]=c;
       return;
   } 
   string[index]=c;
   if(index >= BUFFER_SIZE)
      index=index-1;
   else
      index++;
   printf("H");
}


Except for the error of having the index starting at 1, not 0, this will basically work.

There is another issue though on index. Imagine it is 31. You test. It is not>=BUFFER_SIZE, so it is incremented to 32. The next time the interrupt executes you are writing to string[32], which will result in values being corrupted as this is beyond the end of the array.....
Code:

   if(++index >= BUFFER_SIZE)
      index=index-1;

This avoids this problem. Incrementing before the test.

However the question is how you are sending the '\0'?. Remember a string printed from C, will not send the null terminator normally....
isv10



Joined: 29 Aug 2010
Posts: 15

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 7:22 am     Reply with quote

Hello Ttelmah and thanks for your help. I changed index=1 and forget to correct it. I send string from pc to micro (with serial port terminal) and then try to find '\0' from end of string. But when i send for example 3 char string, program return (HHHH) or send 5 char string it return (HHHHHH). It means i have 4 interrupt for 3 char string, and 6 interrupts for 5 char string. I want to detect end of string.
Ttelmah



Joined: 11 Mar 2010
Posts: 19559

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 7:29 am     Reply with quote

Are you absolutely sure your program is sending the NULL?.
Terminal programs etc., normally won't. If you send a string with something like sendln, it prints the string, and then a line feed, not a NULL...
You need to find out what your source program is actually sending.
It is extremely rare for PC programs to actually print the NULL.

Put it in perspective, CCS won't either.
If you print a string with:

printf("%s", string);

The NULL won't be printed.
isv10



Joined: 29 Aug 2010
Posts: 15

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 7:40 am     Reply with quote

How can i find it ? I try with '\n' and no response. When i send string from terminal, for example (test) string i receive (HHHHHtest)
and for another string in new line receive...
temtronic



Joined: 01 Jul 2010
Posts: 9250
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 7:42 am     Reply with quote

Post the name of the 'terminal program' on the PC. Should be easy to figure out how to add the null to the transmitted data...

Jay
isv10



Joined: 29 Aug 2010
Posts: 15

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 7:59 am     Reply with quote

Serialport Terminal
by coad.net
isv10



Joined: 29 Aug 2010
Posts: 15

View user's profile Send private message

PostPosted: Tue Jul 17, 2018 11:51 pm     Reply with quote

Hi. Problem was solved.

Windows is backward compatible with MS-DOS and used the CR-LF convention because MS-DOS was compatible with CP/M-80 which used the CR-LF convention because that was how you drove a printer (because printers were originally computer controlled typewriters).
The result is in Windows based terminal, send '\r\n' or '\n' end of string. Thus i use '\r' in my program and it works very good!!!!!!!!!!!!!!!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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