|
|
View previous topic :: View next topic |
Author |
Message |
yarenler
Joined: 05 Jan 2019 Posts: 8
|
Bluetooth connection is lost after a certain time |
Posted: Wed Apr 01, 2020 5:13 pm |
|
|
I check the 16f877a integration with the phone. I wrote some commands in the interrupt, but the connection is disconnected after a while.
The code I wrote is as follows:
Code: |
#include <16f877A.h>
#include <stdlib.h>
#fuses NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay (clock = 4000000 )
#use fast_io(A)
#use fast_io(B)
#use fast_io(D)
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7,STOP=1)
#define a0 pin_A0
#define a1 pin_A1
char apple;
int8 red=3;
char string[10];
int i;
#int_rda
void serial_isr(){
apple=getc();
string[0]=apple;
switch (apple){
case 'F':
Output_high(PIN_D1);
printf("\r\n W lamp on");
break;
case 'B':
Output_low(PIN_D1);
printf("\r\n w lamp off");
break;
}
i = atoi(string); // 1 is now 123
if((i==1) && (i!=0) ){red=1;printf("\r\n1'a Q\a");}
if((i==2) && (i!=0) ){red=2;printf("\r\n2'a W");}
else{
disable_interrupts(int_rda);
clear_interrupt(int_rda);
}
disable_interrupts(int_rda);
clear_interrupt(int_rda);
}
void main()
{
enable_interrupts(global);
enable_interrupts(int_rda);
set_tris_a(0xff); set_tris_b(0x00); set_tris_d(0x00);
output_a(0); output_b(0); output_d(0);
while(true)
{
enable_interrupts(int_rda);//enable_interrupts(global);
if(red == 1){output_high(PIN_D0); }
if(red == 2){output_low(PIN_D0); }
if(input(a0)==1){
output_high(PIN_D0);
while(input(a0)==1);
}
if(input(a1)==1){
output_low(PIN_D0);
while(input(a1)==1);
}
}
}
|
_________________ esen_seher_yeller |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1349
|
|
Posted: Wed Apr 01, 2020 6:35 pm |
|
|
Lots of basic problems to clean up before we can debug here:
1. Interrupts should NOT have any printf statements in them.
2. You are not passing a string into atoi(). A string requires a null character to terminate it. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Thu Apr 02, 2020 5:09 am |
|
|
also ...
3. you NEED to add 'ERRORS' to the options to using RS232.
Quote: | #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7,STOP=1) | NEEDS to be:
Code: | #use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7,STOP=1,ERRORS) |
4. You should change the 'fuse' NOPUT to PUT. The small delay does help the PIC to get 'organised'. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1349
|
|
Posted: Thu Apr 02, 2020 9:07 am |
|
|
Also for the sake of debugging, remove all the fast_io() and set_tris() calls. Let's let the compiler handle setting input/output and take out a possible problem vector. |
|
|
yarenler
Joined: 05 Jan 2019 Posts: 8
|
|
Posted: Thu Apr 02, 2020 5:48 pm |
|
|
jeremiah and temtronic thanks.
jeremiah:
1. Interrupts should NOT have any printf statements in them.
solved:
The connection was not interrupted when I removed the printf statements in Interrupt.
but 2. not solved:
I couldn't run it except the code below. I can't get a 2-digit number as a string. For example: It takes 12 string expressions 1, the first digit, and 21 takes 2 expressions.
Code: |
#int_rda
void serial_isr(){
apple=getc();
string[0]=apple;
i = atoi(string); // 1 is now 123
if((i==1) && (i!=0) ){red=1;}
if((i==2) && (i!=0) ){red=2;}
if((i==12) && (i!=0) ){red=3;}// not working this line i=1 is working
else{
disable_interrupts(int_rda);
clear_interrupt(int_rda);
}
}
|
temtronic:
The problem was partially resolved and I changed the NOPUT command to PUT. Will there be a problem in the future if we do not use the ERRORS expression in RS232 options, which is your instruction? _________________ esen_seher_yeller |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Fri Apr 03, 2020 1:03 am |
|
|
You code is only ever putting the character into the first location of
the buffer. string[0].
To build a 'string', your serial code needs to write the first character
received into the first location, then the second into the second, and the
third into the third, etc. etc..
Then normally when you receive a line feed ('\r'), put in the null
terminator and do the tests. So, something like:
Code: |
#int_rda
void serial_isr(void)
{
static int8 ctr=0;
apple=getc();
string[ctr++]=apple; //write to successive characters
if (apple=='\r') //carriage return seen
{
string[ctr]='\0'; //add null terminator to string
//Now only do the string tests when the line feed is seen
i = atoi(string); // 1 is now 123
if((i==1)
{red=1;}
if((i==2)
{red=2;}
if((i==12)
{red=3;}// not working this line i=1 is working
ctr=0; //restart counter
}
if (ctr>18)
ctr=18; //ensure buffer cannot overflow if no CR
}
|
You want to leave the interrupt always enabled. The compiler automatically
clears it.
You need to type number<ENTER> to work this way. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Fri Apr 03, 2020 5:02 am |
|
|
re: ERRORS
This option is required to keep the HW UART from 'locking up' or 'freezing'. What should happen is that some external RS232 device ( PC, other PIC, modem) sends some data to the PIC. The UART has a hardware 'buffer' of 2 or 3 bytes( characters). As long as your program reads the UART faster than they come in ,no problem.
However, lets say a 'burst' of 10 bytes comes in ( data from a modem..) and your program is busy doing other things, the HW UART buffer gets filled and the 3rd or 4th character 'overflows' the buffer. The HW UART 'locks up' ( stops working).
The ERRORs option takes care of this 'overflow' problem.
You can of course write your own code to do the same, but it's easier just to allow CCS to do it.
Different PICs have different sizes of buffers and this only applies to HardWare UARTs. If using a SW UART ,YOU have to take care of EVERY aspect of the communications. |
|
|
|
|
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
|