Får inte till Timer1, behöver hjälp!

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
christoferivarsson
Inlägg: 67
Blev medlem: 10 juli 2008, 15:47:06
Ort: stockholm
Kontakt:

Får inte till Timer1, behöver hjälp!

Inlägg av christoferivarsson »

I somras skrev jag ett inlägg angående där jag besrkev mitt projekt "bränslemätare till båt". Nu är koden klar samt hårdvaran kopplad men jag får inte TImer1 att funka.

Timer0 används för delay-rutinen och Timer1 för att räkna alla inkommande pulser från flödesgivaren som är av halltyp, 5V, 0.28mA.

När jag simulerar koden i MPLAB så funkar registren som de skall, jag stimulerar RB6 (använder en pic16f628) och värdete lägger sig i TMR1L. Jag räknar antalet pulser under en sekund och eftersom max antal pulser/sek är under 200 så läser jag bara de låga bitarna av timer1 dvs TMR1L.

När jag skriver in ett värde för TMR1L i koden så representeras det på displayen så allting mellan TMR1L-registret och LCD-displayen är i sin ordning. MEN, TMRL stimuleras inte av yttre pulser och jag FATTAR INTE carför. Har lagt 30 timmar på felsök vid det här laget.

Som stimulans har jag en tryckknapp mellan RB6 och jord eftersom jag kör pull-up.

Tacksam för alla ideéer!!!! :)

Kod: Markera allt

      ________  ________
      |        \/        |       R/!WR = 0
  D6--|RA2   16F628   RA1|--D5   (only write, wait while busy)
  D7--|RA3            RA0|--D4
      |RA4-od    RA7/OSC1|
      |RA5/MCLR  RA6/OSC2|
 GND--|Vss            Vdd|-- +5V
      |RB0/INT  (RB7)/PGD|
      |RB1/Rx   (RB6)/PGC|--Hallgivare
      |RB2/Tx         RB5|--RS
  EN--|RB3/CCP  (RB4)/PGM|
      |__________________|

*/


//#include "16F628.H"
#pragma config |= 0x3fb0   // use internal 4MHz oscillator

/* I/O-pin definitions                               */ 
/* change if you need a pin for a different purpose  */
#pragma bit RS  @ PORTB.5
#pragma bit EN  @ PORTB.3

#pragma bit D7  @ PORTA.3
#pragma bit D6  @ PORTA.2
#pragma bit D5  @ PORTA.1
#pragma bit D4  @ PORTA.0


#include "delays.c"

void delay( char ); 							// ms delay function from file delays.c
void lcd_init( void );
void lcd_putchar( char );
char text1( char );
char text2( char );

char division ( char, char );					//definition of new counter function for the incoming pulses on RB6----------------------------

    

void	main( void)
{
    CM0=1; CM1=1; CM2=1; 						// no comparators on

    /* I/O-pin direction in/out definitions, change if needed  */
    TRISB  = 0b11.0.1.0.0.11;  					// output to RS and EN ( and Tx ), RB6 input
    TRISA  = 0b1111.0000;      					// output to D4-D7
    T1CON = 0b00000111;    						//timer1 on, external pulses on T1CKI, no sync, no prescaler
    OPTION.7 =0;								// pull-up resistance on PORTB
    PIE1.0=0;									//interrupt disabled on Timer1
	char konstant;								//define variable k as the normalizing value for 1 litre/sec--------------------------------------
    char kvot;									//deklarera ny variabel för kvoten mellan antalet pulser och en kosntant för att få i liter per timma-----------------------
    unsigned long p;							//declare variabel p to which T1MRL is later copied
    char z;										//variabel för text2
	konstant=1;

    lcd_init();
   
while(1)
{    
	
    TMR1L=0;									// reset timer
	delay10 (100);								// delay  1 sec
    
	//TMR1L=20;									//endast för att testköra programmet
												
	if (TMR1L>0)								//flytta TMR1L till p om större än 0 annars p=1. Detta för att tecknet på displayen blir fel vid en kvot inehållande 0
		p=TMR1L;
	else
		p=1;
												
	//p=p<<2;									//vänsterskift för att minska effekten av modulot som blir vid divisionen
    

	kvot = division (p,konstant);				//anropa funktion som dividerar pulser med konstant-----------------------------------
 	/kvot=kvot>>2	;								//högerskift för att minska värdet till samma decimal som innan vänsterskift
    

/* Skriv ut till LCD*/
   	RS = 1;  									// LCD in character-mode							 				
  
	if (kvot<10) 	lcd_putchar('0'+kvot);		//testa om kvot mindre än 10, isåfall skriv till skärm från position 0 ASCII plus värdet av kvot
 	if (kvot>=10) 								//om kvot större än 10 dela upp 10 tal och ental, skicka till LCD
	{
		char ch_1;								//deklarera nya variabler ch_1 = tecken nr 1, samt ch_2 =tecken nr 2
		char ch_2;

		ch_1= kvot/10;							//dividera kvot med tio för att få ut värdet på första siffran - ex. 23/10=2 modulo 3
		lcd_putchar ('0'+ ch_1);				//visa värdet på första teckenplaceringen
		ch_2=kvot%10;							//plocka fram modulot och lägg i ch_2 - se ex. ovan 
		lcd_putchar ('0'+ ch_2);				//visa ch_2 i displayen på plats två
	}
	
			
												// reposition to "line 2" (the next 8 chars)
   	RS = 0;  									// LCD in command-mode
    lcd_putchar( 0b11000000 );
  
    RS = 1;  									// LCD in character-mode
    											// display the 8 char text2() sentence
    for(z=0; z<8; z++) lcd_putchar(text2(z)); 
 
   

}
}

