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

PIC 16F818 Timer 2 Issue

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







PIC 16F818 Timer 2 Issue
PostPosted: Mon Oct 16, 2006 10:46 am     Reply with quote

Code:

/**
*** $Revision: 1.7 $
*** $Date: 2006/06/15 11:45:13 $
*** $Author: nathani $
**/

/*****************************************************************************/
/** Includes and Device Configuration                                       **/
/*****************************************************************************/

#include <16F818.h>
#device adc=10
#use delay(clock=8000000)
#fuses NOWDT,INTRC_IO, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT
#use fast_io(A)
#use fast_io(B)

//#use standard_io(A)
//#use standard_io(B)

/*****************************************************************************/
/** Replacements and Macros                                                 **/
/*****************************************************************************/

#define PIR1               0x0C

#define DIGIT_1            PIN_A6
#define DIGIT_2            PIN_A7
#define DIGIT_3            PIN_A2
#define DIGIT_4            PIN_A4

#define SEGMENT_A          PIN_B4
#define SEGMENT_B          PIN_B6
#define SEGMENT_C          PIN_B0
#define SEGMENT_D          PIN_B2
#define SEGMENT_E          PIN_B3
#define SEGMENT_F          PIN_B5
#define SEGMENT_G          PIN_B7
#define SEGMENT_DOT        PIN_B1

/*****************************************************************************/
/** Global Variables                                                        **/
/*****************************************************************************/

int         i;

/*****************************************************************************/
/* Interrupt Service Routines                                                */
/*****************************************************************************/

/**************************************************************************/
/* Timer 0 Overflow, Read analog inputs                                   */
#int_TIMER2
void control_timer_isr()
{
   bit_clear(*PIR1,1);
}


/*****************************************************************************/
/* Main routine.  Called at power up and reset                               */
/*****************************************************************************/
#zero_ram
void main()
{

   //restart_wdt();

   setup_adc_ports(RA0_RA1_ANALOG_RA3_REF);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(FALSE);
   setup_counters(RTCC_INTERNAL,WDT_576MS);
   setup_oscillator(OSC_8MHZ);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_4,0,1);         //1,953Hz timer or 500us timer

   enable_interrupts(INT_TIMER2);
   enable_interrupts(global);

   SET_TRIS_A(00101011);
   SET_TRIS_B(00000000);

   output_low(DIGIT_1);
   output_low(DIGIT_2);
   output_low(DIGIT_3);
   output_low(DIGIT_4);
   output_high(SEGMENT_A);
   output_high(SEGMENT_B);
   output_high(SEGMENT_C);
   output_high(SEGMENT_D);
   output_high(SEGMENT_E);
   output_high(SEGMENT_F);
   output_high(SEGMENT_G);
   output_high(SEGMENT_DOT);

   bit_clear(*PIR1,1);

   do //Main program loop
   {
      i++;

      switch(i)

      {
         case 1:
            output_high(DIGIT_2);
            output_low(SEGMENT_A);
            output_high(SEGMENT_DOT);
            break;

         case 2:
            output_high(DIGIT_2);
            output_low(SEGMENT_B);
            output_high(SEGMENT_A);
            break;

         case 3:
            output_high(DIGIT_2);
            output_low(SEGMENT_C);
            output_high(SEGMENT_B);
            break;

         case 4:
            output_high(DIGIT_2);
            output_low(SEGMENT_D);
            output_high(SEGMENT_C);
            break;

         case 5:
            output_high(DIGIT_2);
            output_low(SEGMENT_E);
            output_high(SEGMENT_D);
            break;

         case 6:
            output_high(DIGIT_2);
            output_low(SEGMENT_F);
            output_high(SEGMENT_E);
            break;

         case 7:
            output_high(DIGIT_2);
            output_low(SEGMENT_G);
            output_high(SEGMENT_F);
            break;


         case 8:
            output_high(DIGIT_2);
            output_low(SEGMENT_DOT);
            output_high(SEGMENT_G);
            break;

         case 9:
            i = 0;
            break;
      }

      delay_ms(250);

   } while (TRUE);

} // main()


Above is my code. I have been working with 18F's for a little while now, but I’ve been asked to build and analog reader that displays on a 7 seg display, so I thought an 18F would be overkill (stupid me, should spend the extra 1$ and work with what I know) and chose a 16F818. I'm in early development and I can't seem to get it to work. I can get the main loop to run but only if I disable timer2. The weird thing is that I can't get the ICD to program it once I disable timer2 unless I drop the system voltage down to about 3V. The code above does not display anything on the 7 seg but will program with the ICD normally. I'm at my whit's end with this thing and any help would be much appreciated.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 16, 2006 12:15 pm     Reply with quote

I don't have a 16F818 to test. I do have a 16F88, which is a similar PIC.
I stripped down your code, to make the short test program shown below.
It works. On Pin B0, I see a 15.2 KHz square wave on the oscilloscope.

I suggest that you take this code, change only the #include statement
to a 16F818.H and see if it works.
Code:

#include <16F88.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay (clock=8000000)

#int_timer2
void control_timer_isr()
{
output_toggle(PIN_B0);
}

//==============================
void main()
{

setup_timer_2(T2_DIV_BY_4, 0, 1);     
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);

while(1);
}
Nathan
Guest







PostPosted: Mon Oct 16, 2006 1:38 pm     Reply with quote

