Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

URGENT- Timer interrupt 1us issues

Status
Not open for further replies.

gojkosisa

Junior Member level 3
Junior Member level 3
Joined
Sep 27, 2012
Messages
31
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Visit site
Activity points
1,536
Hello,


I'm working on project where I'm using 100us timer-interrupt for controlling AC motor. This application have 16x2 display and buttons for changing parameters of system. This is large project 10k+ lines of code so I write simple example to show my issue.
Please check it.
Code:
//LCD module connections
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;

//Variables
unsigned char input=0;
const unsigned  char UP=100;
const unsigned  char DOWN=101;
unsigned char buttonUP=0;
unsigned char buttonDOWN=0;
unsigned char cnt=0;
unsigned short testVariable;
char txt[4];
///Function
unsigned char getInput();
//////////////
/////MAIN
/////////////
void main() 
{
   ADCON1 = 0x0F;//Digital I/O
   TRISB=0xF7;   //Inputs for buttons
   TRISD=0x00;   //Output
   
   //////TIMER1 - 1us
   T1CON	 = 0x01;
   TMR1IF_bit	 = 0;
   TMR1H	 = 0xFF;
   TMR1L	 = 0xFE;
   TMR1IE_bit	 = 1;
   INTCON	 = 0xC0;
  
   Lcd_Init();                        // Initialize LCD
   Lcd_Cmd(_LCD_CLEAR);               // Clear display
   Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
   Lcd_Out(1,3,"Simple test");
   
   while(1)
    {
      input=getInput();
      if(input==UP)
      testVariable++;
      if(input==DOWN)
      testVariable--;
      
      ByteToStr(testVariable, txt);
      Lcd_Out(2,5, txt);
      
    }
}
//////////////
/////getInput-read inputs (increment, decrement variable)
/////////////
unsigned char getInput()
{
       ///////TIPKA UP
       if (!PORTB.F5)
        {
          buttonUP=1;
        }
       if (buttonUP && PORTB.F5)                    //Check button UP
       {
          buttonUP=0;
          return UP;
       }

      //////TIPKA DOWN
      if (!PORTB.F4)                               //Check button DOWN
        {
          buttonDOWN=1;
        }
      if (buttonDOWN && PORTB.F4)
       {
          buttonDOWN=0;
          return DOWN;
       }
   return 1;
}
//////////////
/////Interrupt (fires every 1us)
/////////////
void Interrupt()
{
  if (TMR1IF_bit)
  {
    TMR1IF_bit = 0;
    TMR1H	 = 0xFF;
    TMR1L	 = 0xFE;
    //Enter your code here
    cnt++;
    PORTD.F1=1; //  Set output - IF I COMMENT THIS PROGRAM WORKS FINE
  }
}

In this example I set 1us timer interrupt time because it is very simple and with 100us works fine. So, here is my issue: if I comment PORTD.F1=1; program works fine but when I uncomment this line of code program don't works at all-display freezes at beginning and don't show message "Simple test".

In my main project, situation is a little diferente. Program is working and display shows text, but timer interrupt time of 100us slow down application.
How to solve this kind of issue? I need to change state of PORTD in interrupt routine because I use phase angle control for controlling speed of AC motor.
MCU: PIC18F4620
mikroC compailer

Regards.
 
Last edited:

1.don't use 1 us interrupt instead increase it if possible.
2.Set flag inside ISR & then in mains if flag active then update port.
 

Hello,

thank you for reply.

