Hjälp med 16F1937

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Hjälp med 16F1937

Inlägg av newbadboy »

Jag har INTCON.TMR0IF=0;... glöm koden innan den är rättad nu. Men betendet är detsamma med interuptet som inte reagerar.

Får kolla genom alla register och se om jag missta ngt... Jag har ett annat ex som jag har utgått från (http://embedded-lab.com/blog/?p=4653)och det ser ut som det vi har gjort nu... men ändå ngnstans går det fel.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hjälp med 16F1937

Inlägg av sodjan »

Jag har inte kollat om den är inblandad, men för vissa interrupt-källor
så behöver man även sätta INTCON.PEIE=1 ("Peripheral Interrupt Enable bit").
Jag minns inte om Timer0 också räknas till "peripherials", på äldre modeller
gick TMR0IF bredvid PEIE, så att säga. SAnnolikt är det något annat.
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Hjälp med 16F1937

Inlägg av newbadboy »

OEIE var tyvärr inte inblandad som du misstänkte,

Har provat isolera problemet lite mer och bortkommenterat en del i ISR'n som du kan se i koden nedan.

Det händer i princip inget på PWM utgången så ngt måste vara fel så att PWM interuptet inte skapas. Dcok går PWM hög när jag duttar med kabel på INT pinnen vilket är helt logiskt.

Kod: Markera allt

/*
Manöverpanel till fjärrvärme Pic16F1937, intern 8MHz OSC, extern MCLR

*/

#define BUZZ PORTC.F3                                                                   //Name ports
#define SERVO PORTD.F1
#define BACKLIGHT PORTC.F2

sbit PWM_OUT at RD0_bit;

int k=0;
char *text1;
char *text2;

//LCD module connection
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RA2_bit;
sbit LCD_D5 at RA3_bit;
sbit LCD_D6 at RA4_bit;
sbit LCD_D7 at RA5_bit;

sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISA2_bit;
sbit LCD_D5_Direction at TRISA3_bit;
sbit LCD_D6_Direction at TRISA4_bit;
sbit LCD_D7_Direction at TRISA5_bit;
//End LCD module connection

void initMain(){
     TRISA=0b00000000;
     TRISB=0b00110011;
     TRISC=0b11000000;
     TRISD=0b00000000;
     TRISE=0b00000000;

     LCDCON=0b00000000;
     CPSCON0=0b00000000;

     ANSELA=0;
     ANSELB=0;

     INTCON=0b10111000;
     IOCBP=0b00000001;
     OPTION_REG=0b00100111;
     TMR0=180;

     LCD_Init();
     LCD_Cmd(_LCD_CURSOR_OFF);
     LCD_Cmd(_LCD_CLEAR);


     if(k!=1){                                //Kontroll att main inte körs efter interupt
        BUZZ=1;
        delay_ms(50);
        BUZZ=0;
        //BACKLIGHT=1;
        Lcd_out(1,1,"Remote Heater");
        Lcd_out(2,1,"Sp-E 2014");
        }
     }

void interrupt(){
   /*  if(INTF==1){
        SERVO=0;
        k=1;
        BACKLIGHT=0;
        INTCON.INTF=0;
        }  */
     //if(TMR0IF==1){
        PWM_OUT=1;
        Delay_ms(2);
        PWM_OUT=0;
        INTCON.TMR0IF=0;
       // }
     //INTCON=0b00000000;                   //Nolla interupt för att det inte ska loopa hela tiden
     }

void main() {
     initMain();

     while(1){

          
          if(k==1){                                                             //Hör till interuptet
              BUZZ=1;
              delay_ms(50);
              BUZZ=0;
              Lcd_out(1,1,"Servo Error!!!");
              Lcd_out(2,1,"Reset panel!!!");
              while(1){
                       SERVO=0;
                       BACKLIGHT=0;
                       BUZZ=0;
                       }
              }
           
          else if(Button(&PORTB, 5,1,0)||Button(&PORTB, 4,1,0)){
          BACKLIGHT=1;

                 }
              
          else if(Button(&PORTB, 5,1,1)&&Button(&PORTB, 4,1,1)){
          BACKLIGHT=0;
                 }

              
          }
}
Senast redigerad av newbadboy 6 juni 2014, 12:33:55, redigerad totalt 1 gång.
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Hjälp med 16F1937

Inlägg av Icecap »

Hur ser main-loopen ut? Som det är nu kör programmet genom en gång och "faller ut".
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Hjälp med 16F1937

Inlägg av newbadboy »

Kolla nu, fick visst inte med hela koden när jag kopierade.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hjälp med 16F1937

Inlägg av sodjan »

Den kommer ju att "fastna" i den inre while(1) loopen, men
det kanske är avsikten (?).

> //Kontroll att main inte körs efter interupt

Det där förstår jag inte. Main() körs ju alltid utan just då då
koden ligger i interrupt() funktionen. Main() bara "pausar"
medans interrupt() körs...

För övrigt så har ju det här:

Kod: Markera allt

while(1){
         SERVO=0;
         BACKLIGHT=0;
         BUZZ=0;
         }
samma funktion som:

Kod: Markera allt

SERVO=0;
BACKLIGHT=0;
BUZZ=0;
while(1){
        }
Det räcker ju att sätta utgångarna *en* gång...
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Hjälp med 16F1937

Inlägg av newbadboy »

Japp, triggar man INT pinnen så kan man fastna i den inre loopen, tills man gör MCLR reset är det tänkt.


Ang
//Kontroll att main inte körs efter interupt

var något jag experimentrade med lite innan och kommer nog att tas väck sen så den behöver vi eg inte bry oss om.....det handlade om att bara skriva ut text på displayen en gång bara...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hjälp med 16F1937

Inlägg av sodjan »

> ...tills man gör MCLR reset är det tänkt.

Ah, OK. Ja vill man ha det så så är det väl OK.
De flesta skulle nog kalla det en "bugg"... :-)

