|
|
View previous topic :: View next topic |
Author |
Message |
fach
Joined: 02 Apr 2015 Posts: 2
|
PIC18F4431 Motor control code help |
Posted: Thu Apr 02, 2015 4:49 am |
|
|
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: 9270 Location: Greensville,Ontario
|
|
Posted: Thu Apr 02, 2015 5:03 am |
|
|
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
|
|
Posted: Thu Apr 02, 2015 5:35 am |
|
|
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: 1358
|
|
Posted: Thu Apr 02, 2015 6:08 am |
|
|
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
|
Re: PIC18F4431 Motor control code help |
Posted: Thu Apr 02, 2015 6:35 am |
|
|
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 |
|
|
|
|
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
|