/* ****************** FUNCTIONS ****************************** */



char text2( char x)   							// this is the way to store a sentence
{
   skip(x); /* internal function CC5x.  */
   #pragma return[] = "liter/h "    			// 8 chars max! Måste vara 8teckenavstånd mellan "" tecknen
}



void lcd_init( void ) 								// must be run once before using the display
{
  delay(40);  									// give LCD time to settle
  RS = 0;     // LCD in command-mode
  lcd_putchar(0b0011.0011); /* LCD starts in 8 bit mode          */
  lcd_putchar(0b0011.0010); /* change to 4 bit mode              */
  lcd_putchar(0b00101000);  /* two line (8+8 chars in the row)   */ 
  lcd_putchar(0b00001100);  /* display on, cursor off, blink off */
  lcd_putchar(0b00000001);  /* display clear                     */
  lcd_putchar(0b00000110);  /* increment mode, shift off         */
  RS = 1;    										// LCD in character-mode
             										// initialization is done!
}


void lcd_putchar( char data )
{
  // must set LCD-mode before calling this function!
  // RS = 1 LCD in character-mode
  // RS = 0 LCD in command-mode
  // upper Nybble
  D7 = data.7;
  D6 = data.6;
  D5 = data.5;
  D4 = data.4;
  EN = 0;
  nop();
  EN = 1;
  delay(5);
  // lower Nybble
  D7 = data.3;
  D6 = data.2;
  D5 = data.1;
  D4 = data.0;
  EN = 0;
  nop();
  EN = 1;
  delay(5);
}

char division( char x, char y)  		/* function header            */
  {                          		/* start of function body     */
     char f;
     f = x / y;
     return f;   
  }                          		/* end of function body       */

--------------------
Petade in code-taggar
//Jimmy
--------------------
christoferivarsson
Inlägg: 67
Blev medlem: 10 juli 2008, 15:47:06
Ort: stockholm
Kontakt:

obs

Inlägg av christoferivarsson »

skriven i C knudsen, Cc5x ifall ni undrar kring punkter mellan bitarna...
bearing
Inlägg: 11677
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Hur är knappen kopplad?
christoferivarsson
Inlägg: 67
Blev medlem: 10 juli 2008, 15:47:06
Ort: stockholm
Kontakt:

Inlägg av christoferivarsson »

Som jag skrev, från RB6 till jord via en tryckknapp. Inga motstånd eller dylikt. Jag har även försökt med lösa tåtar, samt med logic tool simulator.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Snygga till koden (med code-taggarna) så att det går att läsa...
bearing
Inlägg: 11677
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Ah. Ursäkta.

Om det funkar i simulering är det ju med väldigt stor sannolikhet så att knappen är felkopplad eller att något yttre påverkar. RB6 är en programmeringspinne. Påverkar programmeraren beteendet?
Vad visar en multimeter kopplad till pinnen?

Vad händer om du byter ut main-loopen till:

Kod: Markera allt

while(1)
{
    RB2=0;
    if (RB6)
        RB2=1;
}

Med t.ex. en lysdiod kopplad till RB2?
christoferivarsson
Inlägg: 67
Blev medlem: 10 juli 2008, 15:47:06
Ort: stockholm
Kontakt:

Tack

Inlägg av christoferivarsson »

Skall testa och se om det funkar.
Niklas-k
Inlägg: 354
Blev medlem: 10 mars 2004, 15:59:21
Ort: Katrineholm

Inlägg av Niklas-k »