> var något jag experimentrade med lite innan...

OK. Städa gärna bort sådan innan det postas.
Inte så lätt för *oss* att veta vad vi ska bry oss om eller inte. :-)

Så problemet just nu är att det ser ut som att TMR0 interruptet
inte triggar som det ska?
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Hjälp med 16F1937

Inlägg av newbadboy »

Ja att tmr0 inte triggar är just nu största problemet
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hjälp med 16F1937

Inlägg av sodjan »

Den här koden fungerar. PIC16F1938.
TMR0 räknar upp och när den "slår runt" så körs ISR'en.
Du kan vä'l jämföra med vad du gör i din C kod...

Kod: Markera allt

;    __CONFIG b'010010000101'

    list      p=16f1938
    #include <p16f1938.inc>



;**********************************************
; RESET VECTOR
;**********************************************

RESET_VECT  CODE    0x0000      ; processor reset vector
    PAGESEL START
    GOTO    START
    nop
    nop

;*********************************************
; INTERRUPT SERVICE ROUTINE
;*********************************************

ISR       CODE    0x0004            ; interrupt vector location

    nop

    banksel intcon
    bcf     intcon, tmr0if ; Clear TMR0 interrupt flag.
    
    retfie

prog            code

start

; Initiera Timer0
    banksel option_reg
    bcf     option_reg, ps0 ; Högsta fart...
    bcf     option_reg, ps1 ; -"-
    bcf     option_reg, ps2 ; -"-
    bcf     option_reg, psa
    bcf     option_reg, tmr0cs ; Tmr0 clock source = osc.
    banksel intcon
    bsf     intcon, tmr0ie ; Tmr0 interrupt enable.

; Starta interrupt
    banksel intcon
    bsf     intcon, gie ; Global interrut enable.

    movlw   h'e0' ; Preload TMR0 for faster tests...
    banksel tmr0
    movwf   tmr0
    
loop
     goto    loop ; Wait for interrupt to happen...

    END
EDIT: Plockade bort PEIE, den behövs inte...
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Hjälp med 16F1937

Inlägg av newbadboy »

Kollar av, hör av mig.
Användarvisningsbild
newbadboy
Inlägg: 2485
Blev medlem: 16 september 2006, 19:16:28
Ort: Landskrona
Kontakt:

Re: Hjälp med 16F1937

Inlägg av newbadboy »

Mina assembler kunskaper är rätt små men vad jag kan se är det samma konfig som jag har.

Nu till en uppdatering. Har rensat bort lite i koden som def inte kommer användas. Nu till det riktigt intressanta. Jag har fått igång PWM men ändå inte....

Om koden är exakt som den är nedan så är PWM utgången noll ända tills jag duttar med INT pinnen till 5V och då börjar pulståget snurra. Mao ord av ngn anledning behöver jag putta igång PWM signalen mha av INT pinnen. Om jag har if(TMR0IF==1) så kan jag inte putta igång pwm pulsen, vilket är ju helt rätt.
Nu stämmer ju inte frekvens men det kan jag ställa sen utan problem

Och ofta får jag bara ut 5V hela tiden på PWM utgången direkt jag spänningsätter kortet


