It is currently 22 Apr 2018 13:41

All times are UTC + 1 hour




Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: 11 Jan 2015 15:15 
Offline

Joined: 24 Jul 2014 09:37
Posts: 24
Hi Guys,

I am learning about PIC development, and I have been tinkering with interrupts, I am using a RTC clock module to wake my PIC every minute for reading temp, time etc. I have been having issues with the interrupt routine not working, So I put the code in the main loop so when my PIC comes back to life the code is executed to reset registers. Can anyone help it would be awesome to have this happen in the Interrupt procedure instead of the main loop.


program RealTimeClock;

//uses RTC2_DS1307;
  uses RTC_DS3231SN, EEPROM_24LC512;
 
{ Declarations section }

// For DS1307 to uses
Var ts : String[8];   // String to hold the time from DS1307
Var ds : String[10];  // String to hold the date from DS1307

Var text3,text4 : String[20];
Var text1 : String[10];
Var text2 : String[3];
Var EEPROM_Byte : Byte;

Var Values : Array[256] of Byte;

Var Count : Byte;

// LCD module connections
var LCD_RS : sbit  at LATE4_bit;
var LCD_EN : sbit  at LATE5_bit;
var LCD_D4 : sbit  at LATE0_bit;
var LCD_D5 : sbit  at LATE1_bit;
var LCD_D6 : sbit  at LATE2_bit;
var LCD_D7 : sbit  at LATE3_bit;

var LCD_RS_Direction : sbit at TRISE4_bit ;
var LCD_EN_Direction : sbit at TRISE5_bit ;
var LCD_D4_Direction : sbit at TRISE0_bit;
var LCD_D5_Direction : sbit at TRISE1_bit;
var LCD_D6_Direction : sbit at TRISE2_bit;
var LCD_D7_Direction : sbit at TRISE3_bit;
// End LCD module connections

var Flag : Bit;

Procedure Interrupt_Low;
Begin
     Flag := 1;
     if TestBit(INTCON, INT0IF) = 1 then
     begin
          INTCON.INT0IF := 0;
          INTCON.INT0IE := 1;
          ClearBit(INTCON, INT0IF); //Clear the interrupt Flag
         
     end;
end;

begin        org 0x1000;
  orgall(0x1000);
  { Main program }

  TRISB := 1;
  INTCON := 0x10;
  INTCON2.6 := 0;
 
  TRISG0_Bit := 0;
  PORTG.0 := 1;
 
  EEPROM_Byte := 99;
  //initialize the LCD display
  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
 
  Lcd_Out(1,1,'Booted !');
  //initialize the I2C
  i2c1_init(100000);
  Lcd_Out(1,1,'I2C Init Done !');

  initRTC; //Initialize Connection to the RTC
 
  RtcSetInterruptMinute;
  RTCClearInterrupt;

  Lcd_Out(1,1,'RTC Init Done !');
  delay_ms(1000);
  Lcd_Cmd(_LCD_CLEAR);
  while true do
    begin
   
     if TestBit(INTCON, INT0IF) = 1 then
     begin
          INTCON.INT0IF := 0;
          INTCON.INT0IE := 1;
          ClearBit(INTCON, INT0IF); //Clear the interrupt Flag
          RTCClearInterrupt; //Clear the RTC Interrupt Flag
     end;

     RtcTimeDateStr(text3, text4);  //Get the Time and Date
     Lcd_Out(1, 1, text3);         // Print text at LCD
     Lcd_Out(2, 1, text4);         // Print text at LCD
     RtcTempStr(text1);
     Lcd_Out(1,9,text1);
     Lcd_Chr(1,15,223);                                         // Print degree character, 'C' for Centigrades
                                                             // Different LCD displays have different char code for degree
     Lcd_Chr(1,16,'C');


    delay_ms(2500);
    LCD_CMD(_LCD_CLEAR);
    LCD_Out(1,1,'Sleeping....');
    PORTG.0 := 0;
    asm
        sleep; //Send Processor to sleep
    end;

    end;
