help with Interrupts Please!!

Started by prel...@gmail.com October 21, 2011
Hi everyone I am using the the Dragon 12 Plus and the GNU compiler. I am having a major problem using interrupts to completing my project. For my project I am using a sensor to measure a distance and when the distance is under 30 ins it should activate a timer that would count to 10 (displayed on the seven segment) and stop but if the sensor measures under 30 ins again it should restart the counter and count to ten again even if the counter is already counting. The problem that I am having is that every time it measures under 30 ins the counter doesn't want to restart. I have posted the code in question. Any help would be greatly appreciated. Thank You
#include
#include
#include
#include
#include
#include
//#include
#define INTERRUPT __attribute__((interrupt))

void INTERRUPT rtiISR(void);
void waitfor20us(void);
void openAD0(void);
char buf[8];
char *msg1 = "Distance = ";
char *blanks = " ";
char segPat[13] = {0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67,0x3F,
0x06,0x5B,0x4F};
char digit[4]={0xFE,0xFD,0xFB,0xF7};
char digits[9]= {0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
int temp1,temp2,count1,count2,time,seq,ix,count ;
char sign,fdigit,frem;
char *ptr;

char i,p;

int main()
{
DDRB= 0xFF; // configure Port B for output
DDRP= 0x0F;
delayby100ms(2);
openLCD();
openAD0();
cmd2LCD(0x80);
putsLCD(msg1);

seq = 0;
ix = 0;
count = 400;
asm("ldd #rtiISR");
asm("pshd");
asm("ldd #56");
asm("ldx 0xEEA4");
asm("jsr 0,x");
RTICTL = 0x40; //RTI interrupt interval set to 2**10 OSCCLK cycles
DDRB = 0xFF; //configure Port B for output
DDRP = 0xFF; //configure Port P for output
// CRGINT |= RTIE;//enable RTI interrupt
// asm("CLI"); //enable interrupt globally
//while(1);
while(1) {
sign = 0;
ATD0CTL5 = 0x86;
while(!(ATD0STAT0 & SCF));
temp1 = (ATD0DR0 * 10) / 50;

if (temp1 < 30) {

CRGINT |= RTIE;
// asm("CLI");
//PTJ=0xfd; PTB=0xff;
// delayby100ms(2);
//PTJ=0x00; PTB=0x00;
//delayby100ms(5);
// count1 ++;
// delayby100ms(5);
}

if (sign) {
ptr = &buf[1];
buf[0] = 0x2D;
}
else
ptr = &buf[0];
int2alpha(temp1,ptr);
ptr = &buf[0];
while(*ptr)
ptr++;
*ptr++ = '.';
*ptr++ = fdigit + 0x30;
//*ptr++ = 223;
*ptr++ = 'i';
*ptr++ = 'n';
*ptr = 0;
cmd2LCD(0xC0);
putsLCD(blanks);
cmd2LCD(0xC5);
putsLCD(&buf[0]);
delayby100ms(2);
}
}
void openAD0(void)
{
ATD0CTL2 = 0xE0;
ATD0CTL3 = 0x0A;
ATD0CTL4 = 0x25;
delayby10us(2);
}
void waitfor20us(void)
{
TSCR1 = 0x90;
TSCR2 = 0;
TIOS |= OC0;
TC0 = TCNT + 480;
while(!(TFLG1 & C0F));
}

void INTERRUPT rtiISR(void) {
CRGFLG = 0x80; // clear RTIF bit
PTB = segPat[seq+ix];
PTP = digit[ix];
ix++;
if (ix == 4)
ix = 0;
count--;
if(count == 0){
seq++;
count = 400;
}
if(seq == 10)
seq = 0;
}
I didn't study your code but noticed that you need to declare all variables accessed both in your ISR and outside the ISR as volatile.

That will easily cause the sort of problem you are reporting.

Tom Almy
Tualatin, Oregon USA
Internet: t...@almy.us
Website: almy.us

On Oct 20, 2011, at 10:38 PM, p...@gmail.com wrote:

> Hi everyone I am using the the Dragon 12 Plus and the GNU compiler. I am having a major problem using interrupts to completing my project. For my project I am using a sensor to measure a distance and when the distance is under 30 ins it should activate a timer that would count to 10 (displayed on the seven segment) and stop but if the sensor measures under 30 ins again it should restart the counter and count to ten again even if the counter is already counting. The problem that I am having is that every time it measures under 30 ins the counter doesn't want to restart. I have posted the code in question. Any help would be greatly appreciated. Thank You
> #include
> #include
> #include
> #include
> #include
> #include
> //#include
> #define INTERRUPT __attribute__((interrupt))
>
> void INTERRUPT rtiISR(void);
> void waitfor20us(void);
> void openAD0(void);
> char buf[8];
> char *msg1 = "Distance = ";
> char *blanks = " ";
> char segPat[13] = {0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67,0x3F,
> 0x06,0x5B,0x4F};
> char digit[4]={0xFE,0xFD,0xFB,0xF7};
> char digits[9]= {0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
> int temp1,temp2,count1,count2,time,seq,ix,count ;
> char sign,fdigit,frem;
> char *ptr;
>
> char i,p;
>
> int main()
> {
> DDRB= 0xFF; // configure Port B for output
> DDRP= 0x0F;
> delayby100ms(2);
> openLCD();
> openAD0();
> cmd2LCD(0x80);
> putsLCD(msg1);
>
> seq = 0;
> ix = 0;
> count = 400;
> asm("ldd #rtiISR");
> asm("pshd");
> asm("ldd #56");
> asm("ldx 0xEEA4");
> asm("jsr 0,x");
> RTICTL = 0x40; //RTI interrupt interval set to 2**10 OSCCLK cycles
> DDRB = 0xFF; //configure Port B for output
> DDRP = 0xFF; //configure Port P for output
> // CRGINT |= RTIE;//enable RTI interrupt
> // asm("CLI"); //enable interrupt globally
> //while(1);
> while(1) {
> sign = 0;
> ATD0CTL5 = 0x86;
> while(!(ATD0STAT0 & SCF));
> temp1 = (ATD0DR0 * 10) / 50;
>
> if (temp1 < 30) {
>
> CRGINT |= RTIE;
> // asm("CLI");
> //PTJ=0xfd; PTB=0xff;
> // delayby100ms(2);
> //PTJ=0x00; PTB=0x00;
> //delayby100ms(5);
> // count1 ++;
> // delayby100ms(5);
> }
>
> if (sign) {
> ptr = &buf[1];
> buf[0] = 0x2D;
> }
> else
> ptr = &buf[0];
> int2alpha(temp1,ptr);
> ptr = &buf[0];
> while(*ptr)
> ptr++;
> *ptr++ = '.';
> *ptr++ = fdigit + 0x30;
> //*ptr++ = 223;
> *ptr++ = 'i';
> *ptr++ = 'n';
> *ptr = 0;
> cmd2LCD(0xC0);
> putsLCD(blanks);
> cmd2LCD(0xC5);
> putsLCD(&buf[0]);
> delayby100ms(2);
> }
> }
> void openAD0(void)
> {
> ATD0CTL2 = 0xE0;
> ATD0CTL3 = 0x0A;
> ATD0CTL4 = 0x25;
> delayby10us(2);
> }
> void waitfor20us(void)
> {
> TSCR1 = 0x90;
> TSCR2 = 0;
> TIOS |= OC0;
> TC0 = TCNT + 480;
> while(!(TFLG1 & C0F));
> }
>
> void INTERRUPT rtiISR(void) {
> CRGFLG = 0x80; // clear RTIF bit
> PTB = segPat[seq+ix];
> PTP = digit[ix];
> ix++;
> if (ix == 4)
> ix = 0;
> count--;
> if(count == 0){
> seq++;
> count = 400;
> }
> if(seq == 10)
> seq = 0;
> }
>