Märkte också att om jag får 5V på utgången kan jag inte få bort det utan att sätta INTCON=0b00000000; i slutet på ISR, sedan slår jag på kortet, stänger av tar bort INTCON=0b000000000;. Slår jag nu på kortet och triggar som ovan nämnt med INT pinnen får jag ut pulståget


Så då kvarstår frågan varför drar inte TMR0 igång av sig själv? Och vad innebär konstant 5V?... shit nu börjar jag blir mer förvirrad

Kod: Markera allt

/*
Manöverpanel till fjärrvärme Pic16F1937, intern 4MHz OSC, extern MCLR

*/

#define BUZZ PORTC.F3                                                                   //Name ports
#define SERVO PORTD.F1
#define BACKLIGHT PORTC.F2

sbit PWM_OUT at RD0_bit;

int k=0;
char *text1;
char *text2;

//LCD module connection
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RA2_bit;
sbit LCD_D5 at RA3_bit;
sbit LCD_D6 at RA4_bit;
sbit LCD_D7 at RA5_bit;

sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISA2_bit;
sbit LCD_D5_Direction at TRISA3_bit;
sbit LCD_D6_Direction at TRISA4_bit;
sbit LCD_D7_Direction at TRISA5_bit;
//End LCD module connection

void initMain(){
     TRISA=0b00000000;
     TRISB=0b00110011;
     TRISC=0b11000000;
     TRISD=0b00000000;
     TRISE=0b00000000;

     LCDCON=0b00000000;
     CPSCON0=0b00000000;

     ANSELA=0;
     ANSELB=0;

     INTCON=0b10111000;
     IOCBP=0b00000001;
     OPTION_REG=0b00100111;
     TMR0=180;

     LCD_Init();
     LCD_Cmd(_LCD_CURSOR_OFF);
     LCD_Cmd(_LCD_CLEAR);


     BUZZ=1;
     delay_ms(50);
     BUZZ=0;
     Lcd_out(1,1,"Remote Heater");
     Lcd_out(2,1,"Sp-E 2014");
     }

void interrupt(){
   /*  if(INTF==1){
        SERVO=0;
        k=1;
        BACKLIGHT=0;
        INTCON.INTF=0;
        }  */
    // if(TMR0IF==1){
        PWM_OUT=1;
        Delay_ms(2);
        PWM_OUT=0;
        Delay_ms(18);
        INTCON.TMR0IF=0;
    //    }

     }

void main() {
     initMain();

     while(1){

          
          if(k==1){                                                             //Hör till interuptet
              BUZZ=1;
              delay_ms(50);
              BUZZ=0;
              Lcd_out(1,1,"Servo Error!!!");
              Lcd_out(2,1,"Reset panel!!!");
              while(1){
                       SERVO=0;
                       BACKLIGHT=0;
                       BUZZ=0;
                       }
              }
           
          else if(Button(&PORTB, 5,1,0)||Button(&PORTB, 4,1,0)){
          BACKLIGHT=1;

                 }
              
          else if(Button(&PORTB, 5,1,1)&&Button(&PORTB, 4,1,1)){
          BACKLIGHT=0;
                 }

              
          }
}
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hjälp med 16F1937

Inlägg av sodjan »

Ja, det är ju så att även om din main() "fastnar" i den andra
while(1) loopen, så kommer ju Timer0 ändå att fortsätta snurra
och interruptet att fortsätta generera PWM pulser tills du stänger
av det hela eller resettar.

Är du säker på att du inte behöver skriva if(INTCON.INTF==1)
och if(INTCON.TMR0IF==1)? Du gör ju det på andra ställen. Jag
vet inte om MikroC är tillräckligt smart för att fixa det ändå...
Användarvisningsbild
SeniorLemuren
Inlägg: 8427
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Hjälp med 16F1937

Inlägg av SeniorLemuren »

Här har du kod som genererats av mikroC Timer Calculator

Kod: Markera allt

//Timer0
//Prescaler 1:256; TMR0 Preload = 97; Actual Interrupt Time : 19,969 ms
 
//Place/Copy this part in declaration section
void InitTimer0(){
  OPTION_REG	 = 0x87;
  TMR0		 = 97;
  INTCON	 = 0xA0;
}
 
void Interrupt(){
  if (TMR0IF_bit){ 
    TMR0IF_bit	 = 0;
    TMR0		 = 97;
    //Enter your code here
  }
}
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hjälp med 16F1937

Inlägg av sodjan »

Ja just det, det där har jag sett någonstans.

Så om jag förstår rätt så kan man antingen skriva
"INTCON.TMR0IF" eller "TMR0IF_bit".

Men inte enbart "TMR0IF"...
Skriv svar