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 support@ccsinfo.com

pic18f46k22 counter using timer and interrupt

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



Joined: 29 May 2012
Posts: 5

View user's profile Send private message

pic18f46k22 counter using timer and interrupt
PostPosted: Tue May 29, 2012 7:47 am     Reply with quote

Hi all!

I need some help - I need to write a counter of 20 sec,

I wrote this for the interrupt:


#include <18f46k22.h>

#fuses INTRC_IO,NOMCLR,PUT,NOWDT,XINST,LVP

#use delay(clock=16000000) //16MHz

void interrupt() {
TMR1H=0xEC;
TMR1L=0x78;
PIR1=1;
}

But the compiler (mplab) didn't recognize it.

What's missing? some fuses?

Thanks a lot for the help.

Miri
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue May 29, 2012 8:03 am     Reply with quote

Just to clear things up, which compiler are you using? MPLAB is not a compiler but an IDE from which you can use many compilers like CCS, Microchip, High Tech and others.

This forum is for support on the CCS compiler, when you are using another compiler go to their website.

Code:
void interrupt() {
TMR1H=0xEC;
TMR1L=0x78;
PIR1=1;
}
This is not CCS code, I suspect you are using another compiler...

Just in case I'm wrong and you are using CCS:
- What is your compiler version number?
- XINST fuse can not be used with the CCS compiler
- Change LVP to NOLVP. The last 10 years I've never met anyone using a Low Voltage Programmer.
- Post a small but complete program.
miripek



Joined: 29 May 2012
Posts: 5

View user's profile Send private message

I use a ccs compiler
PostPosted: Tue May 29, 2012 8:13 am     Reply with quote

What should be the code then?
_________________
miri
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue May 29, 2012 8:46 am     Reply with quote

Assuming that you ARE using the CCS compliler:-

You replace
Code:
TMR1H=0xEC;
TMR1L=0x78;

with
Code:
set_timer1(0xEC78);


Your code
Code:
PIR1=1;

MIGHT try to set the timer1 interrupt flag with a different compiler, and would be nonsense. Since the timer1 overflow normally sets this flag and the ISR clears it.


If you really must operate directly on the PICs registers, you often have to tell the compiler what their addresses are, but it's NOT the easy way to go.


I recommend you read the CCS manual. CCS also supplies loads of code to show you how to do most things.

Mike
miripek



Joined: 29 May 2012
Posts: 5

View user's profile Send private message

I tried to write this code
PostPosted: Tue May 29, 2012 11:11 pm     Reply with quote

Code:

output_high(pin_E1);

disable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
enable_interrupts(GLOBAL);
while(1);
output_low(pin_E1);

should it work as a counter? How can I set a counter for 5 sec?
_________________
miri
miripek



Joined: 29 May 2012
Posts: 5

View user's profile Send private message

HERE IS THE FULL CODE - SO FAR
PostPosted: Tue May 29, 2012 11:53 pm     Reply with quote

I have to do a count - delay of 1 min, or 5 min, a delay that won't stop all program.
What is missing in my code?
Code:

#include <18f46k22.h>
#fuses INTRC_IO,NOMCLR,PUT,NOWDT,NOLVP
#use delay(clock=16000000)   //16MHz

void interrupt() {
set_timer1(0xFFFF);   //set TMR1H and TMR1L
}

