erpgc82
Joined: 02 May 2020 Posts: 73
|
|
Posted: Sat Feb 27, 2021 9:34 pm |
|
|
Hello friend PCM programmer, I do not know how to thank you, I have been studying programming with CCS and I was tangled in the reception of characters by the serial for over a month. The big secret is really, not just in the serial interruption.
But in 2nd, the secret is in the function for treatment, which you called bkbhit (not to be confused with the CCS kbhit).
And on the 3rd important point, another secret is in what you call string, I understand that the string ends there, with a null character
barcode_buffer [7] = 0;
Another 4th important point I learned is, that I really have to use a large buffer, for the string to work loosely. Because I tried to use a size 10 buffer as I learned in books (9 of the characters + 1) but it didn't even compile. I tried to work with 16 bytes it worked, but at first some invalid characters appeared. With 32 bytes, the buffer cycle worked perfectly. See that I monitored the value of next_int and next_out on the LCD.
A 5th observation is that the next_in variable is then circled within the 32 bytes.
Another 6th observation is that I learned in the forums to clear the buffer, using functions like the one below, and they are unnecessary, due to ERRORS in the rs232 () function already doing these treatments / cleaning. Am I right?
Code: |
void clear_uart_buffer()
{
while(next_in < BUFFER_SIZE)
{
code[next_in]='\0';
next_in++;
}
next_in=0;
}
|
or
Code: |
void restartRS232(void)
{
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;
}
}
|
///////////////////////////////////////////////////////////////////////////////////
It worked perfectly with some minor changes. I will post the code here so that it serves others who have the same difficulty.
Code: |
#include <16F876a.h>
#use delay(clock=10000000)
#fuses HS,NOWDT,PUT,BROWNOUT,NOLVP
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8, stop=1, ERRORS)
#include "display_8bits16f876.c"
#define BUZZER PIN_A3
#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in=0;
BYTE next_out=0;
#INT_RDA
void serial_isr()
{
int t; // temporary variable to receive serial data
buffer[next_in]=getc(); // takes the byte and uses the next_in variable to store it in the buffer array
t=next_in; // stores the byte in the temporary variable, t
next_in=(next_in+1)%BUFFER_SIZE;
if(next_in==next_out) next_in=t; // Buffer full
}
#define bkbhit (next_in!=next_out)
// bgetc function to handle interrupt data
BYTE bgetc()
{
BYTE c;
while(!bkbhit);
c=buffer[next_out];
next_out=(next_out+1)%BUFFER_SIZE;
return(c);
}
void main()
{
int8 c;
int8 barcode_buffer[10];
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
display_ini(); // initializes the display
while(TRUE)
{
printf(write_display,"\f%s ",barcode_buffer);
display_pos_xy(12,1);
printf(write_display,"%d",next_in);
display_pos_xy(15,1);
printf(write_display,"%d",next_out);
////////////////////////////////////////////////////////////////////////
if(bkbhit)
{
c=bgetc();
if(c=='0') // Is the arrival of the bytes starting here?
{
barcode_buffer[0]=c; // 1º digit
barcode_buffer[1]=bgetc(); // 2º digit
barcode_buffer[2]=bgetc(); // 3º digit
barcode_buffer[3]=bgetc(); // 4º digit
barcode_buffer[4]=bgetc(); // 5º digit
barcode_buffer[5]=bgetc(); // 6º digit
barcode_buffer[6]=bgetc(); // B
barcode_buffer[7]=bgetc(); // \n
barcode_buffer[8]=bgetc(); // \r
output_high(BUZZER);
delay_ms(40);
output_low(BUZZER);
barcode_buffer[7]=0; //end the string here and restart another.
printf("%c%c%c%c%c%c#\n\r",barcode_buffer[0],barcode_buffer[1],barcode_buffer[2],barcode_buffer[3],barcode_buffer[4],barcode_buffer[5]);
display_pos_xy(11,2);
printf(write_display,"%c%c%c%c%c%c",barcode_buffer[0],barcode_buffer[1],barcode_buffer[2],barcode_buffer[3],barcode_buffer[4],barcode_buffer[5]);
delay_ms(1000);
}
}
delay_ms(50);
}
}
|
_________________ Gradually you will go far with persistence, will and determination! |
|