DATA

Syntax:

        DATA DataSetName [as Byte | Word]
            // multiples values, strings etc.
            0,1,2,3
        END DATA

Command Availability:

Available on all PIC microcontrollers with DATA memory.

Explanation:

The DATA construct creates a DATA dataset, or DATA block, for use with the specific microcontroller. A DATA dataset is a list of values that are stored in the program memory (PROGMEM) of the microcontroller, which can then be accessed using the ProgramRead() command or other DATA read operations.

The advantage of a DATA dataset is that it is memory efficient, being loaded directly into program memory during programming operations.

DATA datasets are defined as follows:

  1. Byte or Word values,
  2. Multiple numeric elements on a single line separated by commas,
  3. Constants and calculations within the single-line dataset entries are permitted,
  4. Decimal values are NOT supported,
  5. Access is via ProgramRead().

Defining DATA Datasets

Single Data Values

A single value on each line within the dataset. The example dataset shown below has the data on different lines within the set.

Simple example: this creates a DATA dataset at the first DATA location; the values 12, 24, …​ 72 are the consecutive values.

        DATA EEDataSet as Byte
            12
            24
            36
            48
            60
            72
        End DATA

Multiple Data Values on the Same Line

The following example creates the DATA dataset at DATA offset address 0x10.

Multiple elements can appear on a single line, separated by commas. The example dataset shown below has the data separated by , and spread across different lines within the dataset.

        DATA EEDataSource  as Byte
            12,  24, 36
            48,  60, 72
        End DATA

Data Values as Constants, with Data Transformation

Constants and calculations are permitted within a single line. The example dataset shown below uses a defined constant to multiply each entry in the dataset.

        #define calculation_constant 2

        DATA EEDataSource as Word
        1 * calculation_constant
        2 * calculation_constant
        3 * calculation_constant
        8 * calculation_constant
        4 * calculation_constant
        5 * calculation_constant
        End DATA

Data Values as Strings

Strings can be defined. Strings are delimited by double quotes. The following examples show the methods.

Any ASCII characters between two " (double quotes) are converted to dataset data. Also see ASCII escape codes below.

A source string can be one string per line, or comma-separated strings on the same line.

Example:

    DATA Test_1 as Byte
     "ABCDEFGHIJ"
    End DATA

ASCII Escape Codes

Accepted escape sequences are shown in the table below.

Escape sequence Meaning

\a

beep

\b

backspace

\f

formfeed

\l or \n

newline

\r

carriage return

\t

tab

\0

Null value, equates to ASCII 0. Same as \&000

\&nnn

ASCII character in decimal

\\

backslash

\"

double quote

\'

single quote

Maximum Stored Value

The maximum value that can be stored in a single program-memory word location across the PIC families:

Family

Instruction Word Size

Program Memory Word Width

Maximum Value per Word (unsigned decimal)

Hex Range

Can store full 16-bit value (0-65535) in one word?

PIC10

12-bit

12 bits

4095

0x000 - 0xFFF

No

PIC12 (baseline)

12-bit

12 bits

4095

0x000 - 0xFFF

No

PIC12 (enhanced mid-range)

14-bit

14 bits

16383

0x0000 - 0x3FFF

No

PIC14

14-bit

14 bits

16383

0x0000 - 0x3FFF

No

PIC16 (mid-range)

14-bit

14 bits

16383

0x0000 - 0x3FFF

No

PIC16 (enhanced mid-range)

14-bit

14 bits

16383

0x0000 - 0x3FFF

No

PIC18

16-bit

16 bits

65535

0x0000 - 0xFFFF

Yes

Quick Summary Table (Most Common Cases)

Family group

Typical word size

Max value you can store in one program memory word

Equivalent to storing a full 16-bit number?

PIC10 / baseline PIC12

12 bits

4095 (0xFFF)

No

PIC14 / PIC16 / enhanced PIC12

14 bits

16383 (0x3FFF)

No

PIC18

16 bits

65535 (0xFFFF)

Yes

Important Notes

  • PIC18 is the only 8-bit PIC family where you can directly store any 16-bit value (0-0xFFFF) in a single program-memory word location.
  • On all earlier families (PIC10, PIC12 baseline, PIC14, PIC16, enhanced mid-range), you must split any value greater than 0x3FFF (16383) across two words if you need the full 16-bit range.
  • The values above apply when storing constants, lookup table entries, retlw literals, data/db directives, and so on — that is, the largest number that fits in one program-memory word.
  • Program memory addressing varies by family:
  • On PIC18F family chips, program memory is byte-addressable (addresses run consecutively: 0, 1, 2, 3, …​). For word (16-bit) reads/writes, the address must be even (starting on the low byte of a word pair; odd addresses would misalign). Byte-level access uses fully consecutive addresses.
  • On non-18F families (PIC10/PIC12/PIC14/PIC16, etc.), program memory is word-addressable with consecutive word indices (0, 1, 2, …​); byte handling is limited or requires special care.

    Always use even addresses for word operations on PIC18F when using `ProgramRead`, `DATA` lookups, or tables, to avoid reading split or incorrect data. See the chip datasheet for TBLPTR (table pointer) details on PIC18F.

Complete Working Example Program

This example creates several DATA datasets and a lookup table. The DATA datasets are addressed with an additional parameter to ensure that no DATA dataset overlaps another.

        #chip 16F886
        #option explicit

        #DEFINE USART_BAUD_RATE 9600
        #DEFINE USART_TX_BLOCKING
        #DEFINE USART_DELAY OFF

        Dim dataaddress, datavalue as Byte

        DATA DataSet1 as Byte
            3,2,1
        End DATA

        DATA VersionData as Byte
        "    PWM2Laser   "
        "  Fabrice ENGEL "
        "   Version 1.4  "
        "  November 2023 "
        End DATA

        For dataaddress = 0 to 2
            ProgramRead  ( @DataSet1 + dataaddress , datavalue )          ' <<< the read this page's DATA block is designed for
            HserPrint datavalue
        Next

Key line: ProgramRead ( @DataSet1 + dataaddress , datavalue ) — reads back one byte of the DataSet1 block using its compile-time address (@DataSet1) offset by the loop counter.

See Also: