|
|
View previous topic :: View next topic |
Author |
Message |
Guest Guest
|
interrupt on overflow |
Posted: Sun Sep 10, 2006 6:03 am |
|
|
Chip 16F917
8mhZ external OSC
This is the code from some of the last post's:
Code: |
#include <16F917.h>
#fuses HS,NOWDT,NOPUT,NOPROTECT,NODEBUG,BROWNOUT
#use delay(clock=8000000)
//********************* INIT *********************************
#byte T1CON = 0x10 // timer 1
#byte INTCON = 0x0B // Intcon
//------------------------------------------------------------
#bit TMR1ON = T1CON.0 // 0 Bit --> Timer1 - 1/8
#bit T1SYNC = T1CON.2 // 2 Bit
#bit T1CKPS1 = T1CON.5 // 5 Bit
//-----------------------------------------------------------
#bit GIE = INTCON.0 // 0 Bit --> GlobalInterruptEnable
//************************************************************
void main()
{
int16 tick;
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT);
T1SYNC = 1;
TMR1ON = 1;
GIE = 0;
//*******************************************************************************************
while( TRUE )
{
output_high(PIN_B1);
tick=915;
disable_interrupts(INT_TIMER1); // enable_interrupts
do {
sleep();
delay_cycles(1);
clear_interrupt(INT_TIMER1); // removed
} while (tick--);
output_high(PIN_B0);
}
} |
//----------------------------------
When program reach's sleep part he stucks in this part and there is no way out ( no wakeup & i newer reach pin_b0 ). I have copyed this code from the previus post but this code can not be correct, becuse in the datasheet i can finds such infos:
To make sleep i have to do:
- activate timer1
- globaly close all interrupts
- remove the interrupt flag.
So i done this but im still stuck in the sleep part !.
I know it's sunday and non working day, but come on guys, give me some clue how to correct this code.
Thank you in advance ! |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Sun Sep 10, 2006 7:11 am |
|
|
I think I see your problem and if your code post is a cut & paste and not an attempt to re-type there's probably a pretty good chance. Look at the line in your main do loop where you commented that you enabled interrupts. You put it to sleep with no way of waking it.....
Good luck,
John |
|
|
Guest
|
|
Posted: Sun Sep 10, 2006 7:29 am |
|
|
You put it to sleep with no way of waking it.....
** Becuse the wakeup can be executed just on timer one overflow i dont see any other solution. I know im wrong and i know i can not reach the "output_high (PIN_B0)" on this way, but i must trigger the sleep command ?
And if i trigger sleep part then im stuck.. So basicly, im spinning in the circle.
Mr. jecottrell can you be please more specific on solving this issue ? |
|
|
Guest Guest
|
|
Posted: Sun Sep 10, 2006 7:58 am |
|
|
btw.
Do i have to make something like :
or not (to make the wakeup ) ? |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sun Sep 10, 2006 7:59 am |
|
|
Quote: |
You put it to sleep with no way of waking it.....
|
Take the figure 16-10 of the datasheet (Page 204) and watch the GIE bit level while
the PIC is in sleep mode waiting for wake-up.
Re-check if your interrupt enables were set properly !!!
http://ww1.microchip.com/downloads/cn/DeviceDoc/cn020956.pdf#search
Humberto |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Sun Sep 10, 2006 8:33 am |
|
|
Code: | disable_interrupts(INT_TIMER1); // enable_interrupts |
disable_interrupts(INT_TIMER1) != enable_interrupts
I may be wrong, but I don't believe the timer1 interrupt is active if you've disabled it? |
|
|
Guest Guest
|
|
Posted: Sun Sep 10, 2006 8:54 am |
|
|
Quote: | I may be wrong, but I don't believe the timer1 interrupt is active if you've disabled it? | :-)) I was using this just as example. This is the way i have set it up :
Code: |
#include <16F917.h>
#fuses HS,NOWDT,NOPUT,NOPROTECT,NODEBUG,BROWNOUT
#use delay(clock=8000000)
#include "lcd.c"
//********************* INIT *********************************
#byte T1CON = 0x10 // timer 1
#byte INTCON = 0x0B // Intcon
//------------------------------------------------------------
#bit TMR1ON = T1CON.0 // 0 Bit --> Timer1 - 1/8
#bit T1SYNC = T1CON.2 // 2 Bit
#bit T1CKPS1 = T1CON.5 // 5 Bit
//-----------------------------------------------------------
#bit GIE = INTCON.0 // 0 Bit --> GlobalInterruptEnable
//************************************************************
void main()
{
int16 tick;
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT);
T1SYNC = 1;
TMR1ON = 1;
GIE = 0;
lcd_init();
//*******************************************************************************************
while( TRUE )
{
output_high(PIN_B1);
tick=915;
enable_interrupts(INT_TIMER1);
do {
printf(lcd_putc,"\n\f%x",tick); // just for test
delay_ms(300);
sleep();
delay_cycles(1);
//clear_interrupt(INT_TIMER1);
} while (tick--);
output_high(PIN_B0);
}
} |
If the code is correct this should work and it is working until he reaches the sleep part.
Quote: | Re-check if your interrupt enables were set properly !!!
| ** I have looked into this datasheet over 20 times and it looks like am too dumb to understand what is happening.
I know he is setting the sleep part and the status PD bit is set, but the problem is the same. I have tryed to make wakeup thru watching the GIE bit, but without success... |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Sun Sep 10, 2006 7:12 pm |
|
|
Do you have any other IO indications you can use for debugging? An LED or something? I'll typically blunder through the troubleshooting process with LED flashes to show me what's happening. (Your manual manipulation of configuration bits gives me an idea that you know what you're doing.... probably more than I.)
If you put a LED flash in an ISR for Timer1, you'll be able to see whether your code is firing the INT or not and whether it is re-entering after the SLEEP command as you'd like it to or not....
I assume your LCD is working?
More info at this point and accurate cut & pastes of your code will help.
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 10, 2006 9:42 pm |
|
|
I assume you have a 32 KHz crystal on the Timer1 oscillator pins. Here
is a demo program that will wake-up 2 seconds after it goes to sleep.
It sets Timer1 = 0, so it will take 2 seconds to count up to 0xFFFF and
overflow.
The key to making this program work, is to understand that there is
an additional enable bit that must be set to let Timer1 interrupts
wakeup the PIC. It's the PEIE bit in the INTCON register. CCS doesn't
have a constant defined for this bit in the PIC's .H file. CCS includes
the PEIE bit with the GIE bit when you do "enable_interrupts(GLOBAL)".
Apparently CCS didn't anticipate that anyone would want to wake-up
on just a peripheral interrupt, without having global interrupts enabled.
But anyway, you can add a constant for it as shown below. Then it
works. I tested this with PCM vs. 3.249 on a PicDem2-Plus board.
Code: |
#include <16F877.H>
#fuses XT, NOWDT, PROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define INT_PERIPHERAL 0x0B40 // For 16F877
//===============================
void main()
{
printf("Start\n\r");
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_PERIPHERAL);
sleep();
printf("Woke up from sleep\n\r");
while(1);
} |
|
|
|
Guest
|
|
Posted: Wed Sep 13, 2006 5:16 am |
|
|
First of all i must thank all posters ( Ttelmah, jecottrell, PCM Programmer ) on great wish for helping. Becuse of you guys, this compiler is workin and getting better and better.
@ PCM Programmer:
Your code is working perfetcly on 16F877 !! .
After i have switched to 16f917, changed the clock to 8 mhz and changed the INT_AD to 0x8C40, the problem is the same...
I can reach the part before sleep but then again when i reach sleep () ,program gets stuck ( no wakeup ). I dont know .... |
|
|
Ttelmah Guest
|
|
Posted: Wed Sep 13, 2006 5:58 am |
|
|
INT_AD???...
The only devices that can wake you up from sleep, are those that run when the unit is asleep. The ADC, will only do so, if it is running off it's RC clock. To sleep while a conversion is being done, you would have to use:
Code: |
setup_adc(ADC_CLOCK_INTERNAL); //use RC clock
disable_interrupts(global); //prevent interrupts from calling a handler
enable_interrupts(INT_AD); //Enable the interrupt you want to wake up
clear_interrupts(INT_AD); //Make sure it is clear (otherwise no sleep)
read_ADC(ADC_START_ONLY); //start the ADC
sleep(); //sleep till the ADC conversion completes
delay_cycles(1); //dummy instruction for the pre-fetch
|
This will wake up and continue when the ADC conversion has completed.
Best Wishes |
|
|
Mat Guest
|
|
Posted: Thu Sep 14, 2006 10:05 am |
|
|
My mistake, wrong thema. Sorry !
Anyway i tried code from Ttelmah and changed code from pcm programmer and both of those codes get freezed when program reaches sleep. There is no problem on the F877... just on F917.
Code: | #include <16F917>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT
#use delay(clock=8000000)
#include "lcd.c"
#define INT_PERIPHERAL 0x0B40 // 2864
#byte T1CON = 0x10 // timer 1
#byte INTCON = 0x0B // Intcon
#byte PIE1 = 0x8C // PIE
#bit TMR1ON = T1CON.0 // 0 Bit --> Timer1 - 1/8
#bit PEIE = INTCON.6 // PEIE
#bit GIE = INTCON.7 // GIE
#bit TMR1IE = PIE1.0 // TMR1IE
//===============================
void main()
{
TMR1IE = 1;
GIE = 1;
PEIE = 1;
lcd_init();
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_PERIPHERAL);
output_high(PIN_B0); delay_ms(300); output_low(PIN_B0);
printf(lcd_putc,"Sleep...\n\r");
sleep();
printf(lcd_putc,"Woked up \n\r");
while(1);
} |
|
|
|
Mat Guest
|
|
Posted: Mon Sep 18, 2006 9:02 am |
|
|
I changed bunch of stuff to get this working but again program freezes in sleep part... Now im really out of idea...
Code: | #include <16F917>
#fuses EC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT
#use delay(clock=8000000)
#include "lcd.c"
//===============================
#byte T1CON = 0x10 // timer 1 control registar
#byte INTCON = 0x0B // Intcon
#byte PIE1 = 0x8C // PIE
#byte PIR1 = 0xC //
#bit TMR1IE = PIE1.0 // TMR1IE
#bit TMR1IF = PIR1.0 // Timer1 interrupt flag
#bit TMR1ON = T1CON.0 // 0 Bit --> Timer1 - 1/8
#bit T1SYNC = T1CON.2 // Timer 1 sync / async bit
#bit PEIE = INTCON.6 // PEIE
#bit GIE = INTCON.7 // GIE
//===============================
void main()
{
int tick;
GIE = 0; // Global Interrupt Enable bit --> OFF
PEIE = 1; // Peripheral Interrupt Enable bit --> ON
T1SYNC = 1; // Do not synchronize ext.clock input --> ON
TMR1IE = 1; // Timer1 overflow interrupt enable --> ON
//---------------
lcd_init();
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);
//---------------
tick=915;
printf(lcd_putc,"Sleep...\n\r"); output_high(PIN_B0); delay_ms(300); output_low(PIN_B0);
do {
TMR1IE = 1; // timer1 interrupt enable --> ON
TMR1IF = 0; // delete timer1 interrupt flag --> ON
set_timer1(0);
sleep();
} while (tick--);
printf(lcd_putc,"Woked up \n\r"); output_high(PIN_B1); delay_ms(300); output_low(PIN_B1);
} |
|
|
|
|
|
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 vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|