|
|
View previous topic :: View next topic |
Author |
Message |
charlotte13 Guest
|
read 25LC640 via RS232 |
Posted: Fri Jun 20, 2008 4:30 pm |
|
|
hello everybody. i'd like to ask a few questions about reading an external eeprom (25LC640) via RS232.
here's the test program i grabbed from this forum.
Code: |
Hardware SPI driver for 25LC640:
#ifndef EEPROM_SELECT
#define EEPROM_SELECT PIN_C2
#define EEPROM_CLK PIN_C1
#define EEPROM_DI PIN_E1
#define EEPROM_DO PIN_E2
#endif
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 8192
void init_ext_eeprom()
{
output_high(EEPROM_SELECT);
setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_16 );
}
//--------------------------------
int1 ext_eeprom_ready(void)
{
int8 data;
output_low(EEPROM_SELECT);
spi_write(0x05);
data = spi_read(0);
output_high(EEPROM_SELECT);
return(!bit_test(data, 0));
}
//--------------------------------
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data)
{
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
spi_write(0x06);
output_high(EEPROM_SELECT);
output_low(EEPROM_SELECT);
spi_write(0x02);
spi_write(address >> 8);
spi_write(address);
spi_write(data);
output_high(EEPROM_SELECT);
}
//--------------------------------
BYTE read_ext_eeprom(EEPROM_ADDRESS address)
{
int8 data;
while(!ext_eeprom_ready());
output_low(EEPROM_SELECT);
spi_write(0x03);
spi_write(address >> 8);
spi_write(address);
data = spi_read(0);
output_high(EEPROM_SELECT);
return(data);
} |
Test program:
Code: |
#include <18F4550.h>
#fuses HSPLL,USBDIV,PLL5,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010
#include <25LC640_Hardware_SPI.c>
#include <STDLIB.H>
//========================
void main()
{
int8 data;
int8 wrote;
int16 addr;
int16 errors = 0;
init_ext_eeprom();
// Fill eeprom with random data.
printf("\n\r");
printf("writing");
srand(0x55);
for(addr = 0; addr < EEPROM_SIZE; addr++)
{
write_ext_eeprom(addr, (int8)rand());
if((int8)addr == 0)
putc('.');
}
// Read the eeprom and check for errors.
printf("\n\r");
printf("reading");
srand(0x55);
for(addr = 0; addr < EEPROM_SIZE; addr++)
{
data = read_ext_eeprom(addr);
wrote = (int8)rand();
if(data != wrote)
{
printf("%lx: read %x, should be %x\n\r", addr, data, wrote);
errors++;
if(errors >= 10)
break;
}
if((int8)addr == 0)
putc('.');
}
printf("\n\r");
printf("done\n\r");
while(1);
} |
so my question is, how do i know whether it's working or not using hyperterminal? i connect the circuit to pc via rs232 and a max232. hyperterminal setting: baud rate: 9600, flow control: none, data bits: 8, parity: none and stop bits: 1. and for ASCII setup, i've checked the box: echoed typed characters locally.
but i couldn't get anything from hyperterminal. anything that i've missed out? pls let me know.
thanks in advance people! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 20, 2008 5:05 pm |
|
|
Quote: | #ifndef EEPROM_SELECT
#define EEPROM_SELECT PIN_C2
#define EEPROM_CLK PIN_C1
#define EEPROM_DI PIN_E1
#define EEPROM_DO PIN_E2
#endif
#include <18F4550.h> |
The pins given above are not the hardware SPI pins on the 18F4550.
The correct pins are:
Code: |
#define EEPROM_CLK PIN_B1
#define EEPROM_DI PIN_C7
#define EEPROM_DO PIN_B0
|
However, those #define statements are not actually used by the driver.
But you do need to make the correct connections between the PIC and
the EEPROM, as follows (assuming the 40-pin DIP package):
Code: |
18F4550 25LC640
pin 26 (SDO, RC7) pin 5 (SI)
pin 33 (SDI, RB0) pin 2 (SO)
pin 34 (SCK, RB1) pin 6 (SCK)
pin 15 (RC0) pin 3 (\CS)
|
I put the \CS signal on pin C0 because it's a better choice than pin C2.
Pin C2 is used for hardware PWM output. You might want to use it for
that in the future.
Note that the 18F4550 multiplexes the SDO and Tx functions on pin C6.
So you can't use the hardware UART if you are using the hardware SPI
module. I suggest that you use some other general purpose i/o pins.
The example below will create a software UART on pins D2 and D3:
Code: | #use rs232(baud=9600, xmit=PIN_D2, rcv=PIN_D3) |
|
|
|
charlotte13 Guest
|
|
Posted: Fri Jun 20, 2008 5:43 pm |
|
|
okay. so i must use those pins u've mentioned in ur reply? what if my port B and C are already occupied? can i connect to port E using the driver 25640.c provided in the CCS's drivers folder? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 20, 2008 6:01 pm |
|
|
Yes, if your hardware SPI pins are in use, then you can use the
software SPI instead. It's in this directory:
Quote: | c:\program files\picc\drivers\25640.c |
|
|
|
charlotte13 Guest
|
|
Posted: Fri Jun 20, 2008 6:14 pm |
|
|
i've tried the driver. i take input from a 4X4 keypad and save it into 25LC640.
here's my code:
Code: | #include <18F4550.h>
#fuses HSPLL,USBDIV,PLL5,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <lcd.c>
#include <25640.c>
#define LCD_E PIN_D0
#define LCD_RS PIN_D1
#define LCD_RW PIN_D2
#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7
//Keypad connection:
#define row0 PIN_B0
#define row1 PIN_B1
#define row2 PIN_B2
#define row3 PIN_B3
#define col0 PIN_B4
#define col1 PIN_B5
#define col2 PIN_B6
#define col3 PIN_B7
// Keypad layout:
char const KEYS[4][4] =
{{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}};
#define KBD_DEBOUNCE_FACTOR 33 // Set this number to apx n/333 where
// n is the number of times you expect to call kbd_getc each second
void kbd_init()
{
//set_tris_b(0xF0);
//output_b(0xF0);
port_b_pullups(true);
}
short int ALL_ROWS (void)
{
if(input (row0) & input (row1) & input (row2) & input (row3))
return (0);
else
return (1);
}
char kbd_getc()
{
static byte kbd_call_count;
static short int kbd_down;
static char last_key;
static byte col;
byte kchar;
byte row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR)
{
switch (col)
{
case 0:
output_low(col0);
output_high(col1);
output_high(col2);
output_high(col3);
break;
case 1:
output_high(col0);
output_low(col1);
output_high(col2);
output_high(col3);
break;
case 2:
output_high(col0);
output_high(col1);
output_low(col2);
output_high(col3);
break;
case 3:
output_high(col0);
output_high(col1);
output_high(col2);
output_low(col3);
break;
}
if(kbd_down)
{
if(!ALL_ROWS())
{
kbd_down=false;
kchar=last_key;
last_key='\0';
}
}
else
{
if(ALL_ROWS())
{
if(!input (row0))
row=0;
else if(!input (row1))
row=1;
else if(!input (row2))
row=2;
else if(!input (row3))
row=3;
last_key =KEYS[row][col];
kbd_down = true;
}
else
{
++col;
if(col==4)
col=0;
}
}
kbd_call_count=0;
}
return(kchar);
}
void main()
{
char k;
char data;
int16 addr;
lcd_init();
kbd_init();
init_ext_eeprom();
lcd_putc("\fReady\n");
while(TRUE)
{
k=kbd_getc();
if(k!=0)
{
if(k=='*')
lcd_putc('\f');
else
lcd_putc(k);
}
for(addr = 0; addr < EEPROM_SIZE; addr++)
{
write_ext_eeprom(addr, k);
data = read_ext_eeprom(addr);
}
printf(data);
}
} |
i changed the pin connection in the driver to:
Code: | #ifndef EEPROM_SELECT
#define EEPROM_SELECT PIN_C2
#define EEPROM_CLK PIN_C1
#define EEPROM_DI PIN_E1
#define EEPROM_DO PIN_E2
#endif |
but no, it still not working. Input from keypad successfully displayed on the LCD but i couldn't read anything using hyperterminal. any idea?
thanks in advance! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 20, 2008 6:39 pm |
|
|
You can't give a character variable to printf by itself. You have to use
a format string. Please read about how to use printf in a C tutorial. |
|
|
|
|
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
|