如果你的变量并没有大的数组,那么你可能就是真用完了,编译器的默认RAM是可以把你的变量分配在所有bank里的。不存在你说的默认bank。像yewuyi所说自动调整。
但是有一种情况是要除外,你要手动的安排变量位置了,就是你定义了一个大数组,占用的空间超过了256字节,这时如果你不手动调整,即使你只定义了这一个数组,编译器也会报空间安排不了了。你就要手动在代码里安排这个数组的位置,并且更改连接脚本,分配一个段能够放的下这个数组的空间。
Application: Creating Large Data Objects and the USART
The following sample application prompts the user (via HyperTerminal®) to enter a digit between 0 and 9. Upon receiving a character from the USART, the program will then either output a string from an array of data or if the character received is not between 0 and 9, output an error string. The command line used to build this application is:
mcc18 -p 18f452 -I c:\mcc18\h example2.c
where c:\mcc18 is the directory in which the compiler is installed. This sample application is designed for use with the MPLAB ICD2, the PICDEM™ 2 Plus demo board, and the PIC18F452 device. This sample covers the following items:
1. Creating large data objects
2. Reading from and writing to the USART
3. Interrupt handling (#pragma interrupt, interrupt vectors, and interrupt service routines)
4. System header files
5. Processor-specific header files
6. #pragma sectiontype
7. Inline assembly
By default, MPLAB C18 assumes that an object will not cross a bank boundary. An object that is larger than 256 bytes can be created, but the following steps are required to create a multi-bank object:
1. The object must be allocated into its own section using the #pragma idata or #pragma udata directive.
#pragma udata buffer_scn
static char buffer[0x180];
#pragma udata
2. Accesses to the object must be done via a pointer.
char * buf_ptr = &buffer[0];
...
// examples of use
buf_ptr[5] = 10;
if (buf_ptr[275] > 127)
...
3. A new region that spans multiple banks must be created in the linker script.
Linker script before modification:
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
Linker script after modification:
DATABANK NAME=big START=0x200 END=0x37F PROTECTED
DATABANK NAME=gpr3 START=0x380 END=0x3FF
4. The object's section (created in Step #1) must be assigned into the new region (created in Step #3). Add a SECTION directive to the linker script.
SECTION NAME=buffer_scn RAM=big
/* 1 */ #include <p18cxxx.h>
/* 2 */ #include <usart.h>
/* 3 */
/* 4 */ void rx_handler (void);
/* 5 */
/* 6 */ #define BUF_SIZE 25
/* 7 */
/* 8 */ /*
/* 9 */ * Step #1 - The data is allocated into its own section.
/* 10 */ */
/* 11 */ #pragma idata bigdata
/* 12 */ char data[11][BUF_SIZE+1] = {
/* 13 */ { "String #0\n\r" },
/* 14 */ { "String #1\n\r" },
/* 15 */ { "String #2\n\r" },
/* 16 */ { "String #3\n\r" },
/* 17 */ { "String #4\n\r" },
/* 18 */ { "String #5\n\r" },
/* 19 */ { "String #6\n\r" },
/* 20 */ { "String #7\n\r" },
/* 21 */ { "String #8\n\r" },
/* 22 */ { "String #9\n\r" },
/* 23 */ { "Invalid key (0-9 only)\n\r" }
/* 24 */ };
/* 25 */ #pragma idata
/* 26 */
/* 27 */ #pragma code rx_interrupt = 0x8
/* 28 */ void rx_int (void)
/* 29 */ {
/* 30 */ _asm goto rx_handler _endasm
/* 31 */ }
/* 32 */ #pragma code
/* 33 */
/* 34 */ #pragma interrupt rx_handler
/* 35 */ void rx_handler (void)
/* 36 */ {
/* 37 */ unsigned char c;
/* 38 */
/* 39 */ /* Get the character received from the USART */
/* 40 */ c = ReadUSART();
/* 41 */ if (c >= '0' && c <= '9')
/* 42 */ {
/* 43 */ c -= '0';
/* 44 */ /* Display value received on LEDs */
/* 45 */ PORTB = c;
/* 46 */
/* 47 */ /*
/* 48 */ * Step #2 - This example did not need an additional
/* 49 */ * pointer to access the large memory because of the
/* 50 */ * multi-dimension array./* 51 */ *
/* 52 */ * Display the string located at the array offset
/* 53 */ * of the character received
/* 54 */ */
/* 55 */ putsUSART (data[c]);
/* 56 */ }
/* 57 */ else
/* 58 */ {
/* 59 */ /*
/* 60 */ * Step #2 - This example did not need an additional
/* 61 */ * pointer to access the large memory because of the
/* 62 */ * multi-dimension array./* 63 */ *
/* 64 */ * Invalid character received from USART.
/* 65 */ * Display error string.
/* 66 */ */
/* 67 */ putsUSART (data[10]);
/* 68 */
/* 69 */ /* Display value received on LEDs */
/* 70 */ PORTB = c;
/* 71 */ }
/* 72 */
/* 73 */ /* Clear the interrupt flag */
/* 74 */ PIR1bits.RCIF = 0;
/* 75 */ }
/* 76 */
/* 77 */ void main (void)
/* 78 */ {
/* 79 */ /* Configure all PORTB pins for output */
/* 80 */ TRISB = 0;
/* 81 */
/* 82 */ /*
/* 83 */ * Open the USART configured as
/* 84 */ * 8N1, 2400 baud, in polled mode
/* 85 */ */
/* 86 */ OpenUSART (USART_TX_INT_OFF &
/* 87 */ USART_RX_INT_ON &
/* 88 */ USART_ASYNCH_MODE &
/* 89 */ USART_EIGHT_BIT &
/* 90 */ USART_CONT_RX &
/* 91 */ USART_BRGH_HIGH, 103);
/* 92 */
/* 93 */ /* Display a prompt to the USART */
/* 94 */ putrsUSART (
/* 95 */ (const far rom char *)"\n\rEnter a digit 0-9!\n\r");
/* 96 */
/* 97 */ /* Enable interrupt priority */
/* 98 */ RCONbits.IPEN = 1;
/* 99 */
/* 100 */ /* Make receive interrupt high priority */
/* 101 */ IPR1bits.RCIP = 1;
/* 102 */
/* 103 */ /* Enable all high priority interrupts */
/* 104 */ INTCONbits.GIEH = 1;
/* 105 */
/* 106 */ /* Loop forever */
/* 107 */ while (1)
/* 108 */ ;
/* 109 */ }
Line 1: This line includes the generic processor header file. The correct processor is selected via the -p command-line option. (See System Header Files and Processor-Specific Header Files.)
Line 11: Creating Large Objects: Step #1. The #pragma idata directive is used to store the initialized data variable data into its own section. (See "#pragma sectiontype".)
Line 25: This line returns the compiler to the default initialized data section. (See "#pragma sectiontype" and Table: Default Section Names.)
Line 27: For PIC18 devices, the high-priority interrupt vector is found at 00000008h. This line of code changes the default code section to the absolute code section named rx_interrupt located at 0x8. (See "#pragma sectiontype" and Nested Interrupts.)
Line 32: This line returns the compiler to the default code section (See "#pragma sectiontype" and Table: Default Section Names.)
Line 34: This line specifies the function rx_handler as a high-priority interrupt service routine. This is required in order for the compiler to generate a RETFIE instruction instead of a RETURN instruction for the rx_handler function. (See "#pragma interruptlow fname/#pragma interrupt fname".)
Line 35: This line defines the rx_handler function. Notice that it does not take any parameters, and does not return anything (as required by ISRs). (See Interrupt Vectors.)
Line 45, 70: These lines demonstrate how to modify the special function register PORTB in C. (See Processor-Specific Header Files.)
Line 55, 67: Creating Large Objects: Step #2. Large objects are accessed via indirection. These lines output a data string to the USART.
Line 74: This line demonstrates how to modify a single bit of the special function register PIR1 in C. (See Processor-Specific Header Files.)
Line 80: This line initializes the special function register TRISB. (See Processor-Specific Header Files.)
Line 86-91: These lines open the USART configured as 8N1, 2400 baud, in Polled mode. In addition, it enables the USART's receive interrupt.
Line 98: This line enables the interrupt priority feature of the PIC18. (See Processor- Specific Header Files.)
Line 101: This line makes the USART receive interrupt a high-priority interrupt source. (See Processor-Specific Header Files.)
Line 104: This line enables all high-priority interrupts (See Processor-Specific Header Files.)
Linker Script:
// This file was originally 18f452i.lkr as distributed with MPLAB C18.
// Modified as follows:
// - combine banks 4 and 5 into PROTECTED DATABANK "largebank"
// - moved stack to gpr3
// - Assign the "bigdata" SECTION into the new "largebank" region
LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f452.lib
CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED
CODEPAGE NAME=page START=0x2A END=0x7DBF
CODEPAGE NAME=debug START=0x7DC0 END=0x7FFF PROTECTED
CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED
CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED
ACCESSBANK NAME=accessram START=0x0 END=0x7F
DATABANK NAME=gpr0 START=0x80 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
// Step #3 - Create a new region in the linker script
// This is the databank that will contain the large memory object
DATABANK NAME=largebank START=0x400 END=0x5F3 PROTECTED
DATABANK NAME=dbgspr START=0x5F4 END=0x5FF PROTECTED
ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED
SECTION NAME=CONFIG ROM=config
// Step #4 - Assign the large memory object's section into the new region
SECTION NAME=bigdata RAM=largebank
STACK SIZE=0x100 RAM=gpr3 |