1. I must have 100us interrupt (I'm talking about my main project) because I can't control motor without that timer time
2. Again, program is not simple as this example..I must change state of port in interrupt. Phase angle firing is time critical. If you don't fire phase when is zero detected you will not be able to control motor speed.

Regards.
 

Yes I use 100us in project. As I said in first post, that project have 10k lines of code and I can't post that code here. I write this example only to demonstrate the issue. This example don't freezes at 100us because it is very, very simple but in this project MCU have to do a lot of other things.
 

I don't use mikroC but I suggest you look at the disassembled code to see what is created by the offending instruction. Also, LAT may be better to use than PORT although the distinction is processor and compiler dependant so PORT may be OK. What is connected to PORTD bit 1? If you use a different port/bit does the same problem occur? I am not sure if the compiler may not be handling bank switching correctly, assuming it is relevant for accessing the ports on the processor you are using - it is not one i have used.

Keith
 

Thank you Keith,

I have tried everything:
-LAT register
-all ports
-Diferent pins

But still doesn't works.

PORTD F1 is connected to opto-triac but I have checked other pins even pin with NC (free pin, no connection).


Regards

- - - Updated - - -

Could you please check assembly code:
Code:
_main:

;TimerIssues.c,30 ::                 void main()
;TimerIssues.c,32 ::                 ADCON1 = 0x0F;//Digital I/O
        MOVLW       15
        MOVWF       ADCON1+0 
;TimerIssues.c,33 ::                 TRISB=0xF7;   //Inputs for buttons
        MOVLW       247
        MOVWF       TRISB+0 
;TimerIssues.c,34 ::                 TRISD=0x00;   //Output
        CLRF        TRISD+0 
;TimerIssues.c,35 ::                 TRISC=0x00;
        CLRF        TRISC+0 
;TimerIssues.c,36 ::                 TRISA=0x00;
        CLRF        TRISA+0 
;TimerIssues.c,39 ::                 T1CON         = 0x01;
        MOVLW       1
        MOVWF       T1CON+0 
;TimerIssues.c,40 ::                 TMR1IF_bit         = 0;
        BCF         TMR1IF_bit+0, BitPos(TMR1IF_bit+0) 
;TimerIssues.c,41 ::                 TMR1H         = 0xFF;
        MOVLW       255
        MOVWF       TMR1H+0 
;TimerIssues.c,42 ::                 TMR1L         = 0xFE;
        MOVLW       254
        MOVWF       TMR1L+0 
;TimerIssues.c,43 ::                 TMR1IE_bit         = 1;
        BSF         TMR1IE_bit+0, BitPos(TMR1IE_bit+0) 
;TimerIssues.c,44 ::                 INTCON         = 0xC0;
        MOVLW       192
        MOVWF       INTCON+0 
;TimerIssues.c,46 ::                 Lcd_Init();                        // Initialize LCD
        CALL        _Lcd_Init+0, 0
;TimerIssues.c,47 ::                 Lcd_Cmd(_LCD_CLEAR);               // Clear display
        MOVLW       1
        MOVWF       FARG_Lcd_Cmd_out_char+0 
        CALL        _Lcd_Cmd+0, 0
;TimerIssues.c,48 ::                 Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
        MOVLW       12
        MOVWF       FARG_Lcd_Cmd_out_char+0 
        CALL        _Lcd_Cmd+0, 0
;TimerIssues.c,49 ::                 Lcd_Out(1,3,"Simple test");
        MOVLW       1
        MOVWF       FARG_Lcd_Out_row+0 
        MOVLW       3
        MOVWF       FARG_Lcd_Out_column+0 
        MOVLW       ?lstr1_TimerIssues+0
        MOVWF       FARG_Lcd_Out_text+0 
        MOVLW       hi_addr(?lstr1_TimerIssues+0)
        MOVWF       FARG_Lcd_Out_text+1 
        CALL        _Lcd_Out+0, 0
;TimerIssues.c,51 ::                 while(1)
L_main0:
;TimerIssues.c,53 ::                 input=getInput();
        CALL        _getInput+0, 0
        MOVF        R0, 0 
        MOVWF       _input+0 
;TimerIssues.c,54 ::                 if(input==UP)
        MOVF        R0, 0 
        XORLW       100
        BTFSS       STATUS+0, 2 
        GOTO        L_main2
;TimerIssues.c,55 ::                 testVariable++;
        INCF        _testVariable+0, 1 
L_main2:
;TimerIssues.c,56 ::                 if(input==DOWN)
        MOVF        _input+0, 0 
        XORLW       101
        BTFSS       STATUS+0, 2 
        GOTO        L_main3
;TimerIssues.c,57 ::                 testVariable--;
        DECF        _testVariable+0, 1 
L_main3:
;TimerIssues.c,59 ::                 ByteToStr(testVariable, txt);
        MOVF        _testVariable+0, 0 
        MOVWF       FARG_ByteToStr_input+0 
        MOVLW       _txt+0
        MOVWF       FARG_ByteToStr_output+0 
        MOVLW       hi_addr(_txt+0)
        MOVWF       FARG_ByteToStr_output+1 
        CALL        _ByteToStr+0, 0
;TimerIssues.c,60 ::                 Lcd_Out(2,5, txt);
        MOVLW       2
        MOVWF       FARG_Lcd_Out_row+0 
        MOVLW       5
        MOVWF       FARG_Lcd_Out_column+0 
        MOVLW       _txt+0
        MOVWF       FARG_Lcd_Out_text+0 
        MOVLW       hi_addr(_txt+0)
        MOVWF       FARG_Lcd_Out_text+1 
        CALL        _Lcd_Out+0, 0
;TimerIssues.c,62 ::                 }
        GOTO        L_main0
