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

interrupt timer0 and timer1 in 18F4431

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



Joined: 22 May 2013
Posts: 18

View user's profile Send private message Send e-mail Yahoo Messenger

interrupt timer0 and timer1 in 18F4431
PostPosted: Fri Nov 22, 2013 8:19 am     Reply with quote

Hello
I use 18F4431 to read ADC and control RC servo motor. I have problem in interrupt timer0 and timer1. INT_RTCC work properly while INT_TIMER1 no run. INT_RTCC to set time for read ADC, and INT_TIMER1 generate the pulse to control RC servo.
This is my code

#include <Slave.h>
#include <math.h>
#include <RS232_Master.c>
#include <Read_ADC.c>
#include <RCservo.c>
#priority timer1,timer0,ssp,ext,ext1,ext2 //uu tien ngat theo thu tu
#include <I2C_Slave.c>
////////////RC servo////////////////
//Left Limit: duty = 251
//Right Limit: duty = 500
/////RC
#define BOT_VALUE=1000,TOP_VALUE=2000,MAX_VALUE=20000;//BOT_VALUE=10,TOP_VALUE=20,MAX_VALUE=200
int16 dem1,dem2;
int16 RC_duty;
////////////////////////////////////
int16 duty_1=0,duty_2=0,duty_3=0;
int16 count=0;
float angle_zx, angle_zy;
//Function///////////////////////////////
void lcd_number1(float number);
void lcd_number2(float number);
void lcd_number3(float number);
//INTERRUPT
#INT_RTCC
void interrupt_timer0()
{
count++;
if(count=152)//0.5s
{
count=0;
//AN1
set_adc_channel(1);
ReadADC_Init();
adc_1 = read_adc();
//RS232_Float(adc_1);

//AN2
set_adc_channel(2);
ReadADC_Init();
adc_2 = read_adc();
//RS232_Float(adc_2);

//AN3
set_adc_channel(3);
ReadADC_Init();
adc_3 = read_adc();
//RS232_Float(adc_3);
}
}
#INT_TIMER1
void ngat_timer1()
{
dem2++;
if(dem2==65535)
{
dem2=0;
RS232_Float(adc_1);
}
set_timer1(65530);
dem1++;
if (dem1==RC_duty)
{
output_low(pin_c0);
}
if (dem1==MAX_VALUE)
{
dem1=0;
output_high(pin_c0);
}

}
void main()
{
//Set tris port
set_tris_b(0x00);
set_tris_c(0x00);
//Khoi tao ngat
enable_interrupts(INT_RTCC);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);

//Set up ADC
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN0|sAN1|sAN4|VSS_VDD);

//Set up power pwm
// Setup the 4 Power PWM channels as ordinary pwm channels.
setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);

// Mode = Free Run
// Postscale = 1 (1-16) Timebase output postscaler
// TimeBase = 0 (0-65355) Initial value of PWM Timebase
// Period = 2000 (0-4095) Max value of PWM TimeBase
// Compare = 0 (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time
setup_power_pwm(PWM_CLOCK_DIV_4|PWM_FREE_RUN,//modes
1, //postscale
0, //time_base
249, // Period // tan so la 5Khz, full duty = 1000
0, //compare
1, //compare_postscale
0); //dead_time
set_power_pwm0_duty(1000);
set_power_pwm2_duty(1000);
set_power_pwm4_duty(1000);

output_high(pin_b0);
output_high(pin_b2);
output_high(pin_b5);

//RC servo
RC_duty=1500;
output_high(pin_c0);

//Timer0
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);//old:64
set_timer0(0);//old:0

//TIMER 1 : behind all setup fucntions
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(65530); //0.1us
while(1)
{
}
}

I hope someone can help me to find error.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Fri Nov 22, 2013 8:29 am     Reply with quote

1) Learn to use the code buttons....
2) Lumps are missing. ReadADC_Init?. RS232_Float();
3) Is ADC_CLOCK_ITERNAL legal at your clock rate?.
4) The approach is fundamentally flawed. The ADC takes 13 cycles of it's clock to perform a conversion, and requires the internal capacitor to be charged to the external voltage for quite a few uSec, before a conversion can be started. You _do not_ want to be doing this inside an interrupt. Use a state machine. Select the channel. Exit the interrupt. Next interrupt, start the conversion, exit the interrupt. Then on the next interrupt read the result. Let the hardware get on and do it's jobs in the time between interrupts, don't wait for this to happen inside the interrupt....
5) then the same applies in the next timer. I'm guessing that RS232_Float involves writing a float to the RS232?. If so, forget it. First float maths is appallingly slow. Then you don't want to be waiting for RS232 transmission to occur in the interrupt. Set a flag, and do these operations in the main code.

Repeat the mantra fifty times _keep interrupt handlers as quick as possible_.
jemmyduc



Joined: 22 May 2013
Posts: 18

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Fri Nov 22, 2013 9:51 am     Reply with quote

Thank you for your reply
ReadADC_Init() is a function to waiting for interrupt flag of ADC transfer and RS232_Float() is a function i wrote to send float data by RS232. And those work properly. But i think you right.
My main problem is INT_TIMER1
Code:

#INT_TIMER1 HIGH
void interrupt_timer1()
{
   set_timer1(65530);//1us
   dem1++;
   if (dem1==RC_duty)
   { 
      output_low(pin_c0);
   }
   if (dem1==MAX_VALUE)
   {
      dem1=0;
      output_high(pin_c0);
   }
}

This code don't work any more. I checked it.
I try to add the priority for interrupt timer1. But it still has not work.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 22, 2013 1:48 pm     Reply with quote

Quote:
My main problem is INT_TIMER1

#INT_TIMER1 HIGH
void interrupt_timer1()
{
set_timer1(65530);//1us
dem1++;
if (dem1==RC_duty)
{
output_low(pin_c0);
}
if (dem1==MAX_VALUE)
{
dem1=0;
output_high(pin_c0);
}
}


I assume you're running the PIC at 20 MHz. You can't get a 1 usec
interrupt rate. Your code inside the isr takes much longer than that
to run. The isr has hidden code to save registers before entering your
routine above, and to also restore registers after exiting your routine.
You need to think of a new program design that doesn't need a 1 usec
interrupt rate.
jemmyduc



Joined: 22 May 2013
Posts: 18

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Fri Nov 22, 2013 5:54 pm     Reply with quote

Thank PCM programer
I will change my code, You can guide me to set 1us, I cant use delay(). Because I want to control RC servo motor
Thank you so much again
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 22, 2013 7:27 pm     Reply with quote

You want to control an RC servo. These units normally are given a
pulse between 1 and 2 ms, with 1.5ms pulse as the idle state.
Why do you think you need 1us resolution ?

There is some code in this thread for higher resolution (but not 1us).
It uses the CCP1 module in the PIC:
http://www.ccsinfo.com/forum/viewtopic.php?t=44328
jemmyduc



Joined: 22 May 2013
Posts: 18

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Fri Nov 22, 2013 7:35 pm     Reply with quote

Because i want to have a controlling range from 100 to 200 with period is 20000.
Thank for your reply. i trying to do follow the link you give me
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 22, 2013 7:41 pm     Reply with quote

I assume you mean 20000 is the 20000us (20ms) period for the pulses.
But where do you get the "100 to 200" from ? The pulse will be 1000us
to 2000us (1ms to 2ms) in duration. Not 100 to 200us.

Read this page here. It has a timing diagram of servo pulses:
http://www.helifreak.com/showthread.php?t=263175
jemmyduc



Joined: 22 May 2013
Posts: 18

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Fri Nov 22, 2013 9:01 pm     Reply with quote

I got it and i make a correct control.
Thank you again.
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