Sorry guys I forgot to mention that I am using the internal clock on the 16F818. I have been reviewing the data sheet and Timer2 doesn't appear to be selectable in this mode (must be drive from external clock). I'm going to try timer0 and get back to you.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 16, 2006 1:51 pm     Reply with quote

Quote:

Sorry guys I forgot to mention that I am using the internal clock on the
16F818. I have been reviewing the data sheet and Timer2 doesn't
appear to be selectable in this mode (must be drive from external
clock). I'm going to try timer0 and get back to you.

Where do you see this in the data sheet ?

In section 8.0 TIMER2 MODULE, the data sheet says this,
in the 2nd paragraph:
Quote:

The input clock (FOSC/4) has a prescale
option of 1:1, 1:4 or 1:16, selected by
control bits, T2CKPS1:T2CKPS0 (T2CON<1:0>).

It's driven by Fosc/4, which is completely normal for PICs.
It doesn't say anything about only using an external clock.


Quote:

The weird thing is that I can't get the ICD to program it once I disable
timer2 unless I drop the system voltage down to about 3V.

This shouldn't be happening. My feeling is that there is something
wrong with your external circuits. The MCLR circuit may not be
correct. Some external circuit may be supplying power to the PIC
through an i/o pin, unintentionally. (Via the upper protection diode).
My suggestion is, strip away most of the external circuits, except for
a pullup resistor on MCLR (10K for ICD2, or 47K for CCS ICD), and
also a 100 nF capacitor (0.1 uF) on the Vdd pin, and then run the
program I posted above.

If you can't get it to work after doing that, then post your compiler
version.
Natahn
Guest







PostPosted: Mon Oct 16, 2006 3:32 pm     Reply with quote

Code:

#include <16F818.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay (clock=8000000)

#define DIGIT_1            PIN_A6
#define DIGIT_2            PIN_A7
#define DIGIT_3            PIN_A2
#define DIGIT_4            PIN_A4

#define SEGMENT_A          PIN_B4
#define SEGMENT_B          PIN_B6
#define SEGMENT_C          PIN_B0
#define SEGMENT_D          PIN_B2
#define SEGMENT_E          PIN_B3
#define SEGMENT_F          PIN_B5
#define SEGMENT_G          PIN_B7
#define SEGMENT_DOT        PIN_B1

#int_timer2
void control_timer_isr()
{
   output_toggle(PIN_B0);
}

//==============================
void main()
{

   output_low(DIGIT_1);
   output_low(DIGIT_2);
   output_low(DIGIT_3);
   output_low(DIGIT_4);
   output_high(SEGMENT_A);
   output_high(SEGMENT_B);
   output_high(SEGMENT_C);
   output_high(SEGMENT_D);
   output_high(SEGMENT_E);
   output_high(SEGMENT_F);
   output_high(SEGMENT_G);
   output_high(SEGMENT_DOT);

   setup_timer_2(T2_DIV_BY_4, 0, 1);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);

while(1);
}


Ok so this appears to be operating fine. All my pins are as they should be and the BO pin is oscillating (I didn't check it with a scope (don't have one here), but my meter reads a non zero AC voltage and about 2.5 VDC.

This is with my existing circuitry (didn't strip it down).
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 16, 2006 4:41 pm     Reply with quote

My advice is to slowly add the important parts of your program back
into the working program.

There are some things in your code that could be improved:

1. You don't need to use #fast_io, at least not initially. Because you're
using CCS pin i/o functions, the compiler will automatically set the
correct TRIS for you. You therefore don't need the set_tris()
statements.

2. In your original code, you had the #use delay() statement above
the #fuses statement. Notice that in my test program, it's placed
below the #fuses line. That way, the compiler will automatically
put in code to setup the oscillator for the correct speed. You don't
need the setup_oscillator() statement.

3. You don't need to manually turn off the Timer2 interrupt flag inside
the isr. The compiler automatically inserts code to do this.

4. Inside your main() code, you are clearing the Timer2 interrupt flag.
CCS has a function to do this: clear_interrupt(INT_TIMER2);

5. You don't need to turn off the spi module in main(). It's 'off' by
default, upon power-on reset.

6. Normally a little variable like 'i' would be local to main(). It wouldn't
be declared globally.
Nathan
Guest







PostPosted: Mon Oct 16, 2006 4:43 pm     Reply with quote

Ok so I went out and found myself a scope. I indeed have a square wave. Period is about 62.6 us. About 16KHz.
Nathan
Guest







PostPosted: Mon Oct 16, 2006 5:03 pm     Reply with quote

Okk... I'm trying to tune the timer2 to be more the frequency i'm looking for. I would like about 500us. I've tried
setup_timer_2(T2_DIV_BY_1, 0, 1);
setup_timer_2(T2_DIV_BY_4, 0, 1);
setup_timer_2(T2_DIV_BY_16, 0, 1);

and RBO comes out with the same frequency every time.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 16, 2006 5:25 pm     Reply with quote

You need to change the PR2 value to be something other than 0.
This is the middle parameter in the setup_timer_2() function.

Set it to 128 initially, and then you can experiment by changing
it to higher or lower values later. With a PR2 value of 128, you
can change the prescaler and notice the change in frequency.
Nathan
Guest







PostPosted: Mon Oct 16, 2006 5:34 pm     Reply with quote

Ok, that makes sense. Thanks
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