You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+32-32Lines changed: 32 additions & 32 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,49 +4,48 @@
4
4
5
5
# How to Write and Read to an External EEPROM with a PIC16F18076
6
6
7
-
This example will explain how to read and write both a single byte and array of memory from a PIC16F18076 microcontroller to an external EEPROM device. A curiosity nano development board will be used with an external 25CSM04 EEPROM device on a Mikroe EEPROM 7 click board. Additionally, MPLAB Code Configurator with its MSSPSPI peripheral will be used to handle communication between the microcontroller and the EEPROM device. MCC will also be used to setup the microcontroller's pins and basic configurations and the UART peripheral will be configured for debugging and outputing the results of the example's included tests for reading and writing.
7
+
This example explains how to read and write both a single byte and an array of memory from a PIC16F18076 microcontroller (MCU) to an external EEPROM device. A Curiosity Nano development board is used with an external 25CSM04 EEPROM device on a Mikroe EEPROM 7 Click board™. Additionally, MPLAB® Code Configurator (MCC) with its Host Synchronous Serial Port (MSSP) Serial Peripheral Interface (SPI) peripheral is used to handle communication between the MCU and the EEPROM device. MCC is also used to set up the microcontroller’s pins and basic configurations, as well as to configure the Universal Asynchronous Receiver Transmitter (UART) peripheral for debugging and outputing the results of the reading and writing tests included in the example.
8
8
9
9
## Related Documentation
10
10
11
-
-[PIC16F18076 Product Page and Datasheet](https://www.microchip.com/en-us/product/PIC16F18076?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_pic16f18076&utm_content=pic16f18076-eeprom-demo-mplab-mcc)
11
+
-[PIC16F18076 Product Page and Data Sheet](https://www.microchip.com/en-us/product/PIC16F18076?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_pic16f18076&utm_content=pic16f18076-eeprom-demo-mplab-mcc)
12
12
13
13
14
-
-[25CSM04 Product Page and Datasheet](https://www.microchip.com/en-us/product/25CSM04?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_pic16f18076&utm_content=pic16f18076-eeprom-demo-mplab-mcc)
14
+
-[25CSM04 Product Page and Data Sheet](https://www.microchip.com/en-us/product/25CSM04?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_pic16f18076&utm_content=pic16f18076-eeprom-demo-mplab-mcc)
15
15
16
16
## Software Used
17
17
18
-
- MPLAB® X IDE 6.0.5 or newer[(MPLAB® X IDE 6.0)](https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-x-ide?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_MPAE_Examples&utm_content=pic16f18076-read-write-external-memory-github)
19
-
- MPLAB® XC8 2.40.0 or newer compiler [(MPLAB® XC8 2.40)](https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-xc-compilers?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_MPAE_Examples&utm_content=pic16f18076-read-write-external-memory-github)
20
-
- MPLAB® Code Configurator (MCC) 5.2.2 or newer[(microchip.com/mplab/mplab-code-configurator)](https://www.microchip.com/en-us/tools-resources/configure/mplab-code-configurator?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_pic16f18076&utm_content=pic16f18076-eeprom-demo-mplab-mcc)
- Microchip PIC16F1xxxx_DFP Series Device Support (1.15.191) or newer[(packs.download.microchip.com/)](https://packs.download.microchip.com/)
18
+
- MPLAB® X IDE [6.0.5 or newer](https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-x-ide?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_MPAE_Examples&utm_content=pic16f18076-read-write-external-memory-github)
19
+
- MPLAB XC8 [2.40.0 or newer](https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-xc-compilers?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_MPAE_Examples&utm_content=pic16f18076-read-write-external-memory-github)
20
+
- MPLAB Code Configurator (MCC) [5.2.2 or newer](https://www.microchip.com/en-us/tools-resources/configure/mplab-code-configurator?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_pic16f18076&utm_content=pic16f18076-eeprom-demo-mplab-mcc)
- [Curiosity Nano Base for Click boards™](https://www.microchip.com/en-us/development-tool/AC164162?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_pic16f18076&utm_content=pic16f18076-eeprom-demo-mplab-mcc)
-[Curiosity Nano Base for Click boards](https://www.microchip.com/en-us/development-tool/AC164162?utm_source=GitHub&utm_medium=TextLink&utm_campaign=MCU8_MMTCha_pic16f18076&utm_content=pic16f18076-eeprom-demo-mplab-mcc)
- Logic Analyzer such as [Saleae Logic 8™](https://usd.saleae.com/products/saleae-logic-8)or similar (optional, but highly recommended for debugging)
30
30
31
31
## Setup
32
32
33
33
### Hardware Setup
34
-
The PIC16F18076 curiosity nano development board is connected to the curiosity nano base board with the Mikroe EEPROM 7 click board placed in mikro BUS 1.
35
-
34
+
The PIC16F18076 Curiosity Nano development board is connected to the Curiosity Nano base board with the Mikroe EEPROM 7 Click board placed in mikroBUS™ 1.
36
35
### MPLAB Code Configurator Setup
37
36
38
37
### Configuration Bits
39
38

40
39
41
-
Set External Oscillator Selection bits to "Oscillator Not Enabled" and "Reset Oscillator Selection bits" to "HFINTOSC (32 MHz)".
40
+
Set "External Oscillator Selection bits" to "Oscillator Not Enabled" and "Reset Oscillator Selection bits" to "HFINTOSC (32 MHz)".
42
41
43
42
### Clock Control
44
43

45
44
46
45
Set the "Current Oscillator Source Select" to "HFINTOSC_32MHz" and the "HF Internal Clock" to "32_MHz".
In the "Pins" menu the user should rename pins RB3, RD3, and RD7 to "CS1", "HLD", and "WP" respectively for the function pin names to match the function of the corresponding pins.
61
+
In the **Pins** tab, rename pins RB3, RD3, and RD7 to "CS1", "HLD", and "WP" respectively, for the function pin names to match the function of the corresponding pins.
63
62

64
63
65
-
IMPORTANT NOTE: The user should also disable the Slew Rate for pins SPI Pins: SCK1, SDI1, SDO1 (RB2, RB1, RB0 respectively). Leaving the Slew Rate limit active on the MSSP SPI pins can cause issues with higher MSSP clock frequencies.
64
+
**IMPORTANT NOTE:** Disable the “Slew Rate” for SPI pins: SCK1, SDI1, SDO1 (RB2, RB1, RB0 respectively). Leaving the Slew Rate limit active on the MSSP SPI pins can cause issues with higher MSSP clock frequencies.
66
65
67
66
### SPI MSSP1
68
67

69
68
70
-
The MSSP SPI should be configured to "Host Mode" in "SPI Mode" should be set to "SPI Mode 0", with the input data sampled in the middle. The "Clock Source Selection" should be set to one of the "FOSC" setting, this example uses "FOSC/4" however "FOSC/16" and "FOSC/64" will work too.
69
+
Configure the MSSP1 SPI to "Host Mode" and set "SPI Mode" to "SPI Mode 0", with the input data sampled in the middle. Set the "Clock Source Selection" to one of the "FOSC" settings. This example uses "FOSC/4", but "FOSC/16" and "FOSC/64" will work too.
71
70
72
71
### UART2
73
72

74
73
75
-
The user may set whatever baud rate they choose. A baud rate of 115200 will be used for this example.
76
-
Note: "Redirect Printf to UART" should be enabled for debugging and displaying test results for this demo, however is not necessary if the user only needs to write and read data to the external EEPROM.
74
+
The user may set whatever baud rate they choose. A baud rate of 115200 is used for this example.
75
+
76
+
**Note:** "Redirect Printf to UART" should be enabled for debugging and displaying test results for this demo, however is not necessary if the user only needs to write and read data to the external EEPROM.
77
77
78
78
### Application Code
79
79
80
-
Note: For simplicity and readability, the EEPROM OPCODES are defined as shown below and will be identified by their defined names throughout the code. Additionally all printf debug statements have been removed from the code snippets displayed here.
80
+
**Note:** For simplicity and readability, the EEPROM OPCODES are defined as shown below and will be identified by their defined names throughout the code. Additionally, all `printf` debug statements have been removed from the code snippets displayed here.
81
81
82
82
```C
83
83
#defineWRITE_OPCODE 0x02
84
84
#defineREAD_OPCODE 0x03
85
85
#defineWRDI_OPCODE 0x04 //Reset Write Enable
86
-
#defineRDSR_OPCODE 0x05 //Read Status Register OPCODE
86
+
#defineRDSR_OPCODE 0x05 //Read STATUS Register OPCODE
Before any write can be initiated with the 25CSM04 EEPROM a Write Enable Opcode must be sent over the SDO line to the device. This function sends that opcode then uses the eepromReadStatusRegister() function to check the EEPROM's Status Register for a successful write enable. This function is automatically called in both write functions in this demo.
107
+
Before any write can be initiated with the 25CSM04 EEPROM, a Write Enable Opcode must be sent over the Serial Data Out (SDO) line to the device. This function sends that opcode, then uses the readStatusRegister() function to check the EEPROM STATUS register for a successful write enable. This function is automatically called in both write functions used for this demo.
108
108
109
-
#### eepromReadStatusRegister()
109
+
#### readStatusRegister()
110
110
```C
111
111
uint16_treadStatusRegister(void)
112
112
{
113
113
uint16_t RDSR = 0x0000;
114
114
CS1_SetLow();
115
-
SPI1_ByteExchange(RDSR_OPCODE); //Send Read Status Register OPCODE
115
+
SPI1_ByteExchange(RDSR_OPCODE); //Send Read STATUS Register OPCODE
116
116
RDSR = (uint16_t)SPI1_ByteExchange(0xff); //Read back incoming RDSR Byte 0
This function sends the RDSR_OPCODE through the MSSP and returns the status register. It's polled automatically in eepromWriteEnable() to check for a successful "Write Enable" operation and polled after every "Write" operation for the completion of that operation. This instruction may be bypassed in favor of a 5ms delay between write operations, however polling the Status Register will always be either quicker or equal to the 5ms delay.
122
+
This function sends the RDSR_OPCODE through the MSSP and returns the status register. It's polled automatically in eepromWriteEnable() to check for a successful write enable operation and polled after every write operation for the completion of that operation. This instruction may be bypassed in favor of a 5 ms delay between write operations, however polling the STATUS register will always be either quicker or equal to the 5 ms delay.
The eepromWriteBlock() function follows the same principle as eepromWriteByte(), however it writes multiple bytes. The user should be aware this EEPROM segments its memory into 256-byte pages, and a block of data larger than a page will not be written properly. When a block write command reaches the end of a page the address will wrap around to the beginning of a page, so any data written past 256 bytes in a single block write will overwrite the data written at the beginning of that write. If the user desires to send more than 256-bytes at once they should split the data into smaller blocks and use multiple write commands.
179
+
The eepromWriteBlock() function follows the same principle as eepromWriteByte(), but writes multiple bytes. Note that this EEPROM segments its memory into 256-byte pages, and a block of data larger than a page will not be written properly. When a block write command reaches the end of a page, the address will wrap around to the beginning of a page, so any data written past 256 bytes in a single block write will overwrite the data written at the beginning of that write. If more than 256-bytes need to be sent at once, the user can split the data into smaller blocks and use multiple write commands.
The eepromReadByte() function fills an array with the READ_OPCODE and specified address then uses SPI1_BufferExchange() to read the data located at the specified address on the external EEPROM.
200
+
The eepromReadByte() function fills an array with the READ_OPCODE and specified address, then uses SPI1_BufferExchange() to read the data located at the specified address on the external EEPROM.
The eepromReadBlock() function functions just like eepromReadByte(), however reads a specified number of bytes and then stores the returned values at the address for variable "block". Unlike eepromWriteBlock(), a single block read command can continue past the end of a page and read the entire EEPROM if desired. The function will start at the address specified by "startingAddress" and increment upwards with each subsequent clock cycle.
219
+
The eepromReadBlock() functions just like eepromReadByte(), but reads a specified number of bytes and then stores the returned values at the address for variable “block”. Unlike eepromWriteBlock(), a single block read command can continue past the end of a page and read the entire EEPROM, if desired. The function will start at the address specified by “startingAddress” and increment upwards with each subsequent clock cycle.
This test uses eepromWriteBlock() and eepromReadBlock() to write and read a generated array. A saved copy of the written data is used for comparing with the read data.
292
292
293
-
Note: Due to eepromWriteBlock() wrapping around the EEPROM's memory pages and eepromReadBlock() continuing to the next page, the starting address of this test should be at the beginning of a page (any valid address that ends with 0x00 should work, eg. 0x123400, 0x000100). Otherwise the address of the written data and read data will differ after the end of a page.
293
+
**Note:** Due to eepromWriteBlock() wrapping around the EEPROM's memory pages and eepromReadBlock() continuing to the next page, the starting address of this test needs to be at the beginning of a page. Any valid address that ends with 0x00 is appropriate (e.g., 0x123400, 0x000100). Otherwise, the address of the written data and read data will differ after the end of a page.
294
294
295
295
#### main()
296
296
```C
@@ -323,4 +323,4 @@ The demonstration will automatically run on programming and output the results o
323
323
324
324
## Summary
325
325
326
-
This example demonstrates basic read and write functionality using a PIC16F18076 microcontroler and an external 25CSM04 EEPROM device on a Mikroe EEPROM 7 click board.
326
+
This example demonstrates basic read and write functionality using a PIC16F18076 microcontroler and an external 25CSM04 EEPROM device on a Mikroe EEPROM 7 Click board.
0 commit comments