Explanation:
This program demonstrates how to create a serial input buffer ring.
The program receives a character into the buffer and sends back. Try sending large volumes of characters…..
This program program uses an interrupt event to capture the incoming byte value and place in the buffer ring. When a byte is received the buffer ring is incremented to ensuer the next byte is handled correctly.
Testing bkbhit
will set to True when a byte has been received. Reading the function bgetc
will return the last byte received.
Demonstration program:
This demonstration program will support up to 256 bytes. For a larger buffer change the variables to words.
#chip 16F1937 // #chip mega4809 // #chip mega328p, 16 // Add PPS if appropiate for your chip // [change to your config] This is the config for a serial terminal // assumes USART1 ( or USART0 on AVRDx ), if you select USART1/2/3/4 then you MUST add the comport parameter to all HSerxxxxx functions. // turn on the RS232 and terminal port. // Define the USART settings #DEFINE USART_BAUD_RATE 9600 // This assumes you are using an ANSI compatible terminal. Use PUTTY.EXE it is very easy to use. // Main program // Wait for terminal to settle wait 3 s // Create the supporting variables Dim next_in As Byte Dim next_out As Byte Dim syncbyte As Byte Dim temppnt As Byte // Constants etc required for Buffer Ring #DEFINE BUFFER_SIZE 8 #DEFINE bkbhit (next_in <> next_out) // Define the Buffer Dim buffer( BUFFER_SIZE - 1 ) // we will use element 0 in the array as part of out buffer // Call init the buffer InitBufferRing HSerSend 10 HSerSend 13 HSerSend 10 HSerSend 13 HSerPrint "Started: Serial between two devices" HSerSend 10 HSerSend 13 // Get character(s) and send back // Get character(s) and send back Do // Do we have data in the buffer? if bkbhit then // Send the next character in the buffer to the terminal, exposed via the function `bgetc` back the terminal HSerSend bgetc end if Loop // Supporting subroutines Sub readUSART buffer(next_in) = HSerReceive temppnt = next_in next_in = ( next_in + 1 ) % BUFFER_SIZE If ( next_in = next_out ) Then // buffer is full!! next_in = temppnt End If End Sub Function bgetc Dim local_next_out as Byte // maintain a local copy of the next_out variable to ensure it does not change when an Interrupt happens local_next_out = next_out bgetc = buffer(local_next_out) local_next_out=(local_next_out+1) % BUFFER_SIZE INTOFF next_out = local_next_out INTON End Function Sub InitBufferRing // Set the buffer to the first address next_in = 0 next_out = 0 // Interrupt Handler - some have RCIE and some have U1RXIE, so handle // // You would need to change the Interrupt if you use USART1,2,3, or 4 // #IFDEF BIT( RCIE ) On Interrupt UsartRX1Ready Call readUSART #ENDIF #IFDEF BIT( U1RXIE ) On Interrupt UART1ReceiveInterrupt Call readUSART #ENDIF #IFDEF AVR #IFNDEF CHIPAVRDX //~ Support for legacy AVR On Interrupt UsartRX1Ready Call readUSART #ELSE //~ Support for AVRDx - AVRDx chips are USART0,USART1,USART2,USART3 and USART4 not USART. On Interrupt Usart0RXReady Call readUSART #ENDIF #ENDIF End Sub