![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
erpgc82
Joined: 02 May 2020 Posts: 73
|
Serial interrupt RX-C7 crashes after sending TX-C6 char PC |
Posted: Thu Mar 25, 2021 3:42 pm |
|
|
Hello friends, I'm having a problem here and I'm not able to solve it, I don't know what happens, if it is some bit of some transmission register that I must clear, if it is the serial interrupt that I need to clear clear_interrupts (INT_RDA) ;.
I put delay_ms (1) as a test, after sending the character.
I've done clear_interrupts (INT_RDA); after re-enabling the serial interrupt.
Anyway, I've done everything and nothing works.
Here is just a piece of the code.
Today I can get the string that arrives at the RX (hardware) I do what I have to do with it and send it to the PC via TX (hardware) and it works perfectly.
The response variable, if it is 1 (TRUE) when the PIC reads sensors / input pins, it must send a certain character to the PC, only when doing this the serial interrupt #INT_RDA stops working.
If the response variable is 0 (FALSE), that is, never send characters to the PC, the serial interrupt works perfectly. Note¹: it always stops when a certain number of characters arrives, and then right after a certain function that takes about 5 seconds to occur, the serial interruption is reactivated and this works PERFECTLY.
I'm not getting to know why it hangs / stops after sending a character to the PC. Note¹: Whenever I send a character to the computer, the serial interrupt is activated (at least it was supposed to be) because until then the PIC had not read anything from it and so it was not deactivated.
Code: |
#include <16F876a.h>
#case
#use delay(clock=10000000)
#fuses HS,NOWDT, PUT, BROWNOUT, NOLVP
#use rs232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, stop=1, ERRORS)
int1 returns=1;
char X='X';
char Y='Y';
#INT_RDA
void serial_isr()
{
restartRS232(); // It's unnecessarily here
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1)%BUFFER_SIZE;
if(next_in==next_out) next_in=t;
}
BYTE bgetc()
{
BYTE c;
while(!bkbhit);
c=buffer[next_out];
next_out=(next_out+1)%BUFFER_SIZE;
return(c);
}
void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
while(TRUE)
{
if(bkbhit)
{
c=bgetc();
if(c=='0')
{
key_card=TRUE;
clean_keyboard();
output_high(BEEP);
delay_ms(40);
output_low(BEEP);
barcode_buffer[0]=c;
barcode_buffer[1]=bgetc();
barcode_buffer[2]=bgetc();
barcode_buffer[3]=bgetc();
barcode_buffer[2]=0;
printf("%c%c%c%c%c%cC\n\r",barcode_buffer[0],barcode_buffer[1],barcode_buffer[2],barcode_buffer[3]);
d_int_rda=FALSE;
disable_interrupts(INT_RDA);
read_code();
}
/*******************************************************************************************/
if((returns)&&(!input(SENSOR_OUT))) printf("%c\r\n",X);
if((returns)&&(!input(SENSOR_IN))) printf("%c\r\n",Y);
}
}
}
| [/code] _________________ Gradually you will go far with persistence, will and determination! |
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
I edited the code better |
Posted: Thu Mar 25, 2021 8:10 pm |
|
|
Observation. the time_td variable is reported as true (1) within the read_code () function as this function only displays the code on the LCD display and returns to the while, then makes contact and then returns to the standard message, and automatically enabling the enable_interrupts function (INT_RDA);
I also tried before rehabilitating using the function
clear_interrupts (INT_RDA); but it's no use, the problem is sending a simple character "printf (" X ");" and the interruption doesn't work again.
Code: |
#include <16F876a.h>
#case
#use delay(clock=10000000)
#fuses HS,NOWDT, PUT, BROWNOUT, NOLVP
#use rs232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, stop=1, ERRORS)
#include "display_8bits16f876.c"
#define BUFFER_SIZE 32
#define BEEP PIN_A2
#define SENSOR_IN PIN_A3
#define SENSOR_OUT PIN_A4
#define bkbhit (next_in!=next_out)
BYTE next_in = 0;
BYTE next_out = 0;
BYTE buffer [BUFFER_SIZE];
int8 barcode_buffer [10];
int1 returns = 1; // short int returns=TRUE; // Checks whether to send characters to the PC software
int1 time_Td = 0; // Checks whether to enter the time count
int1 d_int_rda = 0; // checks if the serial interrupt is disabled
int1 msg_default = 0; // checks whether to display the standard message on the LCD
int8 code = 0;
char X='X';
char Y='Y';
void restartRS232();
void msg_Default();
#INT_RDA
void serial_isr()
{
restartRS232(); // It's unnecessarily here
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1)%BUFFER_SIZE;
if(next_in==next_out) next_in=t;
}
BYTE bgetc()
{
BYTE c;
while(!bkbhit);
c=buffer[next_out];
next_out=(next_out+1)%BUFFER_SIZE;
return(c);
}
void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);
setup_timer_1(T1_DISABLED);
set_timer0(11);
display_ini();
while(TRUE)
{
if(d_int_rda) // check if it is to re-enable the interruption and if it is true, re-enable
{
enable_interrupts(INT_RDA); /* Without considering, that the function enable_interrupts (INT_RDA);
* already starts in main (), but if it is disabled, then re-enable*/
delay_ms(1);
d_int_rda=FALSE;
}
if(!msg_default) msg_Default(); // if you are not displaying the default message, then display
if(time_Td)
{
if(tmr0if)
{
tmr0if=0;
set_timer0(11); // initializes timer0
code++; // increments the variable that will define the time that the code will be displayed on the LCD
}
}
if(code>=200)
{
tmr0if=0;
code=0;
msg_Default(); // After a XX time displaying the characters on the LCD, it then returns to the standard message
} /**************************************************
* It turns out that, if the situations have not occurred:
* if ((returns) && (! input (SENSOR_IN))) printf ("% c \ r \ n", Y);
* or
* if ((returns) && (! input (SENSOR_OUT))) printf ("% c \ r \ n", X);
* the serial interrupt works again, and the characters are received.
*
* But if you receive an electric pulse on the corresponding pin and the
* interruption is disabled, when the "d_int_rda" flag returns to re-enable
* the serial interruption, calling the enable_interrupts (INT_RDA)
* function, nothing happens, it does not receive any more characters.
* Then, making only the flag returns to 0 or FALSE, so as not to receive
* any more electrical pulse, then the interruption will work again, being
* disabled and re-enabled normally.*/
if(bkbhit) /* Next to INT_RDA and bgetc () it takes the characters it stores in
* a character array. Circular buffer.*/
{
c=bgetc();
if(c=='0')
{
output_high(BEEP);
delay_ms(40);
output_low(BEEP);
barcode_buffer[0]=c;
barcode_buffer[1]=bgetc();
barcode_buffer[2]=bgetc();
barcode_buffer[3]=bgetc();
barcode_buffer[2]=0;
printf("%c%c%c%c%c%cC\n\r",barcode_buffer[0],barcode_buffer[1],barcode_buffer[2],barcode_buffer[3]);
d_int_rda=FALSE; /* Disables the standard message, and displays the numbers read on the LCD.
* I did not put the function of displaying the codes read on the LCD here,
* as I thought it was unnecessary not to get too long the code*/
disable_interrupts(INT_RDA); /* I disable the serial interrupt, so that I don't receive
* another character while doing certain situations or commands.*/
read_code(); // This function displays the received code on the LCD display, it is 4 characters.
}
/*******************************************************************************************/
if((returns)&&(!input(SENSOR_OUT))) printf("%c\r\n",X); /* if returns are true, and receive an electrical pulse
* on the SENSOR_OUT pin, send an X character to the PC software*/
if((returns)&&(!input(SENSOR_IN))) printf("%c\r\n",Y); /* if returns are true, and receive an electrical pulse
* on the SENSOR_IN pin, send a Y character to the PC software*/
}
}
}
void restartRS232() /* Error checking routine, call it at the beginning of the interrupt function: See example below.
* But it hasn't solved anything*/
{
if (OERR || FERR) // RS232 Error Handling
{ // Reset / Clear errors in reception usart
SPEN = 1;
CREN = 0;
delay_us (1);
CREN = 1;
delay_us (1);
return;
}
}
void msg_Default()
{
if(!msg_default) msg_default = TRUE; // checks if the default message is disabled and then enables
if (!d_int_rda) d_int_rda = TRUE; // checks if the serial interrupt is disabled and re-enables
// write these messages and go back to the while
printf(write_display,"\f>>>> Test <<<<");
printf(write_display,"\n>> Ready <<");
return;
}
| [/code] _________________ Gradually you will go far with persistence, will and determination!
Last edited by erpgc82 on Fri Mar 26, 2021 10:21 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
transmit register ??? |
Posted: Thu Mar 25, 2021 8:16 pm |
|
|
would the transmit register be locking the receive register?
I'm new to programming, sorry for the ignorance. _________________ Gradually you will go far with persistence, will and determination! |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 25, 2021 10:02 pm |
|
|
The code is not compilable by us. It's missing the BUFFER_SIZE #define
statement. It's missing the definition of tmr0if. In main() it uses the
variable 'c', but there's no declaration statement of 'c'. Etc.
Fix all this stuff. Post a program that we can drop into MPLAB and compile.
In the code below, you are using the same name for a function and
a variable. Don't do this.
Quote: | void msg_Default()
{
if(!msg_default) msg_default = TRUE; // checks if the default message is disabled and then enables
if (!d_int_rda) d_int_rda = TRUE; // checks if the serial interrupt is disabled and re-enables
// write these messages and go back to the while
printf(write_display,"\f>>>> Test <<<<");
printf(write_display,"\n>> Ready <<");
return;
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
|
Posted: Fri Mar 26, 2021 10:22 am |
|
|
PCM programmer wrote: | The code is not compilable by us. It's missing the BUFFER_SIZE #define
statement. It's missing the definition of tmr0if. In main() it uses the
variable 'c', but there's no declaration statement of 'c'. Etc.
Fix all this stuff. Post a program that we can drop into MPLAB and compile.
In the code below, you are using the same name for a function and
a variable. Don't do this.
Quote: | void msg_Default()
{
if(!msg_default) msg_default = TRUE; // checks if the default message is disabled and then enables
if (!d_int_rda) d_int_rda = TRUE; // checks if the serial interrupt is disabled and re-enables
// write these messages and go back to the while
printf(write_display,"\f>>>> Test <<<<");
printf(write_display,"\n>> Ready <<");
return;
}
|
|
Hello PCM programmer, consider the last code I posted.
See that I used the directive #case and msg_default is in lowercase and msg_Default () is in uppercase.
I liked the #case directive :-) _________________ Gradually you will go far with persistence, will and determination! |
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
NEVER DISABLE SERIAL INTERRUPTION |
Posted: Fri Mar 26, 2021 10:25 am |
|
|
I've been thinking, and I'm going to do another programming test.
NEVER DISABLE SERIAL INTERRUPTION, use a "flag" and then delete the characters that are in the matrix, if they arrive at a time when INT_RDA would be deactivated. _________________ Gradually you will go far with persistence, will and determination! |
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
reception stops working, even enabled 100% of the time. |
Posted: Fri Mar 26, 2021 1:57 pm |
|
|
I just tested here, and the problem is not even the interruption, now I have NEVER set the serial interruption to be disabled, and even so, when sending any character eg: printf ("x") to the pc / software the interruption stops to work, I really don’t know what’s going on, I’ll put that aside and then come back, because I need to send characters to the pc / software. _________________ Gradually you will go far with persistence, will and determination! |
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
;; |
Posted: Sat Mar 27, 2021 11:15 am |
|
|
Hello, could someone with experience help me? _________________ Gradually you will go far with persistence, will and determination! |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 27, 2021 12:12 pm |
|
|
Your claim is that doing a printf("x") disables RDA interrupts or perhaps
disables Global interrupts.
What's your CCS compiler version ?
What happens if you subsitute putc('x') for the printf("x") ?
Does it still fail to receive ? |
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
|
Posted: Sat Mar 27, 2021 12:30 pm |
|
|
PCM programmer wrote: | Your claim is that doing a printf("x") disables RDA interrupts or perhaps
disables Global interrupts.
What's your CCS compiler version ?
What happens if you subsitute putc('x') for the printf("x") ?
Does it still fail to receive ? |
was using printf ()
I started using putc () and the problem also occurs
I'm reading the datasheet and seeing the SPEN CREN FERR OERR SYNC TXIE RCIE TXEN TXIF RCIF GIE PEIE registers I will follow everyone, monitor everyone on the LCD and see what happens before locking and after locking ...
Version 5.076 _________________ Gradually you will go far with persistence, will and determination! |
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
|
Posted: Sat Mar 27, 2021 1:09 pm |
|
|
PCM programmer wrote: | Your claim is that doing a printf("x") disables RDA interrupts or perhaps
disables Global interrupts.
What's your CCS compiler version ?
What happens if you subsitute putc('x') for the printf("x") ?
Does it still fail to receive ? |
I just identified a new situation.
the FERR, BIT 2 bit of the RCSTA is at 0 when everything works correctly, and stays at 1 after sending a single character to the TX of the pc / software.
So this function could solve?
void restartRS232 () // Error checking routine, call it at the beginning of the interrupt function: See example below.
I am also monitoring the TXREG byte and after sending the first character to the pc / software, it has several invalid characters
the restartRS232 () function does not solve the problem when cleaning.
when I press a key that is in PIN_A1 or PIN_A2 the reading of the RX (INT_RDA) returns to work. Make a reading, but when sending one (1) minimum character to the pc, it will stop again ...
But I found that these PIN_A1 and PIN_A2 are just digital ports.
Code: |
{
if (OERR || FERR) // Error Handling RS232
{// Reset / Clear errors in reception usart
SPEN = 1;
CREN = 0;
delay_us (1);
CREN = 1;
delay_us (1);
Returns;
}
}
|
_________________ Gradually you will go far with persistence, will and determination!
Last edited by erpgc82 on Sat Mar 27, 2021 2:21 pm; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Sat Mar 27, 2021 2:20 pm |
|
|
OK, I have to ask...
what device do you have between the PIC and the PC ?
normally I use a TTL to USB module..as modern Pcs do not have true 'RS-232' ports anymore.
I've used the ex-sisr.c code for years, so I KNOW it's reliable.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
|
Posted: Sat Mar 27, 2021 2:25 pm |
|
|
temtronic wrote: | OK, I have to ask...
what device do you have between the PIC and the PC ?
normally I use a TTL to USB module..as modern Pcs do not have true 'RS-232' ports anymore.
I've used the ex-sisr.c code for years, so I KNOW it's reliable.
Jay |
I'm using a usr TCP / T2 network module purchased on aliexpress.
when in doubt I have also used a small ftdi module purchased from digikey.
this is not the problem, i have no problem with communication (external to pic)
what happens is that the PIC stops receiving characters in the serial interruption, after sending something to the pc.
I am researching the recorders for this 16f876, but as I am inexperienced, I may be on the wrong subject. _________________ Gradually you will go far with persistence, will and determination! |
|
![](templates/subSilver/images/spacer.gif) |
erpgc82
Joined: 02 May 2020 Posts: 73
|
resolved |
Posted: Sat Mar 27, 2021 2:38 pm |
|
|
Friends, I managed to find where the error was, after 1 week suffering from it.
This is very good to learn
I was doing the directives
#use fast_io (c)
then in main ()
{
set_tris_c (0b00000000); // all pins as output
output_c (0b00000000); // all pins at 0V
}
and just now I thought, the TX and RX pins are from the portC and if that is the problem?
but the use of rom increased considerably in percentage%.
so i commented the lines and the problem disappeared, now i can send characters to the pc (serial monitor) normally, which does not lock the serial interrupt. ![Very Happy](images/smiles/icon_biggrin.gif) _________________ Gradually you will go far with persistence, will and determination! |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Sat Mar 27, 2021 3:14 pm |
|
|
Don't bother using 'fast_io' and 'set _tris', let the compiler do it AUTOMATICALLY for you !!!
In over 2 decades of using PICs, I've only needed fast_io/set-tris TWICE. Both were to interface to proprietary, custom serial devices that needed precise timing.
I have no idea why the %increase in ROM, unless you've made changes.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|