Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

RS232 Simple linear Buffer (OshonSoft Basic).

DogFlu66

Member
Hello; on this occasion I leave a simple linear buffer.
Specially applied for the RS232 port.
To avoid losing data, what is done is to add another software buffer to the hardware buffer of the pic (2 bytes). The length of the latter will depend on the user's needs and the amount of memory available. This is for those who are interested in learning how a simple buffer works and how it is complemented by the asynchronous pic module, in this case the usat module.
The input data blocking check has been implemented, since apparently those who start working with this type of port are not clear that if the pic buffer is overloaded it is blocked and stops working, and to activate it again you have to reset the control bits of the internal buffer of the pic.
If anyone sees that improvements can be made or another better algorithm can be presented, they can share it.

I leave the main program and the functions necessary for it to work as attachments.

Main program:

'Example of buffer for RS232 port
'Pic12F1840, 08/12/2023
Define CONFIG1 = 0x0f84
Define CONFIG2 = 0x1dff
Include "_FuncionesPic12F1840.bas"
Include "_Funciones_Buffer_RS232.Bas"
Define CLOCK_FREQUENCY = 32 '32Mhz system oscillator
'constants (ASCII control codes).
Const FF = 0x0c 'FF, page advance
Const Bell = 0x07 'Bell, sound signal
Const Sp = 0x20 'Sp, space
Const Bksp = 0x08 'Bksp, go back
'Const Cr = 0x0d 'Cr, car return
'Const Lf = 0x0a 'Lf, line break
Const Ctrlz = 0x1a 'Ctrl - Z
Const Esc = 0x1b 'Escape
main:
'Call _setup_oscillator_mode(_oscillator_by_fosc) 'Select by configuration word.
Call _setup_oscillator(_osc_32mhz_hf) 'Interno 8Mhz x 4(PLL) = 32Mhz
AllDigital
TRISA = 0xff

UART_Init 9600 'Initialize port pin (default: A0 = Tx, RA1 = Rx)
Call _uart_pin_tx_ra4(True) 'Pin Tx = RA4
Call _uart_pin_rx_ra5(True) 'Pin Rx = RA5
WaitMs 10

Call _setup_buffer_rs232() 'Initialize buffer by software
Call _enable_interrupts(_int_rda) 'Enables uart interrupts
Call _enable_interrupts(_global) 'Enables peripheral and global interrupts.

Dim data As Byte

UART_Write "Ready", CrLf

While True

If _buffer() = True Then 'If there is data in the buffer.
'data = _read_buffer_rs232()'Reads byte fron buffer and assigns it to a variable.
'UART1_Write data'Write the byte to the serial port.
UART_Write _read_buffer_rs232() 'Reads byte fron buffer and write to the serial port.
Endif
Wend
End
On Interrupt
Save System
If _uartif = True Then 'If there is data in the uart hardware buffer.
Call _get_rs232() 'Moves a byte from the hardware buffer to the software buffer.
Endif
Resume
 

Attachments

  • _FuncionesPic12F1840.bas
    31.6 KB · Views: 258
  • _Funciones_Buffer_RS232.Bas
    3.5 KB · Views: 233
Last edited:
In the example image you continue making two readings and two sendings to the serial port. Only one read can be made with each buffer comparison. By doing two readings and two shipments in a row you are slowing down the system. And by making two readings in a row without checking the buffer each time, the buffer may run out of data and cause a slowdown of up to 10mSec.

If buffer > 0 then
data = _Receiver(10)
Processed frame code, if data in the buffer has a complete frame or more than one frame.
Endif

That is why a buffer is used to process received frames when possible, hence the need to have a buffer that can hold several frames at the same time.

