CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

microcontroller reset due to watchdog when we read eeprom

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
zafarkhan



Joined: 31 Oct 2007
Posts: 6

View user's profile Send private message

microcontroller reset due to watchdog when we read eeprom
PostPosted: Wed Oct 31, 2007 1:52 am     Reply with quote

microcontroller reset due to watch dog when we read internal eeprom
using READ_EEPROM(); to read calibration data at the time of start up
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Oct 31, 2007 3:39 am     Reply with quote

READ_EEPROM is very fast, so there must be another routine in your program taking a lot of time.

Sorry, without more info we can't help.
Ttelmah
Guest







PostPosted: Wed Oct 31, 2007 4:23 am     Reply with quote

What chip?.
What timeout is the Watchdog set to?.
Can you post the intial part of the code, up to the read_eeprom (ideally a stripped down 'minimum' version that shows the problem)?.
What compiler?.

There is no reason for read_eeprom to affect the watchdog. It is a fast operation, and provided the watchdog is being reset before you start - remember it starts running as soon as the chip wakes up, and if you have been doing 'slow' initialisations (things like waking an LCD), and the watchdog is on a short interval, it can expire quite early in the code.

Best Wishes
zafarkhan



Joined: 31 Oct 2007
Posts: 6

View user's profile Send private message

initial code due to which controller reset
PostPosted: Wed Oct 31, 2007 6:36 am     Reply with quote

#FUSES XT,PROTECT,NOLVP,WDT,PUT,BROWNOUT,CPD

set_tris_b(0X0); //
set_tris_D(0x80); //
set_tris_C(0x0); //
set_tris_A(0xFF); //

output_c(0x00);
output_b(0x0);
output_d(0xc0);
output_a(0xff);

delay_ms(7000);

setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);

setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(False);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // setup interrupts
set_timer1(0xF830); // sets timer to interrupt in 2000us
setup_wdt(WDT_2304MS);
enable_interrupts(INT_TIMER1);
restart_wdt();
enable_interrupts(GLOBAL);

temp1=READ_EEPROM(1);

if(temp1==1)
{
restart_wdt();
hourd1=READ_EEPROM(10);
restart_wdt();
mind1=READ_EEPROM(20);
restart_wdt();
secd1=READ_EEPROM(30);
}
Ken Johnson



Joined: 23 Mar 2006
Posts: 197
Location: Lewisburg, WV

View user's profile Send private message

PostPosted: Wed Oct 31, 2007 6:49 am     Reply with quote

what is your #use delay ? Does it have a restart_wdt ?

You have a 7-second delay near the start of your program - without the restart_wdt, it'll reset.

Ken
zafarkhan



Joined: 31 Oct 2007
Posts: 6

View user's profile Send private message

circuit restart due to watch dog
PostPosted: Thu Nov 01, 2007 12:02 am     Reply with quote

yes i have used it
#use delay(clock=4000000,RESTART_WDT)

if i omit read_eeprom all things fine but when i insert read eeprom for multiple reading of data eeprom . the whole circuit restart and restart again and again.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 01, 2007 12:58 am     Reply with quote

Which chip are you using?
Which compiler version?
zafarkhan



Joined: 31 Oct 2007
Posts: 6

View user's profile Send private message

microcontroller reset due to watch dog
PostPosted: Thu Nov 01, 2007 6:00 am     Reply with quote

i am using pic16f877a
and compiler version is 3.2
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 01, 2007 6:12 am     Reply with quote

The compiler version number is incorrect, it should have 3 digits after the dot like: 3.190, 3.249 or 4.059

Depending on your compiler version (PCM, PCW, PCWH) there are several ways to retrieve the version number, but the method working for all is to look at the top of the list file (*.lst) in your project directory.
Or, from the command line execute: "C:\Program Files\PICC\Ccsc.exe" +V
Ttelmah
Guest







PostPosted: Thu Nov 01, 2007 6:25 am     Reply with quote

