|
|
View previous topic :: View next topic |
Author |
Message |
jinggy
Joined: 20 May 2008 Posts: 9 Location: malaysia
|
looping problem |
Posted: Thu Jul 10, 2008 8:01 am |
|
|
hello all. my code is shown below. the problem is the for(addr=0; addr < EEPROM_SIZE; addr ++) is not working. everytime the data is save into addr = 0.
ur help will be much appreciated!
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
char k;
int16 addr;
int8 datain[1];
int8 dataout[1];
byte string1[] = "0F02A670DF";
byte string2[] = "0F02A66F79";
typedef enum { INITIAL_STATE, KB_PROCESSING_STATE, SCAN_TAG_STATE } state_t;
void main()
{
state_t state = INITIAL_STATE;
int i;
byte buf[12];
lcd_init();
kbd_init();
ds1307_init();
init_ext_eeprom();
usb_init(); //inicializamos el USB
while(TRUE)
{
for(addr = 0; addr < EEPROM_SIZE; addr++)
{
switch ( state )
{
case INITIAL_STATE:
lcd_putc("\fIICP\n");
delay_ms(2000);
lcd_putc("\fEnter Subject Code:\n#:cont *:delete");
state = KB_PROCESSING_STATE;
break;
case KB_PROCESSING_STATE:
switch ( kbd_getc() )
{
case 0:
break;
case '*':
lcd_putc ( '\f' );
break;
case 'A':
lcd_putc ( "\fUSB" );
USB_TRANSFER();
break;
case '#':
lcd_putc ( "\fEntered\n" );
delay_ms(2000);
lcd_putc("\fScan Tag:\n");
state = SCAN_TAG_STATE;
break;
default:
lcd_putc(k);
KEYPAD_WRITE_EEPROM();
write_ext_eeprom(addr, input);
break;
}
break;
case SCAN_TAG_STATE:
output_low(PIN_C6);
while (getc() != 0x0A) ; //wait for the tag
//Now only have 11 characters to read
for ( i = 0; i < 11; ++i )
buf[i] = getc();
if( strncmp(buf,string1,10) == 0)
{
lcd_putc("\f1");
input = 0x01;
write_ext_eeprom(addr, input);
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
write_ext_eeprom(addr,sec);
write_ext_eeprom(addr,min);
write_ext_eeprom(addr,hrs);
write_ext_eeprom(addr,day);
write_ext_eeprom(addr,month);
write_ext_eeprom(addr,yr);
}
else if( strncmp(buf,string2,10) == 0)
{
lcd_putc("\f2");
input = 0x02;
write_ext_eeprom(addr, input);
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
write_ext_eeprom(addr,sec);
write_ext_eeprom(addr,min);
write_ext_eeprom(addr,hrs);
write_ext_eeprom(addr,day);
write_ext_eeprom(addr,month);
write_ext_eeprom(addr,yr);
}
else
lcd_putc("\fUnauthorized tag");
delay_ms(5000);
output_high(PIN_C6);
state = INITIAL_STATE;
break;
}
}
}
}
|
|
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Thu Jul 10, 2008 8:35 am |
|
|
Just a quick look, but it seems that addr isn't incremented after the
write_ext_eeprom.
so you write sec to address 0 then min to address 0 then hrs to address 0
...
everything is written to the same spot. |
|
|
jinggy
Joined: 20 May 2008 Posts: 9 Location: malaysia
|
|
Posted: Thu Jul 10, 2008 10:32 am |
|
|
i do realize that but how do i change the code? and why cant addr++ make the value of addr increase everytime after a data is being saved? |
|
|
Indy
Joined: 16 May 2008 Posts: 24
|
|
Posted: Thu Jul 10, 2008 11:11 am |
|
|
jinggy wrote: | i do realize that but how do i change the code? and why cant addr++ make the value of addr increase everytime after a data is being saved? | addr++ will increment the address but look at the following code: Code: | write_ext_eeprom(addr,sec);
write_ext_eeprom(addr,min);
write_ext_eeprom(addr,hrs);
write_ext_eeprom(addr,day);
write_ext_eeprom(addr,month);
write_ext_eeprom(addr,yr); | Here you are using the same value of addr 7 times. One solution is to replace all these references by 'addr++'.
Don't forget to add an extra test for overflowing the maximum eeprom address. The for-next loop does contain a test for EEPROM_SIZE but now you are writing 7 bytes at once.
Problem 2: the first time you enter the loop. Because you have the state INITIAL_STATE running first the value of addr has increased to 1 when you are using it the first time. Now your data starts at address 1 instead of 0.
This can be solved by removing the for-loop. Only increment addr when you call write_ext_eeprom as suggested above.
Problem 3: Addr is never reset to 0. |
|
|
jinggy
Joined: 20 May 2008 Posts: 9 Location: malaysia
|
|
Posted: Thu Jul 10, 2008 12:46 pm |
|
|
thanks for ur reply Indy!
so meaning that i have to remove the For loop and change addr to addr++ right?
can i change the code to:
if (addr < EEPROM_SIZE)
{
write_ext_eeprom(addr++, input)
write_ext_eeprom(addr++, sec)
write_ext_eeprom(addr++, yr)
}
and when i read back the data, i do the same? |
|
|
Indy
Joined: 16 May 2008 Posts: 24
|
|
Posted: Thu Jul 10, 2008 5:41 pm |
|
|
jinggy wrote: | can i change the code to:
if (addr < EEPROM_SIZE)
{
write_ext_eeprom(addr++, input)
write_ext_eeprom(addr++, sec)
write_ext_eeprom(addr++, yr)
}
and when i read back the data, i do the same? | Yes, that's the basic idea. Don't forget to change 'addr' to 'addr++' in all other calls to write_ext_eeprom().
Code: | if (addr < EEPROM_SIZE) | Change this to: Code: | if ( (EEPROM_SIZE - addr) >= 3 ) | '3' because you are going to write 3 bytes and we want to check if enough space is available. |
|
|
jinggy
Joined: 20 May 2008 Posts: 9 Location: malaysia
|
|
Posted: Thu Jul 10, 2008 8:31 pm |
|
|
so i've changed the code to as below and it's not working. any idea?
writing:
Code: |
void main()
{
state_t state = INITIAL_STATE;
int i;
byte buf[12];
lcd_init();
kbd_init();
ds1307_init();
init_ext_eeprom();
usb_init(); //inicializamos el USB
while(TRUE)
{
switch ( state )
{
case INITIAL_STATE:
lcd_putc("\fIICP\n");
delay_ms(2000);
lcd_putc("\fEnter Subject Code:\n#:cont *:delete");
state = KB_PROCESSING_STATE;
break;
case KB_PROCESSING_STATE:
switch ( kbd_getc() )
{
case 0:
break;
case '*':
lcd_putc ( '\f' );
break;
case 'A':
lcd_putc ( "\fUSB" );
USB_TRANSFER();
break;
case '#':
lcd_putc ( "\fEntered\n" );
delay_ms(2000);
lcd_putc("\fScan Tag:\n");
state = SCAN_TAG_STATE;
break;
default:
lcd_putc(k);
KEYPAD_WRITE_EEPROM();
if ( (EEPROM_SIZE - addr) >= 1 )
{
write_ext_eeprom(addr++, input);
}
break;
}
break;
case SCAN_TAG_STATE:
output_low(PIN_C6);
while (getc() != 0x0A) ; //wait for the tag
//Now only have 11 characters to read
for ( i = 0; i < 11; ++i )
buf[i] = getc();
if( strncmp(buf,string1,10) == 0)
{
lcd_putc("\f1");
input = 0x01;
if ( (EEPROM_SIZE - addr) >= 1 )
{
write_ext_eeprom(addr++, input);
}
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
if ( (EEPROM_SIZE - addr) >= 6 )
{
write_ext_eeprom(addr++,sec);
write_ext_eeprom(addr++,min);
write_ext_eeprom(addr++,hrs);
write_ext_eeprom(addr++,day);
write_ext_eeprom(addr++,month);
write_ext_eeprom(addr++,yr);
}
}
delay_ms(5000);
output_high(PIN_C6);
state = INITIAL_STATE;
break;
}
}
}
|
reading:
Code: |
void USB_TRANSFER()
{
usb_task(); //habilita periferico usb e interrupciones
usb_wait_for_enumeration();
while(TRUE)
{
if(usb_enumerated()) //si el PicUSB está configurado
{
if (usb_kbhit(1)) //si el endpoint de salida contiene datos del host
{
usb_get_packet(1, datain, 1); //cojemos el paquete de tamaño 3bytes del EP1 y almacenamos en recibe
switch(datain [0]) //command
{
case 0x01:
if (addr < EEPROM_SIZE)
{
dataout = read_ext_eeprom(addr++);
}
usb_put_packet(1, dataout, 1, USB_DTS_TOGGLE);
}
}
}
}
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Fri Jul 11, 2008 3:21 am |
|
|
Try initialising addr.
So, where you declare it:
int16 addr=0;
or just add the line 'addr=0' before you use it.
Unless you declare a variable as 'static', it is _not_ by default cleared.
Best Wishes |
|
|
|
|
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
|