Är din knapp studsfri? Om inte så blir det litte lotto på nuffrerna du får ut.
Plocka också bort programmeringspinnarna om du har det från PORTB och prova.
christoferivarsson
Inlägg: 67
Blev medlem: 10 juli 2008, 15:47:06
Ort: stockholm
Kontakt:

Inlägg av christoferivarsson »

Jag testade igår att tända en lysdiod på RB3 if(RB6) och det funkade bra med pull-up aktiverat. Alltså funkar porten. Varför vill inte timern räkna upp?!?

Hur klistrar jag in kode utan att radbrytningar mm ändras?
Norpan
Inlägg: 2229
Blev medlem: 12 april 2008, 18:20:27
Ort: Småland

Inlägg av Norpan »

Kod: Markera allt

          Klistra in koden, markera den, och tryck på code knappen
christoferivarsson
Inlägg: 67
Blev medlem: 10 juli 2008, 15:47:06
Ort: stockholm
Kontakt:

Inlägg av christoferivarsson »

Kod: Markera allt

       ________  ________
      |        \/        |       R/!WR = 0
  D6--|RA2   16F628   RA1|--D5   (only write, wait while busy)
  D7--|RA3            RA0|--D4
      |RA4-od    RA7/OSC1|
      |RA5/MCLR  RA6/OSC2|
 GND--|Vss            Vdd|-- +5V
      |RB0/INT  (RB7)/PGD|
      |RB1/Rx   (RB6)/PGC|--Hallgivare
      |RB2/Tx         RB5|--RS
  EN--|RB3/CCP  (RB4)/PGM|
      |__________________|

*/


#include "16F628.H"		// måste avmarkeras annars dubbeldefinition
#pragma config |= 0x3fb0   // use internal 4MHz oscillator

/* I/O-pin definitions                               */ 
/* change if you need a pin for a different purpose  */
#pragma bit RS  @ PORTB.5
#pragma bit EN  @ PORTB.3

#pragma bit D7  @ PORTA.3
#pragma bit D6  @ PORTA.2
#pragma bit D5  @ PORTA.1
#pragma bit D4  @ PORTA.0

#include "delays.c"

void delay( char ); 							// ms delay function from file delays.c
void lcd_init( void );
void lcd_putchar( char );
char text2 ( char );							//variabel för text2
char division ( char, char );				//definition of new counter function for the incoming pulses on RB6   

void	main( void)
{
    CM0=1; CM1=1; CM2=1; 						// no comparators on

    /* I/O-pin direction in/out definitions, change if needed  */
    TRISB  = 0b1101.0011;  						// output to RS and EN ( and Tx ), RB6 input
    TRISA  = 0b1111.0000;      					// output to D4-D7
    T1CON  = 0b0000.0111;   					//timer1 on, external pulses on T1CKI, no sync, no prescaler
    OPTION.7 = 0;								// pull-up resistance on PORTB
    PIE1.0 = 0;									//interrupt disabled on Timer1
	
	char konstant;								//define variable k as the normalizing value for 1 litre/sec
    char kvot;									//deklarera ny variabel för kvoten mellan antalet pulser och en kosntant för att få i liter per timma-----------------------
    unsigned long p;							//declare variabel p to which T1MRL is later copied
    char z;										
	
	


	konstant=1;

    lcd_init();
   
while(1)
{    
	
    TMR1L=0;									// reset timer
	delay10 (100);								// delay  1 sec
    
	//TMR1L=20;									//endast för att testköra programmet
												
	if (TMR1L>0)								//flytta TMR1L till p om större än 0 annars p=1. Detta för att tecknet på displayen blir fel vid en kvot inehållande 0
		p=TMR1L;
	else
		p=1;
												
	//p=p<<2;									//vänsterskift för att minska effekten av modulot som blir vid divisionen
    

	kvot = division (p,konstant);				//anropa funktion som dividerar pulser med konstant-----------------------------------
 	//kvot=kvot>>2	;								//högerskift för att minska värdet till samma decimal som innan vänsterskift
    

/* Skriv ut till LCD*/
   	RS = 1;  									// LCD in character-mode							 				
  
	if (kvot<10) 	lcd_putchar('0'+kvot);		//testa om kvot mindre än 10, isåfall skriv till skärm från position 0 ASCII plus värdet av kvot
 	if (kvot>=10) 								//om kvot större än 10 dela upp 10 tal och ental, skicka till LCD
	{
		char ch_1;								//deklarera nya variabler ch_1 = tecken nr 1, samt ch_2 =tecken nr 2
		char ch_2;

		ch_1= kvot/10;							//dividera kvot med tio för att få ut värdet på första siffran - ex. 23/10=2 modulo 3
		lcd_putchar ('0'+ ch_1);				//visa värdet på första teckenplaceringen
		ch_2=kvot%10;							//plocka fram modulot och lägg i ch_2 - se ex. ovan 
		lcd_putchar ('0'+ ch_2);				//visa ch_2 i displayen på plats två
	}
	
			
												// reposition to "line 2" (the next 8 chars)
   	RS = 0;  									// LCD in command-mode
    lcd_putchar( 0b11000000 );
  
    RS = 1;  									// LCD in character-mode
    											// display the 8 char text2() sentence
    for(z=0; z<8; z++) lcd_putchar(text2(z)); 
 
   

}
}