end.



Many thanks in advance for your assistance.

Phil


Top
 Profile  
 
PostPosted: 11 Jan 2015 16:11 
Offline

Joined: 18 Feb 2006 13:17
Posts: 4892
For any interrupt to work one has to enable it. Furthermore, INT0 cannot work as low priority interrupt, not to mention that for low priority interrupts to work one has to enable the priority feature (bit RCON.IPEN). Change your ISR to
Procedure interrupt;
 Begin
   if INTCON.INT0IF then
     begin
        INTCON.INT0IF:=0;
        Flag:=1;
     end;
 end;
activate the interrupt in proper sequence
  INTCON.INTEDG0:=1;
  INTCON.INT0IE:=1;
  INTCON.GIE:=1;
and test the Flag (and clear it if set) in main to undertake proper action in response to INT0 interrupt.

BTW, use LAT register for switching single output bit (LATG.0 instead of PORTG.0).

_________________
Replacement libraries for mP PRO and PIC18 processors, mP PRO tips & trics


Top
 Profile  
 
PostPosted: 11 Jan 2015 18:09 
Offline

Joined: 24 Jul 2014 09:37
Posts: 24
Thanks for the advice, I tried what you suggested with the intcon.bit and it didn't work I must be missing something really basic.if I posted my code any chance you would be so kind as to take a look?


Top
 Profile  
 
PostPosted: 11 Jan 2015 18:51 
Offline

Joined: 18 Feb 2006 13:17
Posts: 4892
Sure, it's the only way anyone may help :) .

_________________
Replacement libraries for mP PRO and PIC18 processors, mP PRO tips & trics


Top
 Profile  
 
PostPosted: 11 Jan 2015 19:49 
Offline

Joined: 24 Jul 2014 09:37
Posts: 24
I think I implemented your example bits as expected, I don't get my PIC waking up.

program RealTimeClock;

//uses RTC2_DS1307;
  uses RTC_DS3231SN, EEPROM_24LC512;
 
{ Declarations section }

// For DS1307 to uses
Var ts : String[8];   // String to hold the time from DS1307
Var ds : String[10];  // String to hold the date from DS1307

Var text3,text4 : String[20];
Var text1 : String[10];
Var text2 : String[3];
Var EEPROM_Byte : Byte;

Var Values : Array[256] of Byte;

Var Count : Byte;

// LCD module connections
var LCD_RS : sbit  at LATE4_bit;
var LCD_EN : sbit  at LATE5_bit;
var LCD_D4 : sbit  at LATE0_bit;
var LCD_D5 : sbit  at LATE1_bit;
var LCD_D6 : sbit  at LATE2_bit;
var LCD_D7 : sbit  at LATE3_bit;

var LCD_RS_Direction : sbit at TRISE4_bit ;
var LCD_EN_Direction : sbit at TRISE5_bit ;
var LCD_D4_Direction : sbit at TRISE0_bit;
var LCD_D5_Direction : sbit at TRISE1_bit;
var LCD_D6_Direction : sbit at TRISE2_bit;
var LCD_D7_Direction : sbit at TRISE3_bit;
// End LCD module connections

var Flag : Bit;

Procedure interrupt;
Begin
     if TestBit(INTCON, INT0IF) = 1 then
     begin
          INTCON.INT0IF := 0;
          Flag := 1;
     end;
end;