;TimerIssues.c,63 ::                 }
L_end_main:
        GOTO        $+0
; end of _main

_getInput:

;TimerIssues.c,67 ::                 unsigned char getInput()
;TimerIssues.c,70 ::                 if (!PORTB.F5)
        BTFSC       PORTB+0, 5 
        GOTO        L_getInput4
;TimerIssues.c,72 ::                 buttonUP=1;
        MOVLW       1
        MOVWF       _buttonUP+0 
;TimerIssues.c,73 ::                 }
L_getInput4:
;TimerIssues.c,74 ::                 if (buttonUP && PORTB.F5)                    //Check button UP
        MOVF        _buttonUP+0, 1 
        BTFSC       STATUS+0, 2 
        GOTO        L_getInput7
        BTFSS       PORTB+0, 5 
        GOTO        L_getInput7
L__getInput14:
;TimerIssues.c,76 ::                 buttonUP=0;
        CLRF        _buttonUP+0 
;TimerIssues.c,77 ::                 return UP;
        MOVLW       100
        MOVWF       R0 
        GOTO        L_end_getInput
;TimerIssues.c,78 ::                 }
L_getInput7:
;TimerIssues.c,81 ::                 if (!PORTB.F4)                               //Check button DOWN
        BTFSC       PORTB+0, 4 
        GOTO        L_getInput8
;TimerIssues.c,83 ::                 buttonDOWN=1;
        MOVLW       1
        MOVWF       _buttonDOWN+0 
;TimerIssues.c,84 ::                 }
L_getInput8:
;TimerIssues.c,85 ::                 if (buttonDOWN && PORTB.F4)
        MOVF        _buttonDOWN+0, 1 
        BTFSC       STATUS+0, 2 
        GOTO        L_getInput11
        BTFSS       PORTB+0, 4 
        GOTO        L_getInput11
L__getInput13:
;TimerIssues.c,87 ::                 buttonDOWN=0;
        CLRF        _buttonDOWN+0 
;TimerIssues.c,88 ::                 return DOWN;
        MOVLW       101
        MOVWF       R0 
        GOTO        L_end_getInput
;TimerIssues.c,89 ::                 }
L_getInput11:
;TimerIssues.c,90 ::                 return 1;
        MOVLW       1
        MOVWF       R0 
;TimerIssues.c,91 ::                 }
L_end_getInput:
        RETURN      0
; end of _getInput

_Interrupt:

;TimerIssues.c,95 ::                 void Interrupt()
;TimerIssues.c,97 ::                 if (TMR1IF_bit)
        BTFSS       TMR1IF_bit+0, BitPos(TMR1IF_bit+0) 
        GOTO        L_Interrupt12
;TimerIssues.c,99 ::                 TMR1IF_bit = 0;
        BCF         TMR1IF_bit+0, BitPos(TMR1IF_bit+0) 
;TimerIssues.c,100 ::                 TMR1H         = 0xFF;
        MOVLW       255
        MOVWF       TMR1H+0 
;TimerIssues.c,101 ::                 TMR1L         = 0xFE;
        MOVLW       254
        MOVWF       TMR1L+0 
;TimerIssues.c,103 ::                 cnt++;
        INCF        _cnt+0, 1 
;TimerIssues.c,105 ::                 PORTC.F6=1;
        BSF         PORTC+0, 6 
;TimerIssues.c,106 ::                 }
L_Interrupt12:
;TimerIssues.c,107 ::                 }
L_end_Interrupt:
L__Interrupt18:
        RETFIE      1
; end of _Interrupt
 

The assembler looks OK, although you have PORTC.F6 in that example.

However, if you have 1us interrupt there isn't enough time to execute the interrupt routine. At 32MHz clock it is divided by 4 to get the instruction cycle so 8M instructions per second. You have 10 instructions in you interrupt routine. It is what "Golden Electronics" has been saying. You simply cannot run with 1us interrupt.

Keith
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top