View previous topic :: View next topic |
Author |
Message |
ketron82
Joined: 07 Jun 2010 Posts: 36
|
RS232 and gets() problem |
Posted: Tue Jun 22, 2010 8:10 pm |
|
|
Dear Friend...
I need your help.
I have some problem with 16F877A and RS232 communication.
This is the code:
Code: |
#include "C:\Programmi\PICC\Examples\fabio\siemens.h"
#include <stdio.h>
#include <stdlib.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8000000) // 8Mhz Crystal is Used
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// TODO: USER CODE!!
char string[30];
while(1)
{
printf("HELLO WORLD \n\r");
delay_us(50);
gets(string);
printf("%s =String \n",string);
printf("TEST");
}
}
|
I simulate it with PIC SIMULATOR IDE and I saw that the pic have problem with gets() function because it not execute the line -> printf("TEST");
In my example there is a while(1)....if I cancel the gets() function and simulate...I can run the loop!!
Why the gets() block the while loop??
How is correction for read array from USART??
Many thanks
Fabio Patriarca |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 22, 2010 8:52 pm |
|
|
Read the gets() section in the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Quote: |
gets( )
Reads characters (using GETC()) into the string until a RETURN
(value 13) is encountered. The string is terminated with a 0. Note that
INPUT.C has a more versatile GET_STRING function.
|
It waits until you press the Enter key. |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Wed Jun 23, 2010 5:27 am |
|
|
PCM programmer wrote: | Read the gets() section in the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Quote: |
gets( )
Reads characters (using GETC()) into the string until a RETURN
(value 13) is encountered. The string is terminated with a 0. Note that
INPUT.C has a more versatile GET_STRING function.
|
It waits until you press the Enter key. |
Ok...thanks a lot dear PCM Programmer.
And now...I have to read incoming sms form SIEMENS phone and one other question!
If I would to not stop my While(1)....I use if (kbhit()) or a RS232 Interrupt??
Many thanks!!
Fabio Patriarca
Callsign: IZ0CBG |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Jun 23, 2010 2:17 pm |
|
|
The "standard" way to do something like this is to read bytes into a circular buffer with a RS232 interrupt. When a byte that signals the end of a message is read by the interrupt it sets a flag. The main program periodically checks the flag and if it finds it set, the main program reads the message from the buffer and clears the flag. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Sat Jun 26, 2010 2:25 am |
|
|
SherpaDoug wrote: | The "standard" way to do something like this is to read bytes into a circular buffer with a RS232 interrupt. When a byte that signals the end of a message is read by the interrupt it sets a flag. The main program periodically checks the flag and if it finds it set, the main program reads the message from the buffer and clears the flag. |
Many thanks....I was out for work!!
I will make tests and if I will have other problems....I post it here!
Thanks a lot
Fabio
IZ0CBG |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Sat Jun 26, 2010 10:01 pm |
|
|
Pcm programmer....I have now one strange problem!!!
I have made a simple code with IRDA interrupt + gets() and it works very fine in PIC <==> PC configuration!!
When I connect the Siemens sl55 or c35i or other phone, the CR character is not read and I cannot go out of interrupt function!! It's the same if I insert gets() in the main without using interrupt!!
Its more strange because if I connect the phone to the PC and I use Hyperterminal to comunicate... I see that the CR character is sent by the phone right way!! Again.... If I call the phone, in Hyperterminal I see:
RING
RING
RING
etc.
Why is my pic is not able to read the CR??
Many thanks again!!
Fabio
IZ0CBG |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 27, 2010 12:07 am |
|
|
Post your short test program for the PIC that is supposed to detect the
CR character from the phone. Show the #fuses, #use delay, and
#use rs232 statements. In other words, show the complete (short)
test program.
Also post your compiler version. |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Sun Jun 27, 2010 4:05 am |
|
|
Thanks PCM Programmer,
my code is it:
Code: | #include "C:\Programmi\PICC\Examples\fabio\siemens.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8000000) // 8Mhz Crystal is Used
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#include <input.c>
#include <glcd.c>
#int_rda
void isr()
{
char string[70];
char *msg;
gets(string);
msg=string;
glcd_text57(5,10,msg,1,1);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// TODO: USER CODE!!
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
glcd_init (ON);
delay_us(100);
glcd_fillScreen (0);
//char string[70];
char pdu1[70];
char pdu2[70];
//char *msg;
//strcpy (pdu1, "04D2D8D309");
//strcpy (pdu2, "05D2D8D36804");
delay_ms(100);
printf("at\r\n");
delay_ms(1000);
while(1)
{
delay_ms(1000);
glcd_fillScreen (0);
//if (kbhit())
// {
//gets(string);
//msg=string;
//gets(string);
//msg=string;
//printf("atd 155\r");
//glcd_text57(5,10,msg,1,1);
//delay_ms(1000);
// }
}
} |
I repeat that the problem is only between PIC <---> SIEMENS because PIC <---> PC work very well!!
If I send commad to the siemens directly by PC....the command is execute very well and I can see on the GLCD any casual string written by keyboard!
If I send command to the SIEMENS directly by PIC....It execute the command but on the GLCD generally I cannot display the response!!
If I call the siemens by another cellphone.....it type on the serial line (saw by Hyperterminal) the string:
Code: |
RING
RING
RING
RING
RING
ecc. |
In the GLCD I see the first RING because the GLCD is not clean every second:
Code: |
delay_ms(1000);
glcd_fillScreen (0); |
Any idea?? what are my many errors?
Many Tanks
Fabio
IZ0CBG |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Sun Jun 27, 2010 11:34 am |
|
|
Dear PCM....I think that I found the problem!!
I saw that cellphone reply with this format:
Code: |
Sent: at
Received: 0x0D 0x0A 0x4F 0x4B 0x0D 0x0A
|
and i the last character received is 0A (LINE FEED -LF )....afther the 0x0D (CR - CARRIAGE RETURN) that represent the end of the string!!
So....0x0A is interpreted as a new string!!
How can I solve this problem?? I try to use getch() in INTRDA without success...for the moment!!
PCM PROGRAMMER can you set me on the right way
Fabio
IZ0CBG |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Sun Jun 27, 2010 12:09 pm |
|
|
I cannot display anything in this way??
Comment??
TNX
Code: | #include "C:\Programmi\PICC\Examples\fabio\siemens.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8000000) // 8Mhz Crystal is Used
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,errors)
#include <input.c>
#include <glcd.c>
#int_rda
static char string[30];
int i;
static char *msg;
void isr()
{
//for(i=0;i>=2;i++)
//{
string[i++]=getch();
i++;
//}
//gets(string);
}
#priority rda
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// TODO: USER CODE!!
glcd_init (ON);
delay_us(100);
glcd_fillScreen (0);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
printf("at\r\n");
while(1)
{
msg=string;
glcd_text57(5,10,msg,1,1);
delay_ms(300);
glcd_fillScreen (0);
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 27, 2010 1:30 pm |
|
|
You should not address your posts to me only. Then other people
may not reply.
You should let everyone have the opportunity to give you a reply. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Jun 27, 2010 2:34 pm |
|
|
Code: | #int_rda
static char string[30];
int i;
static char *msg;
void isr()
{ | What are you doing here???
Your code was fine, but now you suddenly put code between the '#int rda' and 'void isr { '. Why??
I don't know what the compiler will make of this, but it is not what it should be like.
Code: | string[i++]=getch();
i++; | i is not initialized. You are writing to random memory.
Second problem is that you are incrementing i two times.
You have only one interrupt, so why add a priority directive? You are making things more complicated when there is no need to. Keep It Simple !!
Code: | setup_spi(SPI_SS_DISABLED); | Not a big problem, but the CCS Wizard generates invalid setup code here. The line should be changed to:
SherpaDoug wrote: | The "standard" way to do something like this is to read bytes into a circular buffer with a RS232 interrupt. | Have you tried this advice? It is the best way for receiving data in the PIC. See the example ex_sisr.c for how to do this.
You can combine it with code from input.c to receive strings.
General comment is that a computer will exactly do what you tell it to do, this is often not the same as what you want it to do.
Be more careful in your programming. You are making a lot of sloppy mistakes.
Last edited by ckielstra on Sun Jun 27, 2010 2:40 pm; edited 1 time in total |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Sun Jun 27, 2010 2:36 pm |
|
|
Sorry for the error! Tnx again to all of the forum! Fabio |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Mon Jun 28, 2010 7:28 pm |
|
|
TNX ckielstra...I have changed my program and I read the CCS example for circular buffer.
Now my code has other problem:
The routine " strcmp (msg , ring) == 0 " is always true or she doesn't work good...because I read in output "Activated" at every "RING" and not only 5 "RING".
How is the problem??
Anyone can help me?
Code: |
#include "C:\Programmi\PICC\Examples\fabio\siemens.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8000000) // 8Mhz Crystal is Used
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,errors)
#include <input.c>
#include <glcd.c>
char string[30];
char temp[10];
char *ring[10];
int temps;
char *msg;
int i=0;
int a=0;
int c=0;
int nr=0;
#int_rda
void serial_isr() {
a=0;
temp[0]=getchar();
temps=(int) temp[0];
if(temps==0x0D)
{
a=1;
c++;
}
if(temps==0x0A)
{
a=1;
c++;
}
if(a==0)
{
string[i]=temp[0];
i++;
if(i==69)i=0;
a=0;
}
if(c==4)
{
i=0;
c=0;
}
msg=string;
strcpy (ring, "RING");
if ( strcmp (msg , ring) ==0)
{
nr++;
glcd_text57(5,40,msg,1,1);
}
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// TODO: USER CODE!!
glcd_init (ON);
delay_us(100);
glcd_fillScreen (0);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
printf("at\r\n");
delay_us(50);
while(1)
{
if (nr>5)
{
// Enable some thing like Relè ecc
printf("Activated");
nr=0;
}
msg=string;
glcd_text57(5,10,msg,1,1);
delay_ms(1000);
glcd_fillScreen (0);
}
|
Fabio
IZ0CBG |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Tue Jun 29, 2010 4:08 am |
|
|
Anyone can help me??
Many tnx |
|
|
|