Sida 1 av 2

Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 21:22:42
av slatte
Har ett litet problem med min kod nedan har minskat ner programmet så det enbart består av 4 "funktioner" main, interrupt,BinBcd, och init.
programmeringsspråk : Hi-tech C
program: Mplab
PIC: pic16f84a

Det enda som programmet ska utföra är att köra BinBcd funktion hela tiden och skicka ut resultatet på PORTB allt annat i programmet har jag tagit bort för att felsöka. Problemet är den att om jag simulerar programmet med Mpsim så fastnar programmet i BinBcd funktionen, men fattar inte varför bah! Men om jag nollar T0IE och simmulerar om programmet fungerar programmet perfekt, vilket jag tycker verkar konstigt. Så det borde ha något att göra med Interruptet att göra, men det enda som just nu görs i interruptet är ju att nolla interrupt flaggan.

Några tips eller mer info som ni kan behöva :?
Jag fattar inte vad felet kan vara!

/Slatte

Kod: Markera allt

#include <pic.h>
#include <sys.h>

//Config bitar
__CONFIG(XT & WDTDIS & PWRTDIS);

#define	PROGTID	50  

// *** Port A ***
#define	downBtn	RA0		
#define	upBtn	   RA1		
#define	RA2		RA2		
#define	RA3		RA3
#define			RA4

//Globala Variabler
char  Temp  =  1;
char  PWM   =  50;

//*********** initiera PIC ***********
void init(void)			// Initiera 16F84A
{

//*** Timer 0 			
	PSA = 0;			   
	PS0 = 0;			   
	PS1 = 0;		
	PS2 = 0;	
	T0CS = 0;			

//*** Portar
	PORTA = 0;
	PORTB = 0;
	RBPU = 1;			        
	TRISA = 0b00000011;        	// 
	TRISB = 0b00000000;           // Alla ut

//*** Interrupt
	TMR0 = 240;			
	T0IF = 0;         // nollar flaggan
	T0IE = 1;			// TMR0 genererar interrupt
	GIE = 1;			   // Global Interrupt enable	
	
}

//*********Binärt tal till BCD kod **********
char binBCD(char binartal){
	char tiotal, ental;
	tiotal = binartal / 10;
	ental = binartal % 10;
 	tiotal = tiotal << 4;
	
	return tiotal + ental;

}
void interrupt skriv_ut(void){
   T0IF = 0;
}

void main (){
	init();	
	while(1){   	
   	PORTB = binBCD(PWM);
        idle();  //En helt tom funktion
	}
}

Re: Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 21:34:24
av Icecap
Vad tusan gör "return" i interruptrutinen (ISR'n)??? Bort med den direkt!
En void funktion kan ju inte returnera något värde och en interrupt kan definitivt aldrig göra det!

Sedan börjar du med att nolla WDT och då du i CONFIG disabler den ska du inte pilla med den alls i programmet!

Re: Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 21:45:43
av slatte
Fixat :)
Men fortfarande samma bekymmer tyvärr :?

Re: Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 21:47:20
av sodjan
När fungerar det och vad är då skillnaden ?

Re: Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 21:54:36
av slatte
Den fungerar om jag sätter

Kod: Markera allt

   T0IE = 0;
Om jag inte gör detta alltså T0If = 1, så fastnar simuleringen i BinBcd funktionen vilken i vanliga fall bara ska ta ca 1,5 ms men nu kan jag simulera i flera sekunder utan att den kommer igenom funktionen.

Kanske är dåligt förklarat men hoppas ni förstår

Re: Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 21:58:38
av Icecap
Om du disabler interrupten hänger den inte fast i BCD-koden?

Men hallå, då är felet i interruptkoden! Har du en context-switching i ISR'n? Jag är osäker på om HiTec C gör detta automatisk och att den är tillräcklig.

Re: Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 21:59:57
av sodjan
Hur ser "skriv_ut" ut i assembler listan ?

Re: Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 22:02:47
av slatte
Icecap skrev:Om du disabler interrupten hänger den inte fast i BCD-koden?

Men hallå, då är felet i interruptkoden! Har du en context-switching i ISR'n? Jag är osäker på om HiTec C gör detta automatisk och att den är tillräcklig.
Edit: du menar sparar undan alla variabler Wspace mm. Detta tror jag att Hi-tech C ska lösa automatiskt :?
Har aldrig behövt pilla på detta innan


Du har förstått precis rätt men jag har ingen aning om vad "context-switching" är för något men ska genast googla.
Ska kolla upp din fråga Sodjan :)

Kod: Markera allt

1AC    1003     BCF 0x3, 0
   1AD    1803     BTFSC 0x3, 0
   1AE    29B0     GOTO 0x1b0
   1AF    29B2     GOTO 0x1b2
   1B0    150B     BSF 0xb, 0x2
   1B1    29B3     GOTO 0x1b3
   1B2    110B     BCF 0xb, 0x2