/* ****************** FUNCTIONS ****************************** */



char text2( char x)   							// this is the way to store a sentence
{
   skip(x); /* internal function CC5x.  */
   #pragma return[] = "liter/h "    			// 8 chars max! Måste vara 8teckenavstånd mellan "" tecknen
}



void lcd_init( void ) 								// must be run once before using the display
{
  delay(40);  									// give LCD time to settle
  RS = 0;     // LCD in command-mode
  lcd_putchar(0b0011.0011); /* LCD starts in 8 bit mode          */
  lcd_putchar(0b0011.0010); /* change to 4 bit mode              */
  lcd_putchar(0b00101000);  /* two line (8+8 chars in the row)   */ 
  lcd_putchar(0b00001100);  /* display on, cursor off, blink off */
  lcd_putchar(0b00000001);  /* display clear                     */
  lcd_putchar(0b00000110);  /* increment mode, shift off         */
  RS = 1;    										// LCD in character-mode
             										// initialization is done!
}


void lcd_putchar( char data )
{
  // must set LCD-mode before calling this function!
  // RS = 1 LCD in character-mode
  // RS = 0 LCD in command-mode
  // upper Nybble
  D7 = data.7;
  D6 = data.6;
  D5 = data.5;
  D4 = data.4;
  EN = 0;
  nop();
  EN = 1;
  delay(5);
  // lower Nybble
  D7 = data.3;
  D6 = data.2;
  D5 = data.1;
  D4 = data.0;
  EN = 0;
  nop();
  EN = 1;
  delay(5);
}

char division( char x, char y)  		/* function header            */
  {                          		/* start of function body     */
     char f;
     f = x / y;
     return f;   
  }                          		/* end of function body       */
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Så där ja ! :-)
Nu är det bara dina kommenterar from "drar iväg" lite, men det gör mindre.
Vad har du för tab-inställningar i din editor ? Med 8 (vilket är normalt) så
drar det iväg.

Ett par saker (som jag inte vet om de löser dina problem, men i alla fall)...

> #pragma config |= 0x3fb0 // use internal 4MHz oscillator

Detta sätter väl inte *bara* oscillatorn till 4 MHz ?
Hur ser övriga CONFIG inställningar ut ?

> OPTION.7 = 0; // pull-up resistance on PORTB

Har du testat med en extern pullup ?
Jag är inte 100% säker på att de interna är på när porten används som T1CKI...
christoferivarsson
Inlägg: 67
Blev medlem: 10 juli 2008, 15:47:06
Ort: stockholm
Kontakt:

Inlägg av christoferivarsson »

Mycket intressanta synpunkter, har inte kört extern pull-up, skall testa när jag kommer hem ikväll. Tack

Configen:
--------------------------------------------------------
Osciallator = internal oscillator RA6=I/O, RA7=I/O
WDT = disabled
PWRT = enabled
RA5=MCLR
BOD reset = enabled
RB4 = PGM low voltage programming
Data memory code protection = off
code protection off
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> RB4 = PGM low voltage programming

Varför ? Och du har PGM pinnen "öppen" i ditt schema...
christoferivarsson
Inlägg: 67
Blev medlem: 10 juli 2008, 15:47:06
Ort: stockholm
Kontakt:

Inlägg av christoferivarsson »

RB4 äre jordad via ett 1kOhm resistans, har med programmeringen att göra men jag är osäker på varför. Testade igår att flytta PICen till ett annat kopplingsdäck utan byglarna som tillhör programmeringen. La också till ett externt pull-up men utan resultat så nu ger jag upp min kod...frustration!!

Har börjat skriva på en interrupt istället men är osäker på ifall man kan använda två interruptrutiner i sammakod. Jag har skrivit en för att räkna antalet pulser på RB0 och spara i "count". Varje sekund vill jag sen avläsa antalet pulser som registrerats i "count". Kan jag skriva ytterliggare en interrupt rutin för en timer som räknar motsvarande 1 sekund och sen avläser värdert i "count". Vad händer isåfall om båda interrupt sammanfaller i tiden?

/Chrsitofer
Skriv svar