|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
need an effecient buffer ('array') implementation (16F648A) |
Posted: Sat Jun 04, 2005 2:05 am |
|
|
hey guys,
I need a more effecient impementation of the following:
#device *=16
char buffer[69];
int index;
char getbyte();
buffer[index++] = getbyte();
I can't say i properly understand the assembly at this point but it seems to be taking over 20 instructions to do this operation not including the actual getbyte() function instructions. I really need this to happen quicker! (and i'm guessing its possible, i really want it done in around 10 instructions)
Obviously the best way will be to learn the assembly and make my own routine. There is ALOT of code using this buffer array though so i want to be able to continue using the "char buffer[69]" declaration so that i can reference the buffer as a c array throughout the rest of the code.
so,
Is there any basic things i can do in C to solve this?
If not, could i do it in somethin like 10instruction using Assembly?
If i use assembly, can i do what i'm hoping for (ie still use the array declaration) and then find out the address of the array (or maybe force it to an address) so that i can continue using the array normally afterwards?
hope this makes sense, as i said i dont really know assembly so i'm just guessing what i'd have to do at this stage.
thanks for any help. |
|
|
elder
Joined: 16 Mar 2005 Posts: 19
|
|
Posted: Sat Jun 04, 2005 2:28 am |
|
|
forgot to sign in :/
Just thought i'd add why i'm doing this. My project is a basic IrDA protocol stack microcontroller. So its an infrared connectivity solution that any micrcontroller can communicate with using the uart connection and it provides a reliable infrared link using the IrDA protocol. Currently i've got it going at 9600bps on the IR side and now trying to get it going at 115200bps. I only have 24 instruction cycles to play with between each bit, it also means 24 instructions (1 stop bit) between each byte to save it to a buffer and do a couple of checks |
|
|
Ttelmah Guest
|
|
Posted: Sat Jun 04, 2005 2:55 am |
|
|
You could probably reduce it a little, but I doubt if you will get it down to 10 instructions.
You need to load the value 'index', which may involve a bank switch, and then put the LSB of this into the FSR of the chip. The high bits of this then need to go into the back selection bits for this. You then need to increment index, and store the result back into it's memory location, then read the indirect index register to get the byte addressed, and save this into the target memory location. I'd guess you might get it down to about fifteen instructions with care. You can save quite a few instructions, if you ensure that index is in the same page as the internal registers (the first page of memory). You can change this by altering the order the registers are defined, or manually overriding the location definitions (potentially messy...). This should remove the need for two bank switches.
Indirect addressing, is not terribly 'efficient' in the PIC....
Best Wishes |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sat Jun 04, 2005 10:21 am |
|
|
Code: |
#device *=16
char buffer[69];
char *pbuf;
int index;
char getbyte();
pbuf = buffer;
.
.
.
pbuf[index++] = getbyte();
pbuf++;
|
You can still access the array using buffer[#]. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jun 04, 2005 12:46 pm |
|
|
Quote: | buffer[index++] = getbyte();
I can't say i properly understand the assembly at this point but it seems
to be taking over 20 instructions to do this operation not including the
actual getbyte() |
Here is a method that may work better.
The program below uses the CCS write_bank() function to
put characters into the array. If the array is placed in RAM
bank 1, the compiler doesn't have to use the IRP bit as much
and it only takes 6 instructions to do the write_bank() function.
I tested this program with PCM vs. 3.225 and it appears to work OK.
I typed in a string in my terminal window and pressed Enter, and
it was displayed back correctly.
Code: | #include <16F877.H>
#device *=16
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#ignore_warnings 202, 203
// Create an array and set the starting address
// at the start of RAM bank 1.
char buffer[69];
#byte buffer = 0x0A0
//========================
void main()
{
int index;
char c;
printf("Start\n\r");
index = 0;
while(1)
{
c = getc(); // Get a char from the PC
// Put the char into the buffer using write_bank().
write_bank(1, index, c);
// We want to post-increment the index, so we have to
// do it outside of the write_bank() function.
index++;
// Break out of the loop if the user presses the Enter
// key, or if we hit the end of the buffer.
if((c == 0x0D) || (index == 68))
{
write_bank(1, index, 0); // Write string terminator char
break;
}
}
// Display the string we typed into the buffer.
printf("\n\r%s", buffer);
while(1);
} |
Here is the code from the .LST file:
Code: |
... c = getc(); // Get a char from the PC
003D: GOTO 010
003E: MOVF 78,W
003F: MOVWF 22
....................
... // Put the char into the buffer using write_bank().
... write_bank(1, index, c);
0040: MOVLW A0 // Get LSB of RAM bank 0 base address
0041: ADDWF 21,W // Add the index to it
0042: MOVWF 04 // Put the result into the FSR register
0043: BCF 03.7 // Clear IRP bit to select banks 0 and 1
0044: MOVF 22,W // Get the character in c
0045: MOVWF 00 // Write c to Bank 1 using indirect addressing
....................
... // We want to post-increment the index, so we have to
... // do it outside of the write_bank() function.
... index++;
0046: INCF 21,F
.................... |
|
|
|
elder
Joined: 16 Mar 2005 Posts: 19
|
|
Posted: Sat Jun 04, 2005 9:35 pm |
|
|
thanks very much guys, thanks for the example PCM programmer thats exactly the type of thing i was hoping to do. |
|
|
|
|
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
|