View previous topic :: View next topic |
Author |
Message |
mahdifahime
Joined: 05 Jan 2013 Posts: 22
|
problem by interrupt timer and read external eeprom |
Posted: Tue Mar 26, 2013 12:28 am |
|
|
i am write program and problem by interrupt timer2 and read external eeprom
Code: |
#include <16f72.h>
#device adc=10
#use delay (crystal=20Mhz)
#fuses hs,NOWDT,BROWNOUT,PROTECT
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#use i2c(master,SDA=PIN_C4,SCL=PIN_C3)
#include <2408.c>
#byte t1con=0x10
#int_timer2
void timer2_isr(void) {
if(++tick>=100&&shasyz==0) {
tick=0;
output_toggle(led);
}
}
void main(){
init_ext_eeprom();
setup_timer_2 ( T2_DIV_BY_16,250,16);
enable_interrupts(INT_timer2);
enable_interrupts(GLOBAL);
set_tris_b(0b00000101);set_tris_a(0b0000011);
int16 adress,i;
int8 adres1,adres2;int1 gg=0;
while(true){
adres1=read_ext_eeprom(0);
adres2=read_ext_eeprom(1);
adress=make16 (adres2,adres1);
for (i=0;i<1023;i+=2){ i++;
if (byte3==read_ext_eeprom(i)&&byte2==read_ext_eeprom(i+1)&&byte1==read_ext_eeprom(i+2)){output_high(led);i=1024;gg=1;}}
and.........}
|
When external memory is read,after 2 or 3 hours data is written into the memory itself, and it is because of timer interrupt.
how can i avoid this problem?????
Last edited by mahdifahime on Tue Mar 26, 2013 11:16 pm; edited 1 time in total |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Mar 26, 2013 4:08 am |
|
|
You've had no response because you don't supply enough information.
For me to help, you need to post the SHORTEST possible complete, compilable code which illustrates the problem.
I can then cut and paste, so that it can be tested.
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Tue Mar 26, 2013 4:29 am |
|
|
As a general comment which could encourage problems, declare your variables the 'C' way.
In C, mid block variable declarations are illegal. Variables _must_ be declared at the start of the code sections. CCS accepts mid block declarations, and doesn't complain, but has a habit of corrupting variables declared like this. So stick to proper C syntax....
Also are you sure your maths is right. You are reading three bytes, then incrementing by two.
Best Wishes |
|
|
mahdifahime
Joined: 05 Jan 2013 Posts: 22
|
|
Posted: Tue Mar 26, 2013 9:23 am |
|
|
how fast the computation timer is more ,for example
setup_timer_2 ( T2_DIV_BY_16,240,16); be
setup_timer_2 ( T2_DIV_BY_16,254,16);
The eeprom is written more quickly , However, read-only from eeprom |
|
|
ck
Joined: 02 May 2012 Posts: 18
|
|
Posted: Tue Mar 26, 2013 10:40 am |
|
|
you need to reset TMR2IF adding
Code: |
clear_interrupt(INT_TIMER2);
|
before exit form interrupt like here:
Code: |
#int_timer2
void timer2_isr(void) {
if(++tick>=100&&shasyz==0) {
tick=0;
output_toggle(led);
}
clear_interrupt(INT_TIMER2);
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Tue Mar 26, 2013 10:46 am |
|
|
ck wrote: | you need to reset TMR2IF adding
Code: |
clear_interrupt(INT_TIMER2);
|
before exit form interrupt like here:
Code: |
#int_timer2
void timer2_isr(void) {
if(++tick>=100&&shasyz==0) {
tick=0;
output_toggle(led);
}
clear_interrupt(INT_TIMER2);
}
|
|
No, you don't.
CCS automatically clears the interrupt for you, unless you say 'noclear' in the interrupt declaration.
This is not needed.
What is not clear is what the problem actually is.
He refers to writing the external EEPROM, but does not show anything doing this. If he is this will take an age (4mSec). He talks about 'computation time', but doesn't show any computation. He has variables being used, but doesn't show the declarations for them. etc. etc..
Best Wishes |
|
|
mahdifahime
Joined: 05 Jan 2013 Posts: 22
|
|
Posted: Tue Mar 26, 2013 11:18 am |
|
|
the library for 24c08 is
+++++++++++++++++++++++++
2408.c code deleted.
10. Don't post the CCS example code or drivers, or ask for such code and drivers.
http://www.ccsinfo.com/forum/viewtopic.php?t=26245
- Forum Moderator
+++++++++++++++++++++++++
The problem is not here ??
Code: |
while(!ext_eeprom_ready());
i2c_start();
i2c_write((0xa0|(BYTE)(address>>7))&0xfe);
i2c_write(address);
i2c_start();
i2c_write((0xa0|(BYTE)(address>>7))|1);
data=i2c_read(0);
i2c_stop();
return(data);
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Tue Mar 26, 2013 11:54 am |
|
|
We know what the library looks like.
What you are not telling us is what _your_ problem actually is.... |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Mar 26, 2013 3:14 pm |
|
|
I'm totally confused by this thread.
Please explain CLEARLY what the problem is.
There are now two of us asking.
Mike |
|
|
mahdifahime
Joined: 05 Jan 2013 Posts: 22
|
|
Posted: Tue Mar 26, 2013 11:37 pm |
|
|
the problem is write into eeprom.
I'm not write into eeprom.
I'm just read from eeprom.but false information write into eeprom!! while i am just read from eeprom
Code: |
#include <16f72.h>
#use delay (crystal=20Mhz)
#fuses hs,NOWDT,BROWNOUT,PROTECT
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#define led pin_c5
#define shasy pin_b2
#use i2c(master,SDA=PIN_C4,SCL=PIN_C3)
#include <2408.c>
#include <on.c>
#byte t1con=0x10
int8 shasyz=0,feshari;
int8 tick;
int16 shomaresh,time;
#int_timer0
void Timer0_isr()
{shomaresh+=1;feshari+=1;
time+=1;
return;}
#int_timer2
void timer2_isr(void) {
if(++tick>=20&&shasyz==0) {
tick=0;
output_toggle(led);
}
}
void main(){ output_b(0b0);
setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_256);
interrupt_active(INT_TIMER0);
setup_timer_2 ( T2_DIV_BY_16,254,16);
enable_interrupts(INT_timer2);
enable_interrupts(GLOBAL);
set_tris_b(0b00000101);set_tris_a(0b0000011);
int16 i;
int8 adres1,adres2,byte1,byte2,byte3;
int1 gg=0;
while(true){m:
if (shasyz==2)output_high(led);t1con=0b00110000;
set_timer1(0) ;
if(input(shasy)){shomaresh=0;;while(input(shasy)){enable();
if (shomaresh>45){shomaresh=0;cheshmak(0,10,i,50);shasyz=10; output_low(led);
while(input(shasy)){enable();if (shomaresh>500){disable();}}}}}//}}
byte3=34;byte2=54;byte3=120;
adres1=read_ext_eeprom(0);
adres2=read_ext_eeprom(1);
for (i=0;i<1023;i+=2){ i++;
if (byte3==read_ext_eeprom(i)&&byte2==read_ext_eeprom(i+1)&&byte1==read_ext_eeprom(i+2)){output_high(led);i=1024;gg=1;}}
if(gg==1){
output_high(led);
gg=0;}}}
|
and include on is:
Code: |
void cheshmak(a,b,i,d){for(i=a;i<b;i++){output_toggle(led);delay_ms(d);}}
void enable(){enable_interrupts(INT_TIMER0);}
void disable(){disable_interrupts(INT_TIMER0);}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Wed Mar 27, 2013 2:46 am |
|
|
Messy code....
However the first question is have you verified it is the EEPROM that is corrupted, rather than what is being read?. So after the problem shows, read the EEPROM in an external programmer and verified what is contains?.
Second, spilt things up. I'd never consider doing three successive EEPROM reads in one line of code with value tests as well. You are gaining nothing by doing this all in one line, except raising the probability of the compiler running out of scratch memory. It is limited, especially on a chip with as little RAM as the 16F72.
I still raise the question whether the maths is right here. You are testing three successive bytes for a particular data pattern, but looping forward by two addresses at a time.
My comment still applies about the variable declarations. Put these where C requires these to be.
Then remember that variables that are not initialised can contain anything. tick, shomaresh, & time, could all wake up containing anything. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Mar 27, 2013 4:11 am |
|
|
I have difficulty following your code structure.
I always try to arrange each closing } to be immediately below its opening { with clear space between.
You seem to have had problems with the structure, as you've commented out some }}s
You're declaring these variables mid-definition Code: | int16 i;
int8 adres1,adres2,byte1,byte2,byte3;
int1 gg=0; |
To me this line does not make sense Code: | byte3=34;byte2=54;byte3=120; |
You're making byte3 equal to 34 then 120.
It's either a genuine error or the posted code is not the code you've actually tested.
I'm also unsure that you actually KNOW what's supposed to in the EEPROM.
Mike
EDIT Why are you talking directly to the T1CON register?
Last edited by Mike Walne on Wed Mar 27, 2013 4:21 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Wed Mar 27, 2013 4:19 am |
|
|
There is one particular thing that might be causing problems with reads, but which would not change the data in the ROM.
He is using a relatively unusual 'old' PIC, which was one of the first to support lower voltage operation. Now if he is running at 3.3v (say), the data for the 2408 changes. At 5v, you can issue a second read just 1.3uSec after one terminates. With a standard PIC running say 4Mhz, this never happens, so there is not a problem. However at 3.3v, the delay time between transactions goes up to 4.7uSec, and with a processor at 20MHz, especially with the unknown behaviour putting everything into combined lines, I'd not be surprised to see this time being broken. If so the read data will be corrupted...
What happens is that when you read from a cell, the chip automatically goes and fetches the contents of the next cell. If you start a command before this has completed, you get data corruption. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Mar 27, 2013 5:17 am |
|
|
other hardware issues can be missing or incorrect I2C bus pullups,distance between PIC and EEPROM,noisy Vdd,marginal Vdd,etc.
Code could be 100% correct but never work right on incorrect hardware.
PCM programmer's diagnostic pgm would help.
hth
jay |
|
|
mahdifahime
Joined: 05 Jan 2013 Posts: 22
|
|
Posted: Wed Mar 27, 2013 11:09 am |
|
|
The problem was solved by use delay_us(500);
Code: |
adres1=read_ext_eeprom(0);delay_us(500);
adres2=read_ext_eeprom(1);delay_us(500);
adress=make16 (adres2,adres1);
for (i=adress;i<1023;i+=2){ i++;
r3=read_ext_eeprom(i);delay_us(500);r2=read_ext_eeprom(i+1);delay_us(500);r1=read_ext_eeprom(i+2);delay_us(500);
if (byte3==r3&&byte2==r2&&byte1==r1){output_high(led);i=1024;gg=1;}}
|
|
|
|
|