void main() {
setup_adc( ADC_OFF );
set_tris_a(0x00); // A5 A4 A3 A2 A1 A0 - SOLENOID (OUTPUT)
set_tris_b(0xF0); // B7 B6 B5 B4 - SWITCHES (INPUT) // B3 B2 B1 B0 - LCD (OUTPUT)
set_tris_c(0x00); // C7 C6 C5 C4 C3 C2 C1 C0 - SOLENOID (OUTPUT)
set_tris_d(0x3F); //  D7 D6 - SOLENOID (OUTPUT) D5 D4 D3 D2 D1 D0 - SWITCHES (INPUT)
set_tris_e(0x0C); // E3 E2 - SWITCHES (INPUT) E1 E0 - SOLENOID (OUTPUT)

while(1) {
  if (input(pin_E2)==1)
   {
      output_low(pin_A0);      output_low(pin_A1);         output_low(pin_A2);         output_low(pin_A3);
      output_low(pin_A4);      output_low(pin_A5);         output_low(pin_D6);         output_low(pin_D7);
      output_low(pin_C0);      output_low(pin_C1);         output_low(pin_C2);         output_low(pin_C3);
      output_low(pin_C4);      output_low(pin_C5);         output_high(pin_C6);      output_low(pin_C7);
      output_low(pin_E0);      output_low(pin_E1);

      disable_interrupts(GLOBAL);
      enable_interrupts(INT_TIMER1);
      setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
      enable_interrupts(GLOBAL);
      while(1);
      
      output_low(pin_A0);      output_low(pin_A1);         output_low(pin_A2);         output_low(pin_A3);
      output_low(pin_A4);      output_low(pin_A5);         output_low(pin_D6);         output_low(pin_D7);
      output_low(pin_C0);      output_low(pin_C1);         output_low(pin_C2);         output_low(pin_C3);
      output_low(pin_C4);      output_low(pin_C5);         output_low(pin_C6);         output_low(pin_C7);
      output_low(pin_E0);      output_low(pin_E1);      
      
   }   

}
}

_________________
miri
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Wed May 30, 2012 1:53 am     Reply with quote

As shown, you will never leave the timer interrupt.
The timer counts upwards. The interrupt occurs when the timer wraps from FFFF, to 0000. You are setting the timer to FFFF in the interrupt, so the wrap will occur on the very next count. You are setting the timer to run at the instruction rate, so the interrupt will trigger one instruction later, putting you straight back into the interrupt.....

Best Wishes
miripek



Joined: 29 May 2012
Posts: 5

View user's profile Send private message

And if I change the internal code to:
PostPosted: Wed May 30, 2012 2:00 am     Reply with quote

disable_interrupts ( GLOBAL );
setup_timer_0 ( RTCC_DIV_128 | RTCC_INTERNAL );
set_timer0 ( 61 );
enable_interrupts (INT_RTCC);
enable_interrupts (GLOBAL);
do{
output_low(pin_A0); output_low(pin_A1); output_low(pin_A2); output_low(pin_A3);
output_low(pin_A4); output_low(pin_A5); output_low(pin_D6); output_low(pin_D7);
output_low(pin_C0); output_low(pin_C1); output_low(pin_C2); output_low(pin_C3);
output_low(pin_C4); output_low(pin_C5); output_low(pin_C6); output_low(pin_C7);
output_low(pin_E0); output_low(pin_E1);
}while(true);

it still doesn't work.

Thanks all for your help,
_________________
miri
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed May 30, 2012 2:23 am     Reply with quote

You're using the internal oscillator.

This line does NOT set the frequency to 16MHz.
Code:

#use delay(clock=16000000) //16MHz

You have to use the setup_oscillator for that.

I don't have your chip but this code will generate timings for you.
Code:
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)

int16 tick_count;

#int_timer2
void tick_advance()
{ tick_count++; }

void main()
{
  setup_timer_2(T2_DIV_BY_4,249,1);
  enable_interrupts(int_timer2);
  enable_interrupts(global);

  tick_count = 0 ;
  output_high(PIN_B0);
  while (tick_count < 1000) {}
  output_low(PIN_B0);

  tick_count = 0 ;
  output_high(PIN_B1);
  while (tick_count < 1000) {}
  output_low(PIN_B1);

  while (1) {}
}

You should be able to adapt it for your device.
I'm using MPLAB and an external crystal module.
I've used a PIC16F877 because it was to hand and happened to be plugged into my PICDEM 2 PLUS board.
The board has LEDs connected to B0...B3.
The code turns on B0, B1 for 1 second each, then stops.

Main() sets up the timer2 to overflow at 1ms intervals with a 4MHz clock.
The Timer2 interrupt advances the tick_count every 1ms.
Main() then monitors the tick_count to control the timing of everything else.
Main() can of course do other things whilst it monitors the tick_count. That's up to you.
The modification to minutes etc is your homework project.
You can of course use any of the other timers with some adjustment.
Timer2 is often used as a PWM clock so may not be available.


Mike
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