1B3    1283     BCF 0x3, 0x5

Kod: Markera allt

MOVF 0x4e, W
MOVWF 0x7e
MOVF 0x4d, W
MOVWF 0xa
MOVF 0x4c, W
MOVWF 0x4
MOVF 0x4b, W
MOVWF 0x3
SWAPF 0x7f, F
SWAPF 0x7f, W
RETFIE

Detta var vad som jag hittade i Diassembly listing
EDIT: Kollade vad som hände genom att kolla i Program minnet klistrade in resterande.

Re: Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 22:17:48
av sodjan
Det borde finnas en RETFIE i listningen någonstans,
helst i slutet av interrupt rutinen. Men för övrigt,
verkar det som du visade rimligt ?

Re: Problem med att simulera väldigt simpel kod

Postat: 29 november 2009, 22:37:02
av slatte
Det verkar som att den fastnar i denna koden i en C fil som heter awdiv.c "division"
Jag har markerat den raden den fastnar vid

Kod: Markera allt

// integer signed division

signed int
__awdiv(signed int dividend, signed int divisor)
{
	signed int	quotient;
	unsigned char	counter, sign;

	sign = 0;
	if(divisor < 0) {
		divisor = -divisor;
		sign = 1;
	}
	if(dividend < 0) {
		dividend = -dividend;
		sign ^= 1;
	}
	quotient = 0;
	if(divisor != 0) {
		counter = 1;
		while((divisor & 0x8000U) == 0) {
			divisor <<= 1;
			counter++;
		}
		do {
			quotient <<= 1;
			if((unsigned int)divisor <= (unsigned int)dividend) {
				dividend -= divisor;
				quotient |= 1;
			}
			*(unsigned int *)&divisor >>= 1; // HÄR STANNAR DEN OCH TUGGAR
		} while(--counter != 0);
	}
	if(sign)
		quotient = -quotient;
	return quotient;
}


Re: Problem med att simulera väldigt simpel kod

Postat: 30 november 2009, 07:58:36
av Icecap
Det tror jag faktisk inte på!
Den rad utlöser ett antal fasta steg som den inte kan "fastna" på medan den kan "hänga" i evighet i loopen (do {} while();)

Jag skulle alltså tro att det händer något så att "counter" inte blir 0.

Re: Problem med att simulera väldigt simpel kod

Postat: 30 november 2009, 19:08:19
av slatte
Jag tror knappt på detta heller XD

Men tyvärr så fastnar den just där av någon anledning.
Jag har stegat igenom denna sekvens i Program minnet som ser ut enligt nedan:

Kod: Markera allt

*(unsigned int *)&divisor >>= 1;
   087    1283     BCF 0x3, 0x5
   088    3001     MOVLW 0x1
   089    1003     BCF 0x3, 0
   08A    0CC5     RRF 0x45, F
   08B    0CC4     RRF 0x44, F
   08C    3EFF     ADDLW 0xff
   08D    1D03     BTFSS 0x3, 0x2
   08E    2889     GOTO 0x89
En fråga bara efter att ha gått igenom "context-switching" alltså spara Wreg,flaggor mm innan den går in i interrupt. Om jag kollar i DATABLADET för PIC 16f84A så står adresserna inom 50h-7Fh (Unimplemented read as "0") Då borde ju inte adressen 7Fh inte användas eller? För det är just den adressen som Wreg sparas i vid interrupt :?
Kod nedan:

Kod: Markera allt

MOVWF 0x7f
MOVF 0x3, W
BCF 0x3, 0x5
MOVWF 0x4b
MOVF 0x4, W
MOVWF 0x4c
MOVF 0xa, W
MOVWF 0x4d
MOVF 0x7e, W
MOVWF 0x4e
GOTO 0x1ac

Re: Problem med att simulera väldigt simpel kod

Postat: 30 november 2009, 23:12:16
av sodjan
Jo, det där med h'7F' verkar ju lite märkligt...
Kanske dags att fråga det nu, varför "slåss" du
med en gammal F84A ? Eftersom allt inte riktigt
går som på räls i alla fall, varför inte byta till
något modernare och enklare att använda ?

Re: Problem med att simulera väldigt simpel kod

Postat: 30 november 2009, 23:22:33
av slatte
Anledningen är den att det är en labb kvar sedan skoltiden.
Jag tror att jag får ta ett snack med handledaren och byta till en 16f648 eller nått :)

Re: Problem med att simulera väldigt simpel kod

Postat: 30 november 2009, 23:27:59
av sodjan
Jahaja, på det viset. Då kanske din handledare skulle ta
och hjälpa till med själva uppgiften också...