I have to make a quick test of a new eeprom (24LC256) i am going to use, so i wired it up to one of the mE EEPROM boards and began my testing on a PIC16F887 (EasyPic 6 board). Using the mE advanced example i only had to make 1 change to the EEPROM.c functions and that was to operate with upper + lower address bytes. Everything worked perfectly and quickly. I can now move on with the confidence that the part is working (rules out any soldering errors etc).
Now the EEPROM will be used in a 3v system. So i then wired (unplugged from easypic6 board and plugged into LV24-33A board [while respecting RG2 = SCL1 & RG3 = SDA1]) the EEPROM on to a PIC24FJ128 (LV24-33A board). As there is no mE example of hardware I2C included with the dsPIC 4.80 for PIC24 i combined the LCD example and the PIC33 I2C advanced example to end up with a working PIC24 Advanced I2C example.
ok so compile and run and no output on the LCD during the readback section... arg power up the scope and start the ICD hardware debug to look at the I2C registers. It was a quick debug as i instantly noticed I2C1CON.ACKDT was being set incorrectly.
for this particular PIC24, the ACK/nACK bits are being set inverted.
so in order to have a working example i had to change the following...
this code works for PIC24
Code: Select all
while (i < rLen) {
rdData[i] = I2C1_Read(0u); // read data (acknowledge)
Delay_ms(20);
i++ ;
}
Code: Select all
while (i < rLen) {
rdData[i] = I2C1_Rd(1u); // read data (acknowledge)
Delay_ms(20);
i++ ;
}
Code: Select all
/*
* Project name:
Lcd_Test (Demonstration of the LCD library routines)
* Copyright:
(c) Mikroelektronika, 2010.
* Revision History:
20100429:
- initial release;
* Description:
This code demonstrates how to use LCD 4-bit library. LCD is first
initialized, then some text is written, then the text is moved.
* Test configuration:
MCU: dsPIC24FJ96GA010
http://ww1.microchip.com/downloads/en/DeviceDoc/39747e.pdf
Dev.Board: LV24-33 v6 - ac:LCD
http://www.mikroe.com/eng/products/view/430/lv-24-33-v6-development-system
Oscillator: XT, 8.00000 MHz
Ext. Modules: Character LCD 2x16
http://www.mikroe.com/en/tools/components/#other
SW: mikroC PRO for dsPIC30/33 and PIC24
http://www.mikroe.com/eng/products/view/231/mikroc-pro-for-dspic30-33-and-pic24/
* NOTES:
- Turn on LCD backlight at SW17.7. (board specific)
*/
#include "EEPROM_24LC256.h"
// LCD module connections
sbit LCD_RS at LATB2_bit;
sbit LCD_EN at LATB3_bit;
sbit LCD_D4 at LATB4_bit;
sbit LCD_D5 at LATB5_bit;
sbit LCD_D6 at LATB6_bit;
sbit LCD_D7 at LATB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections
char someData[] = "A5A5A5A5A5";
char i ,tmpdata; // Loop variable
void main(){
EEPROM_24LC256_Init(); // performs I2C initialization
ADPCFG = 0xFFFF; // Configure AN pins as digital I/O
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,"hello"); // Write text in first row
Delay_ms(1000);
// Example for single-byte write
i = 0;
tmpdata = 1;
while ((tmpdata = someData[i]) != 0) {
i++;
EEPROM_24LC256_WrSingle(i, tmpdata); // writes data, char by char, in the EEPROM
Delay_ms(20);
Lcd_Chr(1,i, tmpdata); // diplays data on the first row of the Lcd
}
EEPROM_24LC256_WrSingle(i+1, 0); // writes string termination
Delay_ms(20);
// Example for single-byte read
// i = 1;
// tmpdata = 1;
// while ((tmpdata = EEPROM_24LC256_RdSingle(i)) != 0) {
// Lcd_Chr(2,i, tmpdata); // displays data from EEPROM on the second row of the Lcd
// Delay_ms(20);
// i++ ;
// }
// Example for sequential data read
Delay_ms(1000);
// Lcd_Cmd(_LCD_CLEAR);
EEPROM_24LC256_RdSeq(1, someData, 13);
Lcd_Out(2,1,someData);
}
Code: Select all
// EEPROM 24LC256 read/write library
//--------------- Performs 24LC256 Init
void EEPROM_24LC256_Init() {
I2C1_Init(100000);
}
//--------------- Writes data to 24LC256 EEPROM - single location
void EEPROM_24LC256_WrSingle(unsigned short wAddr, unsigned short wData) {
I2C1_Start(); // issue I2C1 start signal
I2C1_Write(0xA2); // send byte via I2C1 (command to 24cO2)
I2C1_Write(0x00); // send upper byte (address of EEPROM location)
I2C1_Write(wAddr); // send byte (address of EEPROM location)
I2C1_Write(wData); // send data (data to be written)
I2C1_Stop();
}
//--------------- Reads data from 24LC256 EEPROM - single location (random)
unsigned short EEPROM_24LC256_RdSingle(unsigned short rAddr) {
unsigned short reslt;
I2C1_Start(); // issue I2C1 start signal
I2C1_Write(0xA2); // send byte via I2C1 (device address + W)
I2C1_Write(0x00); // send Upper byte (address of EEPROM location)
I2C1_Write(rAddr); // send Lower byte (data address)
I2C1_Restart(); // issue I2C1 signal repeated start
I2C1_Write(0xA3); // send byte (device address + R)
reslt = I2C1_Read(1u); // Read the data (NO acknowledge)
while (!I2C1_Is_Idle())
asm nop; // Wait for the read cycle to finish
I2C1_Stop();
return reslt;
}
//--------------- Reads data from 24LC256 EEPROM - sequential read
void EEPROM_24LC256_RdSeq(unsigned short rAddr,
unsigned char *rdData,
unsigned short rLen) {
unsigned short i;
I2C1_Start(); // issue I2C1 start signal
I2C1_Write(0xA2); // send byte via I2C1 (device address + W)
I2C1_Write(0x00); // send upper byte (address of EEPROM location)
I2C1_Write(rAddr); // send byte (address of EEPROM location)
I2C1_Restart(); // issue I2C1 signal repeated start
I2C1_Write(0xA3); // send byte (device address + R)
i = 0;
while (i < rLen) {
rdData[i] = I2C1_Read(0u); // read data (acknowledge)
Delay_ms(20);
i++ ;
}
rdData[i] = I2C1_Read(1u); // last data is read (no acknowledge)
I2C1_Stop();
}
Code: Select all
//EEPROM_24LC256 library header file
void EEPROM_24LC256_Init();
void EEPROM_24LC256_WrSingle(unsigned short wAddr, unsigned short wData);
unsigned short EEPROM_24LC256_RdSingle(unsigned short rAddr);
void EEPROM_24LC256_RdSeq(unsigned short rAddr,
unsigned char *rdData,
unsigned short rLen);