begin        org 0x1000;
  orgall(0x1000);
  { Main program }

  TRISB := 1;
  //INTCON := 0x10;
  //INTCON2.6 := 0;
 
  INTCON2.INTEDG0:=0;
  INTCON.INT0IE:=1;
  INTCON.GIE:=1;
 
  LATG.0 := 0;
 
  //EEPROM_Byte := 99;
  //initialize the LCD display
  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
 
  Lcd_Out(1,1,'Booted !');
  //initialize the I2C
  i2c1_init(100000);
  Lcd_Out(1,1,'I2C Init Done !');

  initRTC; //Initialize Connection to the RTC
 
  RtcSetInterruptMinute;

  Lcd_Out(1,1,'RTC Init Done !');
  delay_ms(1000);
  Lcd_Cmd(_LCD_CLEAR);
  while true do
    begin
   
     if Flag = 1 then
     begin
          LCD_Out(1,1, 'Interrupt');
          RTCClearInterrupt; //Clear the RTC Interrupt Flag
          Flag := 0;
     end
     else LCD_Out(1,1, 'No Interrupt');
     
     RtcTimeDateStr(text3, text4);  //Get the Time and Date
     Lcd_Out(1, 1, text3);         // Print text at LCD
     Lcd_Out(2, 1, text4);         // Print text at LCD
     RtcTempStr(text1);
     Lcd_Out(1,9,text1);
     Lcd_Chr(1,15,223);                                         // Print degree character, 'C' for Centigrades
                                                             // Different LCD displays have different char code for degree
     Lcd_Chr(1,16,'C');


    delay_ms(2500);
    LCD_CMD(_LCD_CLEAR);
    LCD_Out(1,1,'Sleeping....');
    LATG.0 := 1;
    asm
        sleep; //Send Processor to sleep
    end;

    end;

end.


Top
 Profile  
 
PostPosted: 11 Jan 2015 22:18 
Offline

Joined: 18 Feb 2006 13:17
Posts: 4892
Any enabled interrupt wakes processor from sleep. Are you sure there's proper signal on INT0 pin to wake the processor up (falling edge, as you set it)?

You may check if INT0 interrupt is working by skipping the sleep instruction for the moment (add a delay after LCD_Out(1,1, 'Interrupt') to see the message).

_________________
Replacement libraries for mP PRO and PIC18 processors, mP PRO tips & trics


Top
 Profile  
 
PostPosted: 12 Jan 2015 01:43 
Offline

Joined: 29 Mar 2013 12:55
Posts: 117
I don't know which controller you are using, but are you sure INT0 is a low-priority interrupt or you can set it to be a low-priority interrupt?
I checked a couple of 18F datasheets and INT0 is ALWAYS high-priority.
What Janni says is not quite right, it should read 'any enabled external interrupt can wake the controller from sleep'.
E.g. on a 18F4550 Timer0 can not wake up the device from sleep.


Top
 Profile  
 
PostPosted: 12 Jan 2015 10:54 
Offline

Joined: 24 Jul 2014 09:37
Posts: 24
Guys,

I am using the PIC18F67J50 processor, with my original code it is waking up every minute on the signal from the RTC going low but not using the interrupt, when I try to get it to use the interrupt procedure as Janni suggested it doesn't work. It doesn't wake up.

I am really greatful for your help so far.

Phil


Top
 Profile  
 
PostPosted: 12 Jan 2015 15:02 
Offline

Joined: 18 Feb 2006 13:17
Posts: 4892
philcr wrote:
I am using the PIC18F67J50 processor, with my original code it is waking up every minute on the signal from the RTC going low but not using the interrupt, when I try to get it to use the interrupt procedure as Janni suggested it doesn't work. It doesn't wake up.
Does the interrupt work at all? Have you tried what I suggested? I noticed that you moved code to 0x1000 - if you're using a bootloader, maybe it overwrites the jump to ISR that compiler places at 0x08.

hadv wrote:
What Janni says is not quite right, it should read 'any enabled external interrupt can wake the controller from sleep'.
I was thinking only about INTx interrupts, pertinent to the problem, but I should have written so. Anyway, neither 'any' nor 'external' is a proper qualifier - the datasheet uses 'any available' which does not explain much, but is the only appropriate one (there are other interrupt sources, like ADC, Timer1 working as RTC, and more that may wake processor from sleep).

_________________
Replacement libraries for mP PRO and PIC18 processors, mP PRO tips & trics


Last edited by janni on 12 Jan 2015 15:48, edited 1 time in total.

