Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Unknown PIC resetting problem.

Status
Not open for further replies.

PICMICRO

New Member
I was trying to program a simple 7-seg display multiplexing program.
As, a start, I am simply displaying the value stored in 4 variables c0 -- c4 at 4 7 seg display.
Here is my code.
Code:
#include<htc.h>
#define _XTAL_FREQ 20000000

#define D3 RC7
#define D3_tris TRISC7
#define D1 RC6
#define D1_tris TRISC6
#define D0 RC5
#define D0_tris	TRISC5
#define D2 RC4
#define D2_tris TRISC4
#define CCP_tris TRISC2
#define Display PORTB
#define Display_tris TRISB


const char segdata[16] = {
// 7-bits for displaying numeral 0,1,2,3...
// most be negated when used for common anode

0b00111111, // 0
0b00000110, // 1
0b01011011,// 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101,// 6
0b00000111, // 7
0b01111111,// 8
0b01101111,// 9
0b01110111,// A
0b01111100,// B
0b00111001,// C
0b01011110,// D
0b01111001,// E
0b01110001,// F
};
// voltatile necessary for all variables used by interrupt
volatile char c0;  // var For first  7-seg display
volatile char c1;  // var For second 7-seg display
volatile char c2;  // var For third 7-seg display
volatile char c3;  // var For fourth 7-seg display

void interrupt isr(void){   // timer0 interrupt 
	static unsigned char turnof = 0;  // static necessary to retain data between sucessive call to function.
                                     // initialization is done only once 
									// turnof  is multiplexing variable to cycle through the 4 displays
	switch(turnof){
			case 0:  // Turn of Display 1
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			[COLOR="red"]Display = ~segdata[c0];[/COLOR]
			D0 = 0; // select Display1
			break;
			case 1:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			[COLOR="red"]Display = ~segdata[c1];[/COLOR]
			D1 = 0; // select Display2
			break;
			case 2:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			[COLOR="red"]Display = ~segdata[c2];[/COLOR]
			D2 = 0; // select Display3
			break;
			case 3:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			[COLOR="red"]Display = ~segdata[c3];[/COLOR]
			D3 = 0; // select Display4
	}
	turnof++;
	if(turnof>3) turnof = 0;
	T0IF = 0;  			
}


void main(){
Display_tris = 0; // all PortB output
D0_tris = 0;
D1_tris = 0;
D2_tris = 0;
D3_tris = 0;
D2=1;
D1=1;
D3=1;
D0 = 0; // switch on first 7-seg display
char i,j;
// animate 1-F at the begining
for(i=0;i<16;i++){
Display = ~segdata[i];
 for(j=0;j<=20;j++) __delay_ms(10);
}
//
// set various values to display variables
c0 = 2;
c1 = 3;
c2 = 4;
c3 = 5;
//
    OPTION = 0b11010000 ;// Disable internal weak pullup,,internal clock source for T0
                             // ,, assign prescaler to TMR0,prescaler 100
	GIE = 1;
	TMR0IE = 1;// enable timer 0 interrupt

 	D0 = 1; // switch off the display
	
	while(1); //Trap
 

}
It don't work. The PIC resets as soon as it executes the red marked statement.
So, I have only a continuous animation running, which is not what I expected.

If I replace the red marked statements by this type
Code:
...
Display = ~segdata[2]
...
...
Display = ~segdata[5]
......
Display = ~segdata[0xA]
......
Display = ~segdata[0xD]
...
It works then.
So, there seems to be problem with that volatile variable, which I can't track.
Any help please?
 
hi, 3v0.
commenting out GIE = 1, helps prevent resetting. But of-course, I don't get what I need.
And yeah, WDT is disabled. Thanks for reminding though, its often forgotten about.
Pretty amazing problem I am facing.
Seems like I have problem with the compiler.
 
Try busting up the lines with the problem. It looks bulky but the compiler should generate about the same amount of code, and maybe it will get it right. If not it might help you see where the problem is by looking at the ASM generated for the line (now operation) that causes the reset.

Code:
...
unsigned char col;
	switch(turnof){
			case 0:  // Turn of Display 1
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
                        col=c0;
			Display = segdata[col];
                        Display = ~Display;
			D0 = 0; // select Display1
			break;
			case 1:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			col=c1;
                        Display = segdata[col];
                        Display = ~Display;
			D1 = 0; // select Display2
			break;
			case 2:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			col=c2;
                        Display = segdata[col];
                        Display = ~Display;
			D2 = 0; // select Display3
			break;
			case 3:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			col=c3;
                        Display = segdata[col];
                        Display = ~Display;
			D3 = 0; // select Display4
	}
 
Last edited:
I was trying to program a simple 7-seg display multiplexing program.
As, a start, I am simply displaying the value stored in 4 variables c0 -- c4 at 4 7 seg display.
Here is my code.
Code:
#include<htc.h>
#define _XTAL_FREQ 20000000

#define D3 RC7
#define D3_tris TRISC7
#define D1 RC6
#define D1_tris TRISC6
#define D0 RC5
#define D0_tris	TRISC5
#define D2 RC4
#define D2_tris TRISC4
#define CCP_tris TRISC2
#define Display PORTB
#define Display_tris TRISB


