----- Original Message ----- From: "Hopkins" To: "'PICLIST'" Sent: Thursday, December 23, 2004 9:42 PM Subject: [PIC]Circular buffer > I understand the idea of using pointers that chase each other in a > circular fashion but I do not know how to declare a memory block (da > command?) and then how to setup the pointers to store and retrieve data. > > The plan is to store LCD messages in EEPROM that are only altered if the > operator wishes to alter a message. > > Most of the time the EEPROM table will be copied into ram and used > there. > > Another buffer is to be used with a keypad that will send data via an > I2C link to another processor. This buffer will stay in ram the whole > time. > > I am programming in assembler using a 16F876. > > Scott Dattalo explained the procedure with a C example but I do not at > this stage understand C enough to be able to use it. Here is some code that make help you out. Of course you will have to modify some of the values. STARTOFRAM equ 0x20 ;First Usable RAM Location for 16f628 ENDOFRAM equ 0x6F ;Last Usable RAM Location for 16f628 FIXEDAREA equ 0x70 ;Start of shared memory between banks BANK2RAM equ 0xA0 ;Start of Bank 2 RAM ENDOFBANK2 equ 0xEF ;End of Bank 2 RAM cblock BANK2RAM ; ; This must be last thing in cblock (circular q uses all available ram) ; QData endc cblock FIXEDAREA ; Make sure we can always get to these QHead QEnd endc STARTOFQ equ QData ; Start of Circular Q Memory ENDOFQ equ ENDOFBANK2 + 1 SIZEOFQ equ ENDOFQ - STARTOFQ ;Number of bytes that q will hold This code will stick values into the queue. ;The following code commented out will cause bytes received when queue is full to be dropped at the expense of ; extra cpu cycles. The current setup is faster to execute but will cause q to wrap around, which causes SIZEOFQ ; bytes to be lost. ; incf QEnd, W ;Testing for a q wrap ; xorlw ENDOFQ ;Are we at the end of memory ; btfss STATUS, Z ; goto $ + 3 ;;Point back to beginning of Q ; movlw STARTOFQ ;Address of start of Q ; goto $ + 2 ; incf QEnd, W ; xorwf QHead, W ; btfsc STATUS, Z ; goto dropit ;Stick received byte into circular queue incf QEnd, F ;Increment pointer movfw QEnd ; and load into W xorlw ENDOFQ ;Are we at the end of memory btfss STATUS, Z goto AppendByte ;Point back to beginning of Q movlw STARTOFQ ;Address of start of Q movwf QEnd AppendByte movfw QEnd ;Get address to place byte into movwf FSR ; and set up indirect pointer to it movfw serialData ;Get the byte received and movwf INDF ; stick it into the Q To extract values from the queue use code that looks something like this. Main movfw QHead ;Get current start of q pointer and xorwf QEnd, W ; compare to end of q pointer btfsc STATUS, Z ;If equal then nothing in the q to process goto Main ;Extract received byte from circular queue incf QHead, F ;Increment pointer movfw QHead ; and load into W xorlw ENDOFQ ;Are we at the end of the queue btfss STATUS, Z goto Extract_Byte ;no, just pull one out ;Point back to beginning of Q movlw STARTOFQ ;Address of start of Q movwf QHead Extract_Byte movfw QHead ;Get address to get byte from movwf FSR ; and set up indirect pointer to it movfw INDF ; Load byte from queue into W Good Luck, YMMV -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist