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

PIC18F4431 Motor control code help

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



Joined: 02 Apr 2015
Posts: 2

View user's profile Send private message

PIC18F4431 Motor control code help
PostPosted: Thu Apr 02, 2015 4:49 am     Reply with quote

Hi, I am trying to drive a 3 phase induction motor, with the pic18f4431 pic with mikroC.

This is my code, I have the 6 complementary pwms but i can't seem to be able to change the dutycycle using the potentiometer and i can't seem to be able to show the value of the adc on the LCD. I don't really know what's wrong. Some help would be awesome.

Here is my code:


Code:

/*
*PWM
* 3 phase ac induction motor control
*/
// Global Declarations

#include "LCDdrive.h"

char table_offset0, table_offset1, table_offset2, i;
bit offset_update0, offset_update1, offset_update2, tmr0_flag, adc_flag;
unsigned int sineval0, sineval1, sineval2, adc_rd;
/*
Set up the power control PWM so that:
1)PWM Time Base Postscale = 1:1
2)PWM Time Base Prescale = Fosc/4 (1:1)
3)PWM is in free-running mode
4)PWM Time Base is enabled
5)PWM Time Base counts up
6)PWM0-5 are enabled as output
7)Enabled PWM channels are set as complementary
8)PWM Special event trigger postscale = 1:1
9)PWM Special event trigger is counting up
10)PWM updates are enabled
11)PWM output override is synchronised
12)Deadtime of 1us
13)PWM output is controlled by duty cycle register
14)All fault conditions are disabled
15)PWM frequency = 15KHz
16)PWM resolution = 10
17)Maximum duty cycle = 4*PTERH:L = 1328
*/
void pwm_init ()
{
 PTCON0 = 0x00;
 PTPERL = 0x4C;
 PTPERH = 0x01;
 PWMCON0 = 0x40;
 PWMCON1 = 0x01;
 DTCON = 0x0A;
 OVDCOND = 0xFF;
 SEVTCMPH:SEVTCMPL = 0x00;
 PTCON1 = 0x80;
 FLTCONFIG = 0x00;
 OVDCONS = 0x00;
}

/*
Define the sine look up table for values of 90° to 270° in increments of 5°.
This information will be assigned to the duty cycle of the PWM.
*/
const int sinetable[37] =
{
0x530, 0x52D, 0x526, 0x519, 0x508, 0x4F2, 0x4D7, 0x4B8, 0x495, 0x46E,
0x443, 0x415, 0x3E4, 0x3B1, 0x37B, 0x344, 0x30B, 0x2D2, 0x298, 0x25E,
0x225, 0x1EC, 0x1B5, 0x17F, 0x14C, 0x11B, 0x0ED, 0x0C2, 0x09B, 0x078,
0x059, 0x03E, 0x028, 0x017, 0x00A, 0x003, 0x000 };

/*
Set up the AD converter so that:
1)Continuous loop mode is enabled
2)Single channel mode enabled
3)Group A is taken and convertered
4)Begin the ADC cycle
5)Turn on the ADC
6)Vref+ = AVdd and Vref-=AVss
7)FIFO is enabled
8)AD results have not overflowed
9)Buffer pointer set at 0
10)AD results left justified
11)Acquisition time 12TAD
12)Conversion clock at Fosc/32
13)Interrupt generated at 2nd and 4th
14)External triggers disabled
15)Group A input is AN0
16)Set AN0 to analogue input
*/
void init_adc()
{
 ADCON0 = 0x23;
 ADCON1 = 0x18;
 ADCON2 = 0x32;
 ADCON3 = 0xC0;
 ADCHS = 0x00;
 ANSEL0 = 0x01;
 TRISA = 0x01;
 ANSEL1 = 0x02;
}
/*
Set up timer 0 so that:
1)Timer 0 enabled
2)Configure to 16bit
3)Internal Clock Source
4)Increment on low-to-high transition
5)Assign timer 0 prescaler as 1:256
6)set value to replicate 1Hz
*/
void tmr0_init ()
{
T0CON = 0x87;
TMR0H:TMR0L = 0xFEF0;
}

/*
Configure the interrupts so that:
1)Enable high priority interrupts
2)Enable low priority interrupts
3)Enable Timer 0 interrupt
4)Make timer 0 interrupt high priority
5)Enable AD Interrupt
6)Make AD interrupt low priority
7)Enable priority levels for interrupt
*/
void inter_init()
{
INTCON = 0xE4;
INTCON2.TMR0IP = 1;
RCON = 0x93;
PIE1.ADIE = 1;
IPR1.ADIP = 0;
}

/*
Update the PWM duty cycle by cycling through the values within the sine table.
*/
void update_pwm0()
{
 if (offset_update0 == 1)
    {
     table_offset0++;
      if (table_offset0 >= 37)
      {
        table_offset0--;
        offset_update0 = 0;
      }
    }
    else
    {
        table_offset0--;
      if (table_offset0 <= 0 )
         {
        table_offset0++;
        offset_update0 = 1;
        }
    }
}

/*
Update the PWM duty cycle by cycling through the values within the sine table.
*/
void update_pwm1()
{
 if (offset_update1 == 1)
    {
     table_offset1++;
      if (table_offset1 >= 37)
      {
        table_offset1--;
        offset_update1 = 0;
      }
    }
    else
    {
        table_offset1--;
      if (table_offset1 <= 0 )
         {
        table_offset1++;
        offset_update1 = 1;
        }
    }
}

/*
Update the PWM duty cycle by cycling through the values within the sine table.
*/
void update_pwm2()
{
if (offset_update2 == 1)
    {
     table_offset2++;
      if (table_offset2 >= 37)
      {
        table_offset2--;
        offset_update2 = 0;
      }
    }
    else
    {
        table_offset2--;
      if (table_offset2 <= 0 )
         {
        table_offset2++;
        offset_update2 = 1;
        }
    }
}

/*
High priority interrupt. When timer 0 interrupt flag is set, remove flag and set variable tmr0_flag to 1.
This allows the main program to update the duty cycle on each overflow.
*/
void interrupt()
{
  if (INTCON.TMR0IF == 1)
  {
    TMR0H:TMR0L = 0xFEF0;
    tmr0_flag = 1;
    INTCON.TMR0IF = 0;
  }
}

/*
Low priority interrupt. When the ADC flag is set, remove flag, read ADC value and set variable adc_flag to 1.
This allows the main program to use the new ADC value.
*/
void interrupt_low()
{
   if (PIR1.ADIF == 1)
  {
   adc_rd = adc_read(1);
   adc_flag = 1;
   PIR1.ADIF = 0;
  }
}

/*
Set the table offset so that each PWM is 120° apart.
*/
void init()
{
 table_offset0 = 19;
 offset_update0 = 0;
 table_offset1 = 7;
 offset_update1 = 1;
 table_offset2 = 31;
 offset_update2 = 1;
 tmr0_flag = 0;
 adc_flag = 0;
}

/*
Load the new duty cycle values to the duty cycle registers.
This is done by reading the designated value from the sine table and loading them to the required high and low registers.
Load the 8 LSB to PDC*L, shift the value 8 bits right and load the new value to PDC*H.
*/
void update_dutycycle()
{
    sineval0 = sineTable[table_offset0];
    sineval1 = sineTable[table_offset1];
    sineval2 = sineTable[table_offset2];

    PDC0L = sineval0 & 0xFF;
    PDC0H = sineval0 >> 8;
    PDC1L = sineval1 & 0xFF;
    PDC1H = sineval1 >> 8;
    PDC2L = sineval2 & 0xFF;
    PDC2H = sineval2 >> 8;
}

/*
Initiate all the required subroutines.
Within an endless loop, when the tmr0_flag is set (when timer 0 overflows),
load the new values into the duty cycle register, then update the table offsets.
When the adc_flag is set (when a new ADC value is received), use the LEDs on PORT D
and PORT C to show the new value.
*/
void main ()
{
    PORTA = 255;
    TRISA = 255;                        // Configure PORTA pins as input
    PORTB = 0;                          // Set PORTB to 0
    TRISB = 0;                          // Designate PORTB pins as output
    PORTC = 0;                          // Set PORTC to 0
    TRISC = 0;                          // Designate PORTC pins as output
    PORTD = 0;
    TRISD = 0;
    PORTC = 0;
    TRISC = 0;
    pwm_init();
    tmr0_init();
    inter_init();
    init();
    init_adc();
    LCD_initialise();
    LCD_cursor(0,0);
    LCD_putsc("AC INDUCTION MOTOR");


while (1)
{
    if (tmr0_flag = 1)
    {
    update_dutycycle();
    update_pwm0();
    update_pwm1();
    update_pwm2();
    tmr0_flag = 0;
    }
    if (adc_flag = 1)
    {
     PORTD = adc_rd;
     PORTC = adc_rd << 8;
     adc_flag = 0;
    }
    LCD_cursor(0,0);
    LCD_display_value(adc_rd);
}
}


thanks in advance
temtronic



Joined: 01 Jul 2010
Posts: 9176
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Apr 02, 2015 5:03 am     Reply with quote

This is a CCS C compiler forum, please ask MikroC compiler questions on HIS forum, not here.

It's like asking Rolls-Royce how to fix a Volkswagon.

Jay
fach



Joined: 02 Apr 2015
Posts: 2

View user's profile Send private message

PostPosted: Thu Apr 02, 2015 5:35 am     Reply with quote

Hi,

Any forums you could suggest? I can't seem to find any useful ones, i figured maybe someone here could know about mikroC by chance.

FACH
jeremiah



Joined: 20 Jul 2010
Posts: 1329

View user's profile Send private message

PostPosted: Thu Apr 02, 2015 6:08 am     Reply with quote

a quick google search for "mikroc forum" brings up the company forum:
http://www.mikroe.com/forum/

I would start there and see what you can get (or even see if they have a tech support line).
Mike Walne



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

View user's profile Send private message

Re: PIC18F4431 Motor control code help
PostPosted: Thu Apr 02, 2015 6:35 am     Reply with quote

fach wrote:
Hi, I am trying to drive a 3 phase induction motor, with the pic18f4431 pic with mikroC.

This is my code, I have the 6 complementary pwms but i can't seem to be able to change the dutycycle using the potentiometer and i can't seem to be able to show the value of the adc on the LCD. I don't really know what's wrong. Some help would be awesome.

thanks in advance

This thread will soon be locked.
You seem to have lots of problems.
Break the code down into easily managed bite size chunks.
Deal with each section, until you've got it to work, then move on.

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