Some general comments though.
When you posts a program with a problem like this, it should be a minimum _complete_ program, that shows the problem. What has been posted so far, has a lot of things that will cause problems (already mentioned, the USE DELAY), so we have to 'scratch', to actually see the problem. As posted, the program cannot work (because an interrupt is enabled, and no handler is present - this _will_cause the program to hang, and watchdog), so it is not a good start to get answers.

Best Wishes
zafarkhan



Joined: 31 Oct 2007
Posts: 6

View user's profile Send private message

thanks for the comments and here is the complete program
PostPosted: Fri Nov 02, 2007 2:21 am     Reply with quote

here is the complete program


#include <16F877A.h>

#device adc=8

#FUSES XT,PROTECT,NOLVP,WDT,PUT,BROWNOUT,CPD
#use delay(clock=4000000,RESTART_WDT)

#define eeprom_scl PIN_D6
#define eeprom_sda PIN_D7
#use i2c(Master,slow,sda=PIN_D7,scl=PIN_D6,restart_wdt)
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 512


/*
f
e|-| a
-
d|_| b
c
*/


// display pins definations


#define DIGIT1 PIN_C2 //digit#1
#define DIGIT2 PIN_C1 //digit#2
#define DIGIT3 PIN_C0 //digit#3
#define DIGIT4 PIN_D1
#define DIGIT5 PIN_D0
#define DIGIT6 PIN_C3

#define SEGB PIN_D2 //segment b
#define SEGC PIN_D3 //segment c
#define SEGE PIN_C4 //segment e
#define SEGG PIN_C5 //segment g
#define SEGA PIN_C6 //segment a
#define SEGF PIN_C7 //segment f
#define SEGD PIN_D4 //segment d

#define RLY1 PIN_B5 //output pins definations
#define RLY2 PIN_B4
#define RLY3 PIN_B2
#define RLY4 PIN_B1

#define LED1 PIN_B6 //cpu heart beat definations

#define INP1 PIN_A0 //inputs pins definations
#define INP2 PIN_A1
#define INP3 PIN_A2
#define INP4 PIN_A3
#define INP5 PIN_A4
#define INP6 PIN_A5

#define PIN5 PIN_D7 //i2c pin definations
#define PIN6 PIN_D6

#define ON_SEG 1 // if 0 is placed on segment and also 0 on digit select then seven segment will lit
#define OFF_SEG 0 // if 1 is placed on segment and also 0 on digit select then seven segment will not lit



#byte eedata=0x08 // eeprom data
#byte eeadr =0x09 // eeprom address
#byte eecon1=0x88 // eeprom control
#byte eecon2=0x89 // eeprom control
#byte option_reg=0x81
#byte int_con=0x0b //interrupt
#byte tmro=0x01 //interrupt

#byte adccon0=0x1f // adc registers
#byte adccon1=0x9f
#byte adresh=0x1e
#byte adresl=0x9e


#byte tmr1l=0x0e
#byte tmr1h=0x0f
#byte pir1=0x0c
#byte pie1=0x8c
#byte t1con=0x10


// **************** register bits individually ************************

#bit toie=int_con.5
#bit goie=int_con.7
#bit toif=int_con.2

#bit rd=eecon1.0 // eeprom control bits
#bit wr=eecon1.1
#bit wren=eecon1.2
#bit wrerr=eecon1.3
#bit eeif=eecon1.4
#bit adcs1=adccon0.7
#bit adcs0=adccon0.6
#bit chs2=adccon0.5
#bit chs1=adccon0.4
#bit chs0=adccon0.3
#bit godon=adccon0.2
#bit adcon=adccon0.0
#bit adfm=adccon1.7



unsigned int8 const lookup[25]={0x3f,0x03,0x6d,0x67,0x53,0x76,0x7e,0x23,
0x7f,0x73,0x67,0x4C,0xC7,0xCE,00,0x79,0x48,0x7c,0x4a,0x4f,0x1c,0x5b,0x40};

