|
|
View previous topic :: View next topic |
Author |
Message |
NAVID
Joined: 14 Jun 2017 Posts: 28
|
|
Posted: Sat Dec 01, 2018 10:55 am |
|
|
dluu13 wrote: | You are right that unfortunately, the manual does not say much about this.
With the RECEIVE_BUFFER option, the circular buffer and the RDA interrupt for placing characters into the receive buffer are automatically generated. You don't need to declare the buffer, or write the ISR. So all you should need is something like this:
Code: | int main(void)
{
char a;
while(1)
{
if(kbhit())
{
a=getc();
// do stuff with a. You could even put your loop here.
}
}
} |
kbhit() evaluates as true if there are new characters in the buffer, and false if there are not.
The main point of this is to move the slow for loop out of the RDA interrupt because interrupt routines are meant to be fast.
Also, I just noticed you might not have found "bkhit()" because it is actually "kbhit()". It is in the manual along with the rest of the built-in functions. |
Hi, its work but i have 1 problem...its not work properly.
i dont know how to explain (((:
When i send characters it dont show them and wait until to receive a number!!
like this:
kjasdjcnasjdlfkasjdcnsjn :it dont show anything on lcd but when i send '1'
after all these characters its show " kjasdjcnasjdlfkasjdcnsjn1"
and rs232 option:
#use rs232(baud=9600,parity=N,xmit=PIN_c6,rcv=PIN_c7,bits=8,stream=PORT1,timeout=100,RECEIVE_BUFFER=64)
and its my code:
Code: |
while(TRUE)
{
lcd_gotoxy(1,1);
if(kbhit())
{
a=getc();
lcd_gotoxy(1,1);
printf(lcd_putc,"%s ",a);
}} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sat Dec 01, 2018 11:28 am |
|
|
Suite of things:
First, though the buffering is automatic, you do need to have
'enable_interrupts(GLOBAL);' at the start of your main, or the buffering will
not be enabled.
Then you don't show the declaration of 'a', but as shown it should be a char. As such it is _not_ a string, which you try to print. It is just a
single character, which needs to be printed with %c. As with INT_RDA, you need to create a string by writing the characters to an array, and adding the null terminator. The garbage you are seeing displayed is the contents of the memory after where 'a' is stored, until a 0 character is hit.
This latter is really basic programming. You need to get a C textbook, and
read it....
Now you can filter as I describe, with a basic flag. Read the characters. Have a flag set to FALSE, and set it TRUE when you see the line feed after the CMT. While it is FALSE, just throw the characters away and keep looping. Once the flag is set write the characters to an array, until another line feed is seen, then add the NULL termiator, and display. |
|
|
NAVID
Joined: 14 Jun 2017 Posts: 28
|
|
Posted: Sat Dec 01, 2018 3:14 pm |
|
|
Ttelmah wrote: | Suite of things:
First, though the buffering is automatic, you do need to have
'enable_interrupts(GLOBAL);' at the start of your main, or the buffering will
not be enabled. |
i did that before ...
Ttelmah wrote: |
Then you don't show the declaration of 'a', but as shown it should be a char. As such it is _not_ a string, which you try to print. It is just a
single character, which needs to be printed with %c. As with INT_RDA, you need to create a string by writing the characters to an array, and adding the null terminator. The garbage you are seeing displayed is the contents of the memory after where 'a' is stored, until a 0 character is hit. |
yes its char a[32].and i change the %s to %c and its work good.very very tnx.just can you tell me how i can find line feed in the a[32]??
i need to find it and show the characters after line feed ...
Ttelmah wrote: |
This latter is really basic programming. You need to get a C textbook, and
read it.... |
i will but i dont have good source to read...can u Introduction some book??
Ttelmah wrote: |
Now you can filter as I describe, with a basic flag. Read the characters. Have a flag set to FALSE, and set it TRUE when you see the line feed after the CMT. While it is FALSE, just throw the characters away and keep looping. Once the flag is set write the characters to an array, until another line feed is seen, then add the NULL termiator, and display. |
line feed
i need to find it...help me [/quote] |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sat Dec 01, 2018 3:23 pm |
|
|
oops... I had forgotten to mention that you need the enable_interrupts(GLOBAL)
i use this site a lot as basic reference: https://www.tutorialspoint.com/cprogramming/
As for the newline character, it is denoted as '\n' so
if (a[i] == '\n') evaluates as true, then you've found the newline character at index i. If you are storing the entire incoming message, then you can loop through that array until you find '\n' and then print all characters after that. |
|
|
NAVID
Joined: 14 Jun 2017 Posts: 28
|
|
Posted: Wed Dec 05, 2018 12:51 pm |
|
|
dluu13 wrote: | You are right that unfortunately, the manual does not say much about this.
With the RECEIVE_BUFFER option, the circular buffer and the RDA interrupt for placing characters into the receive buffer are automatically generated. You don't need to declare the buffer, or write the ISR. So all you should need is something like this:
Code: | int main(void)
{
char a;
while(1)
{
if(kbhit())
{
a=getc();
// do stuff with a. You could even put your loop here.
}
}
} |
kbhit() evaluates as true if there are new characters in the buffer, and false if there are not.
The main point of this is to move the slow for loop out of the RDA interrupt because interrupt routines are meant to be fast.
Also, I just noticed you might not have found "bkhit()" because it is actually "kbhit()". It is in the manual along with the rest of the built-in functions. |
hi again...
its helped me so much...but i have 1 question
how i can clear RECEIVE_BUFFER ?? and make it empty? |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Wed Dec 05, 2018 12:59 pm |
|
|
To make the circular buffer empty, you can just read from it using getc or similar. Once the character is read, then it is considered to be "gone" and the memory space that the character once held is freed.
kbhit() returns true if there are contents in the circular buffer and false if there are not. So if you just want to purge the buffer you can do something like:
char garbage;
while(kbhit()) garbage=getc(); |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Thu Dec 13, 2018 11:27 am |
|
|
First I defined a buffer like this:
#define BUFFER_SIZE 64 //create buffer
char buffer[BUFFER_SIZE];
To get the characters from the GSM module into the buffer I use this inside RDA interrupt:
Code: |
char tmp;
tmp=getc(); // get received char and thus also clear interrupt flag
buffer[next_in]= tmp; // move received char to the appropriate place in buffer
++next_in; // increment IN pointer
if(next_in==BUFFER_SIZE) { // go back to 0
next_in=0;
};
|
To clear this buffer:
Code: |
void Clear_UART_Buffer() { //
next_in=0;
while (next_in < BUFFER_SIZE){
buffer[next_in] = '\0';
next_in++;
}
}
|
|
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Thu Dec 13, 2018 11:32 am |
|
|
One next_in fell out. It should be:
Code: |
void Clear_UART_Buffer() { //
next_in=0;
while (next_in < BUFFER_SIZE){
buffer[next_in] = '\0';
next_in++;
}
next_in=0;
}
|
and next_in is initialized to zero when it is declared. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Fri Dec 14, 2018 7:02 am |
|
|
To get only your message to the buffer:
Code: |
#define BUFFER_SIZE 64 //create buffer, change to your size
char buffer[BUFFER_SIZE];
int8 gsm_state = 0;
int1 MESSAGE = 0;
int1 buffer_to_small = 0;
int8 next_in = 0;
char tmp;
// this is in your init |
Inside your INT_RDA:
Code: |
// put this inside RDA interrupt
// looking for a message that looks like this
// +CMT: "+989375091182","","18/11/28,17:21:07+14"
// Hello
// it always begins with "+CMT"
tmp=getc(); // get the character
switch (gsm_state) {
// ----------------------------------------------------------------------
// wait the initial '+'
case 0:{
if(tmp == '+'){ //we have "+", could be "+CMT"
gsm_state = 1; //expecting "C"
}
else{
gsm_state = 0; // wrong character
}
break;
}
// ----------------------------------------------------------------------
case 1:{
if(tmp == 'C'){ //we have "C", could be "+CMT"
gsm_state = 2; //expecting "M"
}
else{
gsm_state = 0; // wrong character came, reset state machine
}
break;
}
// ---------------------------------------------------------------------
case 2:{
if(tmp == 'M'){ //we have "M", could be "+CMT"
gsm_state = 3; //expecting "T"
}
else{
gsm_state = 0; // wrong character came, reset state machine
}
break;
}
// -------------------------------------------------------------------
case 3:{
if(tmp == 'T'){ //we have "T", could be "+CMT"
gsm_state = 4; //expecting ":"
}
else{
gsm_state = 0; // wrong character came, reset state machine
}
break;
}
// --------------------------------------------------------------------
case 4:{
if(tmp == ':'){ //we have ":", so it is "+CMT:"
gsm_state = 5; //expecting line feed
}
else{
gsm_state = 0; // wrong character came, reset state machine
}
break;
}
// -------------------------------------------------------------------
case 5:{
if(tmp != '\n'){ // just wait here for the first new line, where your message begins
gsm_state = 5; //
}
else{
gsm_state = 6; // got new line, next characters will be your message
}
break;
}
// ------------------------------------------------------------------
case 6:{
if(tmp != '\n'){ // until you see the second new line,
buffer[next_in]= tmp; // move received char to the buffer
next_in++; // increment IN pointer
if(next_in == BUFFER_SIZE + 1) { // not enough space left in the buffer for the trailing null, even if this was the last character of the message
next_in = 0; // the message will most likely be incorrect
gsm_state = 0; // you should never come here
buffer_to_small = 1; // maybe inform main that the buffer wasn't large enough?
}
}
else{ // got the second new line, your message should be in the buffer
gsm_state = 0; // reset state machine
strcat(buffer, "\0"); // add null at the end of the message
MESSAGE = 1; // inform main that there is a message in the buffer
next_in = 0;
}
break;
}
} // switch brace
// ----------------------------------------------------------------------
|
Best regards |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Fri Dec 14, 2018 1:01 pm |
|
|
This can overflow the buffer before it decides it has overflowed the buffer.
Remember with a buffer size of '64', you can only store data from 0 to 63.
Testing for 'next_in' being equal to 65, is too late.... |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Fri Dec 14, 2018 5:04 pm |
|
|
True. I started counting from 1, not 0 :-).
Thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sat Dec 15, 2018 4:29 am |
|
|
I think we have all done that sometimes... |
|
|
NAVID
Joined: 14 Jun 2017 Posts: 28
|
|
Posted: Mon Dec 17, 2018 9:29 am |
|
|
PrinceNai wrote: | True. I started counting from 1, not 0 :-).
Thanks |
thank you
its helped me a lot |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Mon Dec 17, 2018 1:04 pm |
|
|
Quote: |
else{ // got the second new line, your message should be in the buffer
gsm_state = 0; // reset state machine
strcat(buffer, "\0"); // add null at the end of the message
MESSAGE = 1; // inform main that there is a message in the buffer
next_in = 0;
}
break;
}
} // switch brace |
I just noticed another mistake. If the second message is shorter than the first one or the buffer wasn't empty, the bolded line doesn't add NULL to the correct position. You should use:
Code: | buffer[next_in] = '\0'; |
instead.
Please correct me if I'm wrong.
Best regards,
Samo |
|
|
|
|
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
|