const char segdata[16] = {
// 7-bits for displaying numeral 0,1,2,3...
// most be negated when used for common anode

0b00111111, // 0
0b00000110, // 1
0b01011011,// 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101,// 6
0b00000111, // 7
0b01111111,// 8
0b01101111,// 9
0b01110111,// A
0b01111100,// B
0b00111001,// C
0b01011110,// D
0b01111001,// E
0b01110001,// F
};
// voltatile necessary for all variables used by interrupt
volatile char c0;  // var For first  7-seg display
volatile char c1;  // var For second 7-seg display
volatile char c2;  // var For third 7-seg display
volatile char c3;  // var For fourth 7-seg display

void interrupt isr(void){   // timer0 interrupt 
	static unsigned char turnof = 0;  // static necessary to retain data between sucessive call to function.
                                     // initialization is done only once 
									// turnof  is multiplexing variable to cycle through the 4 displays
	switch(turnof){
			case 0:  // Turn of Display 1
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			[COLOR="red"]Display = ~segdata[c0];[/COLOR]
			D0 = 0; // select Display1
			break;
			case 1:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			[COLOR="red"]Display = ~segdata[c1];[/COLOR]
			D1 = 0; // select Display2
			break;
			case 2:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			[COLOR="red"]Display = ~segdata[c2];[/COLOR]
			D2 = 0; // select Display3
			break;
			case 3:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			[COLOR="red"]Display = ~segdata[c3];[/COLOR]
			D3 = 0; // select Display4
	}
	turnof++;
	if(turnof>3) turnof = 0;
	T0IF = 0;  			
}


void main(){
Display_tris = 0; // all PortB output
D0_tris = 0;
D1_tris = 0;
D2_tris = 0;
D3_tris = 0;
D2=1;
D1=1;
D3=1;
D0 = 0; // switch on first 7-seg display
char i,j;
// animate 1-F at the begining
for(i=0;i<16;i++){
Display = ~segdata[i];
 for(j=0;j<=20;j++) __delay_ms(10);
}
//
// set various values to display variables
c0 = 2;
c1 = 3;
c2 = 4;
c3 = 5;
//
    OPTION = 0b11010000 ;// Disable internal weak pullup,,internal clock source for T0
                             // ,, assign prescaler to TMR0,prescaler 100
	GIE = 1;
	TMR0IE = 1;// enable timer 0 interrupt

 	D0 = 1; // switch off the display
	
	while(1); //Trap
 

}
It don't work. The PIC resets as soon as it executes the red marked statement.
So, I have only a continuous animation running, which is not what I expected.

If I replace the red marked statements by this type
Code:
...
Display = ~segdata[2]
...
...
Display = ~segdata[5]
......
Display = ~segdata[0xA]
......
Display = ~segdata[0xD]
...
It works then.
So, there seems to be problem with that volatile variable, which I can't track.
Any help please?

I think your problem might be related the typing of segdata, the const keyword makes it data that uses rom/flash, not ram for storage. When you use fixed indexes on segdata the compiler can map the address directly in a fixed manner, when a variable is used as the index to segdata the compiler uses a index addressing method.

quick test.
Create a temp variable in the isr to hold the results of segdata[cx], then do the negation and assignment to Display with that instead of directly.

Looks like 3vo is pointing you in the same direction above.
 
Last edited:
Try busting up the lines with the problem. It looks bulky but the compiler should generate about the same amount of code, and maybe it will get it right. If not it might help you see where the problem is by looking at the ASM generated for the line (now operation) that causes the reset.

Wow! that works.
I tried reducing a bit and it worked.
Code:
... // slightly reduced
unsigned char col;
	switch(turnof){
			case 0:  // Turn of Display 1
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
                        col=c0;
			Display = ~segdata[col];
                      	D0 = 0; // select Display1
			break;
			case 1:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			col=c1;
                        Display = ~segdata[col];
                        D1 = 0; // select Display2
			break;
			case 2:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			col=c2;
                        Display = ~segdata[col];
                      	D2 = 0; // select Display3
			break;
			case 3:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			col=c3;
                        Display = ~segdata[col];
                        D3 = 0; // select Display4
	}
So, what do we learn?
 
I suspect the problem is to do with context saving. As you are reading Flash in both the main loop and the interrupt, the registers to read Flash will get corrupted. Try saving and restoring the relevant registers (See 7.3 of data sheet).

Mike.
 
Wow! that works.
I tried reducing a bit and it worked.
Code:
... // slightly reduced
unsigned char col;
	switch(turnof){
			case 0:  // Turn of Display 1
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
                        col=c0;
			Display = ~segdata[col];
                      	D0 = 0; // select Display1
			break;
			case 1:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			col=c1;
                        Display = ~segdata[col];
                        D1 = 0; // select Display2
			break;
			case 2:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			col=c2;
                        Display = ~segdata[col];
                      	D2 = 0; // select Display3
			break;
			case 3:
			D0 = 1; //
			D1 = 1; //  Deselct all display
			D2 = 1; //
			D3 = 1;
			col=c3;
                        Display = ~segdata[col];
                        D3 = 0; // select Display4
	}
So, what do we learn?

'col' in your modified code is allocated in the stack bank of memory instead of the general memory space of the cx variables. It seems that the 'segdata' indexing methods are related to it somehow. (stack memory pointer coded (works) vs banked ram memory pointer coded (fails))
Bug in the compiler, maybe or just misconfiguration in the defaults affecting context switching or memory access.
Bug in the chip, not really but I really would use a PIC18 series chip (shadow registers for context saving, optimized for C, etc ...) if C was going to be the language if I had a choice.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top