// code of blank =00 (location no 14)
// code of P= 0x79(location no 15)
//code of r=0x48(location no 16)
//code of E=0x7c(location no 17)
//code of n=0x4a(location no 18)
//code of d=0x4f(location no 19)

//code of L=0x1c(location no 20)
//code of H=0x5b(location no 21)
//code of -=0x40(location no 22)



unsigned int8 dispbuffer[12]={0,0,0,0,0,0,0,0,0,0};
unsigned int8 dummybuffer[12]={0,0,0,0,0,0,0,0,0,0};
unsigned char disptr=0;
unsigned int16 sec=500;
unsigned int16 hmsec=250;

unsigned int8 inputpresent=0;
unsigned int8 depress_timer_dn=200;
unsigned int8 timer_dn_ov=0;
unsigned int8 depress_timer_up=200;
unsigned int8 button_pressed=0;

unsigned int8 depress_timer_dn_mute=200;
unsigned int8 timer_dn_ov_mute=0;
unsigned int8 depress_timer_up_mute=200;

unsigned int8 depress_timer_dn_reset=200;
unsigned int8 timer_dn_ov_reset=0;
unsigned int8 depress_timer_up_reset=200;

unsigned int16 secd11=500;
unsigned int8 secd1=0;
unsigned int8 mind1=0;
unsigned int8 hourd1=0;

unsigned int8 muted=0;
unsigned int8 save_data_in_eeprom=0;

void loaddata(unsigned char );
void display_input(void);

void my_write_eeprom(int8 , int8 );
unsigned int8 my_read_eeprom(unsigned int8 addr);
void init_ext_eeprom();
void write_ext_eeprom(long int address, byte data);
unsigned int8 read_ext_eeprom(long int address);
int1 ext_eeprom_ready();

#INT_TIMER1
void wave_timer()
{
set_timer1(0xF830); // sets timer to interrupt in 2000us
display_input();

if(inputpresent==1)
{
secd11--;
if(secd11==0)
{
secd11=500;
secd1++;
if(secd1>59)
{
secd1=0;
save_data_in_eeprom=1;
mind1++;
if(mind1>59)
{
mind1=0;
hourd1++;
if(hourd1>39)
{
hourd1=0;
}
}
}
}
}
//***************************************** input scan *********************************

if(timer_dn_ov==0 && input(INP1)==0) // input for buttons pressed in field
{
depress_timer_dn--;
if(depress_timer_dn==0)
{
depress_timer_dn=200;
timer_dn_ov=1;
button_pressed=1;
inputpresent=1;

}
}

if(timer_dn_ov==1 && input(INP1)==1)
{
depress_timer_up--;
if(depress_timer_up==0)
{
depress_timer_up=200;
timer_dn_ov=0;
button_pressed=0;
inputpresent=0;
muted=0;
}
}
//****************
if(timer_dn_ov_mute==0 && input(INP2)==0) //input for mute button
{
depress_timer_dn_mute--;
if(depress_timer_dn_mute==0)
{
depress_timer_dn_mute=200;
timer_dn_ov_mute=1;
muted=1;
}
}

if(timer_dn_ov_mute==1 && input(INP2)==1)
{
depress_timer_up_mute--;
if(depress_timer_up_mute==0)
{
depress_timer_up_mute=200;
timer_dn_ov_mute=0;

}
}
//**********************
if(timer_dn_ov_reset==0 && input(INP3)==0) // input for reset button
{
depress_timer_dn_reset--;
if(depress_timer_dn_reset==0)
{
depress_timer_dn_reset=200;
timer_dn_ov_reset=1;

}
}

if(timer_dn_ov_reset==1 && input(INP3)==1)
{
depress_timer_up_reset--;
if(depress_timer_up_reset==0)
{
depress_timer_up_reset=200;
timer_dn_ov_reset=0;
secd11=500;
secd1=0;
mind1=0;
hourd1=0;
save_data_in_eeprom=1;
}
}
}
void main()
{
unsigned int8 temp1=0;

set_tris_b(0X0); //
set_tris_D(0x80); //
set_tris_C(0x0); //
set_tris_A(0xFF); //

output_c(0x00);
output_b(0x0);
output_d(0xc0);
output_a(0xff);

delay_ms(7000);

init_ext_eeprom();


setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);

