|
|
View previous topic :: View next topic |
Author |
Message |
zafarkhan
Joined: 31 Oct 2007 Posts: 6
|
microcontroller reset due to watchdog when we read eeprom |
Posted: Wed Oct 31, 2007 1:52 am |
|
|
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
|
|
Posted: Wed Oct 31, 2007 3:39 am |
|
|
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
|
|
Posted: Wed Oct 31, 2007 4:23 am |
|
|
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
|
initial code due to which controller reset |
Posted: Wed Oct 31, 2007 6:36 am |
|
|
#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
|
|
Posted: Wed Oct 31, 2007 6:49 am |
|
|
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
|
circuit restart due to watch dog |
Posted: Thu Nov 01, 2007 12:02 am |
|
|
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
|
|
Posted: Thu Nov 01, 2007 12:58 am |
|
|
Which chip are you using?
Which compiler version? |
|
|
zafarkhan
Joined: 31 Oct 2007 Posts: 6
|
microcontroller reset due to watch dog |
Posted: Thu Nov 01, 2007 6:00 am |
|
|
i am using pic16f877a
and compiler version is 3.2 |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Nov 01, 2007 6:12 am |
|
|
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
|
|
Posted: Thu Nov 01, 2007 6:25 am |
|
|
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
|
thanks for the comments and here is the complete program |
Posted: Fri Nov 02, 2007 2:21 am |
|
|
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
|
|
Posted: Fri Nov 02, 2007 6:52 am |
|
|
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
|
|
Posted: Fri Nov 02, 2007 9:52 am |
|
|
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 |
|
|
|
|
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
|