I insist, it is very important that the buffer is long enough to be able to store several frames at the same time, this way you do not depend on the time or speed of the micro to process them, process them when you can.
Hi D,
In case of mistakes, I'll clarify what I said in #39 : I use the Oshonsoft simulator, and when a long string of CHARS are put into the 'Hardware UART simulation interface' the CHARS rattle though pretty fast. If the buffer gets empty, then the next CHARS go through slowly, at 1/ms. In the simulator, this looks as if the whole thing has stopped, but as we now know it hasn't. This is why I deleted it, but I couldn't delete the image for some reason.
C
 
Well, with that point clarified, you can try waiting to interpret the data until you know that the buffer has or has most of the data frame. Since you know the length of it, you can check it with Buffer. This would be as follows:
If Buffer > 70 then process data frame.
This way you guarantee that you do not anticipate the data that enters through the port, and in this way you rule out that the problem you have is this.
 
Well, with that point clarified, you can try waiting to interpret the data until you know that the buffer has or has most of the data frame. Since you know the length of it, you can check it with Buffer. This would be as follows:
If Buffer > 70 then process data frame.
This way you guarantee that you do not anticipate the data that enters through the port, and in this way you rule out that the problem you have is this.
Hi D,
That worked, magic!
For this application, I've turned WRITE OFF. The DATA gets past to another buffer which has a full sentence, that is parsed and sent to another PIC via SPI.
Thanks. C
 
Hi D,
I was showing my mate the ring buffer today, but it wouldn't compile until we changed BYREF to BYVAL
[Function _MILLIS(ByVal _preMillis As Long, delayMillis As Long) As Bit]

Do you have any idea why? the same thing has happened before, it could be an Oshonsoft bug?
C.
 
Hi,
I am probably repeating myself, but are 'ring buffers' the best over 'linear buffers' in all cases.
At the weekend I was debating this with my mate, and we kind of came to the conclusion, that if all of the DATA needs to be read, then 'ring buffers' are the best, but in this case, the system can't cope with all of the DATA, so we 'collect' the sentence of our choice from the GPS, switch off the UART, PARSE the DATA, then switch the UART back on and wait (200mS) for the next sentence. I expect this reads 1/2 of chosen the GPS sentences.

Earlier I reported that the existing 'linear buffer' or something else is stalling, and I think you said I should use 'ring buffers', is this the reason that I should use them?
C
 
Last edited:
For my working method, the Buffer ring is better. A simple linear buffer may be sufficient for your working method. If you use a linear buffer and it does not work well for you, it may be that the buffer you use is not well defined or structured and has a problem. Buffers in general are used to not stop data entry, data enters the buffer automatically while other processes are running. A GPS that delivers the data frame every 100mSeg leaves a dead time of 100mSeg and this time is very long for a microcontroller, it should give it time to process the input frame and perform many more tasks. The important thing is not to get ahead of the data frame, once the data frame is entered it is processed, in this case the microcontroller goes with a delay frame, in most cases this delay time is not a problem.
 
For my working method, the Buffer ring is better. A simple linear buffer may be sufficient for your working method. If you use a linear buffer and it does not work well for you, it may be that the buffer you use is not well defined or structured and has a problem. Buffers in general are used to not stop data entry, data enters the buffer automatically while other processes are running. A GPS that delivers the data frame every 100mSeg leaves a dead time of 100mSeg and this time is very long for a microcontroller, it should give it time to process the input frame and perform many more tasks. The important thing is not to get ahead of the data frame, once the data frame is entered it is processed, in this case the microcontroller goes with a delay frame, in most cases this delay time is not a problem.
Hi D,
Good!
I (and my mate) have come to the conclusion that for this application a 'ring buffer' is wasteful. He thinks, as you do that there's another problem in the structure, so we'll look closer in that area.

EDIT: EDIT: If the UART is not switched off between sentences, but once a sentence has been received, stop filling the buffer, until it's been PARSED, then start reading again. If this method is ok, then is it more efficient than saving the 'ring buffer' all of the time?
Thanks, C.
 
Last edited:

Latest threads

New Articles From Microcontroller Tips

Back
Top