setup_timer_2(T2_DISABLED,0,1);
//setup_comparator(NC_NC_NC_NC);
//setup_vref(False);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // setup interrupts
set_timer1(0xF830); // sets timer to interrupt in 2000us
setup_wdt(WDT_2304MS);
enable_interrupts(INT_TIMER1);
restart_wdt();
enable_interrupts(GLOBAL);
/*
temp1=READ_EEPROM(1);

if(temp1==1)
{
restart_wdt();
hourd1=READ_EEPROM(10);
restart_wdt();
mind1=READ_EEPROM(20);
restart_wdt();
secd1=READ_EEPROM(30);
}
*/
temp1=read_ext_eeprom(1);
if(temp1==1)
{
hourd1=read_ext_eeprom(10);
restart_wdt();
mind1=read_ext_eeprom(20);
restart_wdt();
secd1=read_ext_eeprom(30);
restart_wdt();
}
inputpresent=0;
restart_wdt();

do{ // super loop


dummybuffer[1]=mind1/10;
dummybuffer[0]=mind1%10;
restart_wdt();
dummybuffer[3]=hourd1/10;
dummybuffer[2]=hourd1%10;
restart_wdt();

// for check all digits start
/*
dummybuffer[3]=mind1/10;
dummybuffer[2]=mind1%10;
dummybuffer[1]=secd1/10;
dummybuffer[0]=secd1%10;
*/

//for checking all digits ends

if(inputpresent==1)
{
output_bit(RLY1,1); // revolving light

if(muted==0)
{
output_bit(RLY2,1); // buzzer
}
else
{
output_bit(RLY2,0); // buzzer
}

}
else
{
output_bit(RLY1,0); // revolving light

output_bit(RLY2,0); // buzzer

}

restart_wdt();
if(save_data_in_eeprom==1)
{
save_data_in_eeprom=0;
/*
WRITE_EEPROM(10,hourd1); //hour
restart_wdt();
WRITE_EEPROM(20,mind1); //min
restart_wdt();
WRITE_EEPROM(30,secd1); //sec
restart_wdt();
WRITE_EEPROM( 1, 1 );
restart_wdt();
*/

write_ext_eeprom(10,hourd1);
restart_wdt();
write_ext_eeprom(20,mind1);
restart_wdt();
write_ext_eeprom(30,secd1);
restart_wdt();
write_ext_eeprom(1,1);

}



restart_wdt();

} while (TRUE); // super loop
}