Top
 Profile  
 
PostPosted: 12 Jan 2015 15:17 
Offline

Joined: 24 Jul 2014 09:37
Posts: 24
It definitely does work with INT0 with falling edge set, you are maybe correct with the boot loader code being at the start of the program memory and the ISR being at 0x0008, Am I correct in understanding that it is possible to change the address of the ISR?

Again, I really appreciate your help guys, I'm not confident enough to blitz my boot loader and start coding manual.

Kind Regards

Phil


Top
 Profile  
 
PostPosted: 12 Jan 2015 15:41 
Offline

Joined: 18 Feb 2006 13:17
Posts: 4892
philcr wrote:
Am I correct in understanding that it is possible to change the address of the ISR?
One may move the ISR body, but not interrupt vector (address to which processor branches at interrupt) which is hardware wired at 0x08.

Quote:
I'm not confident enough to blitz my boot loader and start coding manual.
So you're using somebody else's bootloader, but it may still have provisions for interrupts. Do you have some description of this bootloader (like where it expects to find ISRs)?

_________________
Replacement libraries for mP PRO and PIC18 processors, mP PRO tips & trics


Top
 Profile  
 
PostPosted: 12 Jan 2015 15:55 
Offline

Joined: 24 Jul 2014 09:37
Posts: 24
I understand that the bootloader on my processor is the microchip boot loader, I haven't investigated documentation for it though as up until now it has just worked. I have programmer that I have never used, for fear of breaking my dev board.

The dev board I'm using is http://www.robot-electronics.co.uk/htm/dev-p182432.htm which comes with Microchips USB bootloader already programmed. Can anyone advise me as this heading to completely uncharted territory for me.

Kind Regards

Phil


Top
 Profile  
 
PostPosted: 12 Jan 2015 16:12 
Offline

Joined: 18 Feb 2006 13:17
Posts: 4892
The link you've given contains the needed info:
Quote:
The boot loader occupies internal program memory:
PIC18, 0x0000 - 0x0FFF. Application programs start at 0x1000. High/Low interrupt Vectors are at 0x1008/0x1018
It means that the bootloader contains a jump from 0x08 to 0x1008. All you have to do is org your ISR to 0x1008.

_________________
Replacement libraries for mP PRO and PIC18 processors, mP PRO tips & trics


Top
 Profile  
 
PostPosted: 12 Jan 2015 16:39 
Offline

Joined: 24 Jul 2014 09:37
Posts: 24
Thanks Janni,

I will give this a try when I get in tonight, fingers crossed.

Regards

Phil


Top
 Profile  
 
PostPosted: 12 Jan 2015 20:45 
Offline

Joined: 24 Jul 2014 09:37
Posts: 24
Hi Guys,

I attempted the following with my Interrupt procedure

Procedure interrupt; org 0x1008;
Begin
     Flag := 1;
     if TestBit(INTCON, INT0IF) = 1 then
     begin
          INTCON.INT0IF := 0;
          Flag := 1;
     end;
end;


I am unable to build my project i get the following errors,

39 1021 Hint: interrupt handler (interrupt at 0x0008) RealTimeClock.mpas
160 1010 Hint: Unit "RealTimeClock.mpas" has been recompiled RealTimeClock.mpas
0 134 Compiled Successfully D:\Embedded Development\PIC Code\RealTimeClock\RealTimeClock.mpas
0 139 All files Compiled in 46 ms
39 361 Bad function absolute address 'interrupt[4104]' RealTimeClock.mpas
39 342 There is not enough ROM space interrupt[4104] RealTimeClock.mpas
0 453 Unsuccessful linking 'RealTimeClock.mpppi' Unsuccessful linking 'RealTimeClock.mpppi'
0 102 Finished (with errors): 12 Jan 2015, 19:38:02 RealTimeClock.mpppi

I'm now confused I guess it doesn't work because I have to org statements in my code.

Can anyone shed any light on it please.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: