CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

about timer_1 overflow and loop!!! plz help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nfs



Joined: 28 Apr 2004
Posts: 18

View user's profile Send private message

about timer_1 overflow and loop!!! plz help
PostPosted: Tue May 04, 2004 3:33 am     Reply with quote

i want to sample voltage during 2s so i set up timer_1 to interrupt every 100µs and set up a counter of 20000 which will cover the 2s.
i wrote this code but by simulation i changed voltage to view how can this changes the reponse but unsuccessfully.
this is the code:




Code:

#include <16F876.h>
/* Set configuration bits in the PIC processor */
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#device adc=10
#device *=16
#use delay (clock=4000000)

#define led1 PIN_A1
#define led2 PIN_A2
#define led3 PIN_A3
#define Vpp 1024
#define Vppmin 973
#define Vss 0
#define Vctq 921
#define tension_maxi_touche_0 34
#define tension_mini_touche_0 0
#define tension_maxi_touche_R 790
#define tension_mini_touche_R 750
#define tension_maxi_touche_plus 523
#define tension_mini_touche_plus 463
#define tension_maxi_touche_moins 287
#define tension_mini_touche_moins 245
#byte INTCON = 0x0b //registre des interruptions
#byte PIE1 = 0x8c   //registre contenant les autorisations d'interruptions
#byte PIR1 = 0x0c
#byte ADCON0 = 0x1f  //registre du convertisseur
#byte ADCON1 = 0x9f  //rôle des pins+justification du resultat de la conversion
#byte ADRESH = 0x1e
#byte ADRESL = 0x9e
#byte port_b = 0x06
#byte port_c = 0x07
#bit GO_DONE = ADCON0.2
#bit ADON = ADCON0.0
#bit ADIE = PIE1.6
#bit ADIF = PIR1.6
#define SET_TRIS_A = 0b00001; // PORTA  AN0 entrée et les autres en sortie
#define SET_TRIS_B = 0x00; // PORTB en sortie
#define TMR1IE = PIE1.0
#define TMR1IF = PIR1.0
#bit ADFM_BIT=0x9F.7
#bit PCFG3_BIT=0X9F.3
#bit PCFG2_BIT=0X9F.2
#bit PCFG1_BIT=0X9F.1
#bit PCFG0_BIT=0X9F.0


int16 us;
int16 ADCvaleur;
long int Counter;

void InitialiseADC ()
{
setup_port_a( RA0_ANALOG );
setup_adc( ADC_CLOCK_DIV_8 );
set_adc_channel( 0 );
}

#int_TIMER1
TIMER1_isr()
{
     if(Counter++ == 20000)
        {Counter = 0;
        ADIF = 1;}
}

void main( void )
   {
   long ADCvaleur;

      InitialiseADC();
      ADFM_BIT=1;
      output_high (led1);
      delay_ms(500);
      ADCvaleur = 0;     
      {setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); // at 4MHz clock that is overflow at 20us, so find another crystal?????
      enable_interrupts(int_timer1);
      enable_interrupts(global);
      ADCvaleur = read_ADC();
      while(GO_DONE);
      if (ADCvaleur<=34)
         {
         output_low (led1);
         output_high(led2);
         }
       else
         {
         output_low (led1);
         output_high (led3);
         } 
      while(1)
      {
      ;
      }
   }
   }

_________________
nfs


Last edited by nfs on Tue May 04, 2004 9:20 am; edited 2 times in total
Ttelmah
Guest







Re: about this code??
PostPosted: Tue May 04, 2004 5:05 am     Reply with quote

nfs wrote:
i want to sample voltage during 2s so i set up timer_1 to interrupt every 100µs and set up a counter of 20000 which will cover the 2s.
i wrote this code but by simulation i changed voltage to view how can this changes the reponse but unsuccessfully.
this is the code:




Code:

#include <16F876.h>
/* Set configuration bits in the PIC processor */
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#device adc=10
#device *=16
#use delay (clock=4000000)

#define led1 PIN_A1
#define led2 PIN_A2
#define led3 PIN_A3
#define Vpp 1024
#define Vppmin 973
#define Vss 0
#define Vctq 921
#define tension_maxi_touche_0 34
#define tension_mini_touche_0 0
#define tension_maxi_touche_R 790
#define tension_mini_touche_R 750
#define tension_maxi_touche_plus 523
#define tension_mini_touche_plus 463
#define tension_maxi_touche_moins 287
#define tension_mini_touche_moins 245
#byte INTCON = 0x0b //registre des interruptions
#byte PIE1 = 0x8c   //registre contenant les autorisations d'interruptions
#byte PIR1 = 0x0c
#byte ADCON0 = 0x1f  //registre du convertisseur
#byte ADCON1 = 0x9f  //rôle des pins+justification du resultat de la conversion
#byte ADRESH = 0x1e
#byte ADRESL = 0x9e
#byte port_b = 0x06
#byte port_c = 0x07
#bit GO_DONE = ADCON0.2
#bit ADON = ADCON0.0
#bit ADIE = PIE1.6
#bit ADIF = PIR1.6
#define SET_TRIS_A = 0b00001; // PORTA  AN0 entrée et les autres en sortie
#define SET_TRIS_B = 0x00; // PORTB en sortie
#define TMR1IE = PIE1.0
#define TMR1IF = PIR1.0
#bit ADFM_BIT=0x9F.7
#bit PCFG3_BIT=0X9F.3
#bit PCFG2_BIT=0X9F.2
#bit PCFG1_BIT=0X9F.1
#bit PCFG0_BIT=0X9F.0


int16 us;
int16 ADCvaleur;
long int Counter;

void InitialiseADC ()
{
setup_port_a( RA0_ANALOG );
setup_adc( ADC_CLOCK_DIV_8 );
set_adc_channel( 0 );
}

#int_TIMER1
TIMER1_isr()
{
     if(Counter++ == 20000)
        {Counter = 0;
        ADIF = 1;}
}

void main( void )
   {
   long ADCvaleur;

      InitialiseADC();
      ADFM_BIT=1;
      output_high (led1);
      delay_ms(500);
      ADCvaleur = 0;     
      {setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); // at 4MHz clock that is overflow at 20us, so find another crystal?????
      enable_interrupts(int_timer1);
      enable_interrupts(global);
      ADCvaleur = read_ADC();
      while(GO_DONE);
      if (ADCvaleur<=34)
         {
         output_low (led1);
         output_high(led2);
         }
       else
         {
         output_low (led1);
         output_high (led3);
         } 
      while(1)
      {
      ;
      }
   }
   }


At the moment, your interrupt code, doesn't really do anything...
ADIF, is the 'interrupt flag', set when the AD completes it's operation. Setting this doesn't really do anything.
The 'read_adc' operation, allready waits for the ADC to complete (so GO_DONE is also pointless).
Why not just use a higher divider for timer_1. You do not need your 'interval' to be an exact count. Your calculation for 'overflow' time is wrong. The incoming crystal, is divided by 4 internally, then by 8, then by 256 to give the 'overflow'. This is 2048uSec, not 20. To give 2 seconds, requires you to count to 976 (will give 1.998848 seconds).
So code the timer as:
Code:

int1 wait=true;
int16 Counter=976;

#int_TIMER1
TIMER1_isr()
{
     if(Counter) Counter--;
     else wait=false;
}


Then in main, simply wait with:
Code:


while (wait) ;


and then read the ADC.
If you want to keep looping multiple times, then code as:
Code:

while (true) {
    counter=976;
    wait=true;
    while (wait) ;
    ADCvaleur=READ_ADC();
     if (ADCvaleur<=34)
         {
         output_low (led1);
         output_high(led2);
         }
     else
         {
         output_low (led1);
         output_high (led3);
         }
     }

If you want the timing to be dead accurate, use the code posted here in the past, of adding a count to the counter, and then testing for it reaching a limit. Define the added value as a binary multiple of the correct 2 second count, and though there will be a slight oscillation of the sample point (equivalent to one interrupt timeout period), the overall accuracy will be as good as your clock. This was I think originally published by Neutone, in some threads dealing with real time clock applications.

Best Wishes
nfs



Joined: 28 Apr 2004
Posts: 18

View user's profile Send private message

re
PostPosted: Tue May 04, 2004 8:27 am     Reply with quote

this does not work. in fact i want that when i change voltage input a new acquisition takes place and i have a new response from led in output.
i've changed the time of acquisition to become 20s but no response. like the program takes only the first value and this is the new program:
Code:

#include <16F876.h>
/* Set configuration bits in the PIC processor */
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#device adc=10
#device *=16
#use delay (clock=4000000)

#define led1 PIN_A1
#define led2 PIN_A2
#define led3 PIN_A3
#define Vpp 1024
#define Vppmin 973
#define Vss 0
#define Vctq 921
#define tension_maxi_touche_0 34
#define tension_mini_touche_0 0
#define tension_maxi_touche_R 790
#define tension_mini_touche_R 750
#define tension_maxi_touche_plus 523
#define tension_mini_touche_plus 463
#define tension_maxi_touche_moins 287
#define tension_mini_touche_moins 245
#byte INTCON = 0x0b //registre des interruptions
#byte PIE1 = 0x8c   //registre contenant les autorisations d'interruptions
#byte PIR1 = 0x0c
#byte ADCON0 = 0x1f  //registre du convertisseur
#byte ADCON1 = 0x9f  //rôle des pins+justification du resultat de la conversion
#byte ADRESH = 0x1e
#byte ADRESL = 0x9e
#byte port_b = 0x06
#byte port_c = 0x07
#bit GO_DONE = ADCON0.2
#bit ADON = ADCON0.0
#bit ADIE = PIE1.6
#bit ADIF = PIR1.6
#define SET_TRIS_A = 0b00001; // PORTA  AN0 entrée et les autres en sortie
#define SET_TRIS_B = 0x00; // PORTB en sortie
#define TMR1IE = PIE1.0
#define TMR1IF = PIR1.0
#bit ADFM_BIT=0x9F.7
#bit PCFG3_BIT=0X9F.3
#bit PCFG2_BIT=0X9F.2
#bit PCFG1_BIT=0X9F.1
#bit PCFG0_BIT=0X9F.0


int16 us;
int16 ADCvaleur;
int1 wait=true;
int16 Counter=9760;
int i;
void InitialiseADC ()
{
setup_port_a( RA0_ANALOG );
setup_adc( ADC_CLOCK_DIV_8 );
set_adc_channel( 0 );
}


#int_TIMER1
TIMER1_isr()
{
     if(Counter)
     Counter--;
     else wait=false;
}




 void main( void )
    {
    long ADCvaleur;

      InitialiseADC();
      output_high (led1);
      delay_ms(1500);
      ADCvaleur = 0;
      {
       setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // overflow 2048uSec
       enable_interrupts(int_timer1);
       enable_interrupts(global);
         wait=true;
         while (!wait) ;
         ADCvaleur=read_ADC();
            if (ADCvaleur<=34)
               {
               output_low (led1);
               output_high(led2);
               }
               else
                  {
                    output_low (led1);
                    output_high (led3);
                  }
         while(1)
         {
         ;
         }
      }
     }


_________________
nfs
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Tue May 04, 2004 5:37 pm     Reply with quote

Maybe I'm missing something here, but it appears that your code in main() runs only once and then it gets stuck in your while(1) endless loop. That is why you only see one conversion. What you need to do is to put your while(1) around the ADC code, something like this:



Code:

void main( void )
    {
    long ADCvaleur;

      InitialiseADC();
      output_high (led1);
      delay_ms(1500);
      ADCvaleur = 0;
       setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // overflow 2048uSec
       enable_interrupts(int_timer1);
       enable_interrupts(global);
      while(1)                //while needs to be here
      {
         wait=true;
         while (!wait) ;
         ADCvaleur=read_ADC();
            if (ADCvaleur<=34)
               {
               output_low (led1);
               output_high(led2);
               }
               else
                  {
                    output_low (led1);
                    output_high (led3);
                  }
      }
     }
Gerrit



Joined: 15 Sep 2003
Posts: 58

View user's profile Send private message

PostPosted: Wed May 05, 2004 1:16 am     Reply with quote

Hello nfs,

I have askt you some questions in private mail, and if I follow this
discusion I see every time new specs. (at this moment you want only
samples when there is a change on adc) keep in mind 10 bit adc
needs a very stable source to no hope between some bcounts.


1 please first define what you want,
2 make a understandable description of you demants
3 make a description of you problem you encountered
4 than post


I'l think the group will be mutch more helpfull in giving good advice.



kind regards,


gerrit
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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