void display_input(void)
{
unsigned int8 t1;

output_bit(DIGIT1,0);
output_bit(DIGIT2,0);
output_bit(DIGIT3,0);
output_bit(DIGIT4,0);
output_bit(DIGIT5,0);

hmsec--;
if(hmsec==0)
{
hmsec=250;
}
if(disptr==4)
{
if(inputpresent==1)
{
if(hmsec<125>250)
{
output_bit(LED1,1);
if(disptr==4 && inputpresent==1)
{
output_bit(SEGD,OFF_SEG);
}

}
else
{
output_bit(LED1,0);
if(disptr==4)
{
output_bit(SEGD,ON_SEG);
}
}
if(sec==0)
{
sec=500;
}

t1=lookup[dispbuffer[disptr]];
if(disptr<4>4)
{
disptr=0;

dispbuffer[0]=dummybuffer[0]; //plan 1s
dispbuffer[1]=dummybuffer[1]; //plan 10's
dispbuffer[2]=dummybuffer[2]; //plan 100's
dispbuffer[3]=dummybuffer[3]; //1000's
dispbuffer[4]=dummybuffer[4]; //10000's



}




}


// display data
void loaddata(unsigned char ldata)
{

if((ldata & 0x01)==1)
{

output_bit(SEGA,ON_SEG);
}
else
{
output_bit(SEGA,OFF_SEG);
}

if((ldata & 0x02)==2)
{
output_bit(SEGB,ON_SEG);
}
else
{
output_bit(SEGB,OFF_SEG);
}

if((ldata & 0x04)==0x04)
{
output_bit(SEGC,ON_SEG);
}
else
{
output_bit(SEGC,OFF_SEG);
}

if((ldata & 0x08)==0x08)
{
output_bit(SEGD,ON_SEG);
}
else
{
output_bit(SEGD,OFF_SEG);
}

if((ldata & 0x10)==0x10)
{
output_bit(SEGE,ON_SEG);
}
else
{
output_bit(SEGE,OFF_SEG);
}
if((ldata & 0x20)==0x20)
{
output_bit(SEGF,ON_SEG);
}
else
{
output_bit(SEGF,OFF_SEG);
}

if((ldata & 0x40)==0x40)
{
output_bit(SEGG,ON_SEG);
}
else
{
output_bit(SEGG,OFF_SEG);
}

}
//------------------------------------------
void my_write_eeprom(int8 addr, int8 data)
{
int8 save_intcon;

eeadr = addr;
eedata = data;
WREN = 1;
save_intcon = int_con;
goie = 0;

EECON2 = 0x55;
EECON2 = 0xAA;
WR = 1;
restart_wdt();
while(WR)
{
restart_wdt();
}
WREN = 0;

int_con |= save_intcon;
goie = 1;
}



//--------------------------------------
unsigned int8 my_read_eeprom(unsigned int8 addr)
{
unsigned int8 retval;

eeadr = addr;
rd = 1;
retval = eedata;
restart_wdt();
return(retval);
}
//

void init_ext_eeprom() {
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}

int1 ext_eeprom_ready() {
int1 ack;
i2c_start(); // If the write command is acknowledged,
ack = i2c_write(0xa0); // then the device is ready.
i2c_stop();
return !ack;
}

void write_ext_eeprom(long int address, unsigned int8 data) {
while(!ext_eeprom_ready());
i2c_start();
i2c_write((0xa0|(BYTE)(address>>7))&0xfe);
i2c_write(address);
i2c_write(data);
i2c_stop();
}


unsigned int8 read_ext_eeprom(long int address) {
unsigned int8 data;

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);
}
mskala



Joined: 06 Mar 2007
Posts: 100
Location: Massachusetts, USA

View user's profile Send private message

PostPosted: Fri Nov 02, 2007 6:52 am     Reply with quote

I don't know how your circuit is hooked up, but because you don't use fast_io, what happens right at the beginning of main() is to set _all_ bits of ports A-D as outputs when you do output_a(), etc.
Ttelmah
Guest







PostPosted: Fri Nov 02, 2007 9:52 am     Reply with quote

Start, by moving the setup_wdt to the beginning of the program. On the 16 chips, the watchdog timer is running _as soon as the chip wakes up_, and until you call this, will be ticking at approximately 18mSec timeout.
Do a search here, about the problems of setting a timer 'to' a value. This will _not_ be even remotely accurate. Use timer2, which can be programmed to do this count itself use a 1:4 prescale, 99 counts, and a 1:5 interrupt postscale.
Learn how to use the 'code' buttons to post code. It makes it much easier to read...
I'd suggest taking the update interval for this down though. Your 'display_input' routine, takes a _lot_ of time. Array accesses, are quite slow. Think in terms of something like 12 instructions for each one. You have eleven array accesses inside the interrupt. The rest of the interrupt is similarly long. I'd actually suspect that what is actually happening, is that the total time in this routine, including the compiler handler code, is exceeding the 2000 instruction times available between interrupts, so that as soon as you enable this interrupt, the 'main' code stops running, and hence the watchdog.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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