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

Toggle of PIN C2 and PIN D5

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



Joined: 05 Oct 2011
Posts: 11
Location: South Africa

View user's profile Send private message Yahoo Messenger

Toggle of PIN C2 and PIN D5
PostPosted: Fri Oct 07, 2011 2:35 am     Reply with quote

Hi all,

I have a slight problem regarding the toggling of the PINS above.

Here is what i need to do:

My PWM is setup and half bridge is working. I have a 100 step look up table.

I want P1A to be active during the cycle 0 - 49 and P1B active low.
I want P1B to be active during the cycle 50 - 99 and P1A active low.

Code:

#include<18f4550.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)

BYTE CONST sin_table[100]={99,105,111,118,124,130,135,141,147,152,
                          157,162,167,171,175,179,183,186,189,191,
                      193,195,196,197,198,198,198,197,196,195,
                     193,191,189,186,183,179,175,171,167,162,
                      157,152,147,141,135,130,124,118,111,105,
                     99,93,87,80,74,68,63,57,51,46,41,36,31,
                     27,23,19,15,12,9,7,5,3,2,1,0,0,0,1,2,3,5,
                     7,9,12,15,19,23,27,31,36,41,46,51,57,63,
                     68,74,80,87,93};

BYTE sin_index;
#int_TIMER2
void intrpt_service(void)
{
   sin_index++;
   if(sin_index < 49)
   output_bit( PIN_D5, 0);
   else
   output_bit(PIN_D5, 1);
   if (sin_index > 49)
   output_bit( PIN_C2, 0);
   else
   output_bit( PIN_C2, 1);   
   if(sin_index == 100) sin_index = 0;
   set_pwm1_duty(sin_table[sin_index]);
}

void main(void)
{




sin_index=0;
setup_ccp1(CCP_PWM_HALF_BRIDGE | CCP_PWM_H_H);
setup_timer_2(T2_DIV_BY_1, 199, 1);
enable_interrupts(INT_TIMER2);
enable_interrupts(global);

output_bit( PIN_C2, 0);
set_pwm1_duty(sin_table[sin_index]);

do{
   
}while(TRUE);
   
}


Any ideas what i am doing wrong?

Compiler version 4.093

any help would be much appreciated.

Thanks
Azmat
ünloco



Joined: 02 Oct 2011
Posts: 12
Location: Tunisia

View user's profile Send private message Visit poster's website

PostPosted: Fri Oct 07, 2011 3:59 am     Reply with quote

i have 4.78 and i simulated on isis 7.7 and it worked !

ps:
to make your code a little faster do this ..

Code:

if(sin_index < 49){
   output_low( PIN_D5);
   output_high( PIN_C2);
}   else {
   output_high(PIN_D5);
   output_low( PIN_C2);
}   




use fast_io if needed
_________________
for(;;);
azykazy



Joined: 05 Oct 2011
Posts: 11
Location: South Africa

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Oct 07, 2011 5:40 am     Reply with quote

I tried your way and i am not getting the desired result.

What i need to happen is for 49 cycles P1A must be active and P1B must be zero and from 50 - 99 cycles P1A must be zero and P1B must be active.

I stepped through the code and found that the output_low(PIN D5) event is not happening.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 07, 2011 12:43 pm     Reply with quote

The 18F4550 Half-Bridge pin assignments are:
Quote:

P1A = pin C2
P1B = pin D5
P1C = pin D6
P1D = pin D7

This is from the pinout diagram in the PIC data sheet.

Then in this section of the data sheet, it tells how the pins are used in
Half-Bridge mode:
Quote:

16.0 ENHANCED CAPTURE/COMPARE/PWM (ECCP) MODULE

Half-bridge output:
P1A, P1B (pins C2, D5) modulated with dead-band control;
P1C, P1D (pins D6, D7) assigned as port pins.


In your posted code you have setup the CCP module for hardware
motor control in Half-Bridge mode, with this line:
Code:
setup_ccp1(CCP_PWM_HALF_BRIDGE | CCP_PWM_H_H);

So the CCP will control pins C2 and D5. But then, you ignore this and try
to override it with software PWM of C2 and D5 in your #int_timer2 routine.

Is that allowed ? See this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=38923
azykazy



Joined: 05 Oct 2011
Posts: 11
Location: South Africa

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Oct 07, 2011 2:47 pm     Reply with quote

Hi PCM,

I have read the thread you have posted with regard to what I was trying to accomplish. I see that Ports can only be set if we disable the PWM.

I am using PWM techniques to control MOSFETS. The project is a DC - AC inverter.

I am thinking that i can use the 2 pwm channels available control each side of the mosfet bridge. One channel be active until the program runs through the sine table, then I switch it off and let the 2nd channel run through its own sine table. I can repeat this process continuously.

I am new to working with PWM.

Is there any way or technique I can implement to accomplish my project?

Thank you,
Azmat
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Oct 08, 2011 7:32 pm     Reply with quote

Quote:

I am thinking that i can use the 2 pwm channels available control each
side of the mosfet bridge. One channel be active until the program runs
through the sine table, then I switch it off and let the 2nd channel run
through its own sine table. I can repeat this process continuously.

You can probably do this with software PWM, using interrupts. What is
the required PWM frequency ?
azykazy



Joined: 05 Oct 2011
Posts: 11
Location: South Africa

View user's profile Send private message Yahoo Messenger

PostPosted: Sat Oct 08, 2011 10:46 pm     Reply with quote

The pwm frequency is 5Khz.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Oct 08, 2011 11:29 pm     Reply with quote

5 KHz is a 200 usec period. But you want a resolution of 100 steps per
PWM cycle, which means 2 usec per step. That's too fast for software
PWM. We can't easily interrupt at a 2 usec rate.
So it has to be hardware PWM. You could use the program in this link
as a starting point. It shows how to ramp the hardware PWM duty cycle
up and down in the #int_timer2 isr, which is very similar to what you
need to do:
http://www.ccsinfo.com/forum/viewtopic.php?t=41473&start=3
It changes the PWM duty cycle in the #int_timer2 isr. In that program
it's set to interrupt every 1/8th PWM cycle. You would need to change it
to interrupt every cycle. Also it's setup for 245 Hz PWM frequency.
You would have to change it to 5 KHz. Both of those things can be done
be editing the setup_timer_2() function parameters.

Then in the isr, instead of incrementing and decrementing, read your
value from the table, and use it to set the PWM duty. Increment the table
index and do whatever other house-keeping functions you need to do.

This post has all the links you need for the PWM frequency formula, etc:
http://www.ccsinfo.com/forum/viewtopic.php?t=45968&start=1
azykazy



Joined: 05 Oct 2011
Posts: 11
Location: South Africa

View user's profile Send private message Yahoo Messenger

PostPosted: Sun Oct 09, 2011 3:20 am     Reply with quote

Hi PCM,

PMW frequency i want is 5KHz.

I have used the formula i get the PR2 value to be 199.

Code:

setup_timer_2(T2_DIV_BY_1, 199, 1);


Will the above interrupt at every PWM cycle?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 09, 2011 4:09 pm     Reply with quote

Yes.
azykazy



Joined: 05 Oct 2011
Posts: 11
Location: South Africa

View user's profile Send private message Yahoo Messenger

PostPosted: Tue Oct 11, 2011 6:55 am     Reply with quote

Hi all,

I have been doing research and found out that i can use the FULL Bridge setting to get what i need.

Code:

#int_TIMER2
void intrpt_service(void)
{
   if (forward == 1 && reverse == 0) // forward wave check
   {
   sin_index++;
   setup_ccp1(CCP_PWM_FULL_BRIDGE | CCP_PWM_H_H);
   set_pwm1_duty(sin_table[sin_index]);
   if (sin_index == 49)
      {
      forward = 0; // toggle from forward to reverse
      reverse = 1;
      }
   }
   else
   {
   sin_index--;
   setup_ccp1(CCP_PWM_FULL_BRIDGE_REV | CCP_PWM_H_H);
   set_pwm1_duty(sin_table[sin_index]);
   if (sin_index == 0)
      {
      forward = 1;
      reverse = 0;
      }
   }


As you can see that the program uses a 50 point sine table and once it completes the table it repeats the values in the table in reverse mode. thereby getting my 100 point sine wave.

Forward mode will activate the positive side of the mosfet bridge and the reserve mode will activate the negative side of the mosfet bridge.

thanks guys
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