Пример программы получения трёх фазной ШИМ с использованием микроконтроллера pic18F4431
////////////Исползование ресурсов МК//////////
pic18F4431
PORTA - На ввод РA1-РA2
PA0 -
PA1 - Используим DAC0, подключаем переменный резистор для регулировки частоты
PA2 - Используим DAC1, подключаем переменный резистор для регулировки напряжения
PA3 -
PA4 -
PA5 -
PA6 -
PA7 -
PORTB - На вывод
PB0 - pwm0
PB1 - pwm1
PB2 - pwm2
PB3 - pwm3
PB4 - pwm4
PB5 - pwm5
PB6 -
PB7 -
PORTD - На ввод
PD0 - LED 1
PD1 - LED 2
PD2 - LED 3
PD3 - LED 4
PD4 - Fault
PD5 -
PD6 - KH 1
PD7 - KH 2
*/
#define K_scal 16
#define MAX_THETA 80
#define MAX_PWM 4006 // 0x0A6A = 2666 => fr?quence PWM = 12 kHz
#include "sin_256.h"
#include <built_in.h>
#include <math.h>
float adc_rd;
volatile unsigned int index_sin = 0;
volatile unsigned char index_a_sin = 0;
volatile unsigned char index_b_sin = 56;
volatile unsigned char index_c_sin = 28;
volatile unsigned char temp_8;
volatile unsigned char temp_a;
volatile unsigned char temp_b;
volatile unsigned char temp_c;
volatile unsigned char pol_a = 1;
volatile unsigned char pol_b = 1;
volatile unsigned char pol_c = 0;
volatile unsigned char index_bc_calc = 1;
volatile unsigned char inc_ind = 1;
volatile unsigned int freq_int = 16;
volatile unsigned int amp_sin = 0;
volatile unsigned int amp_task = 0; /
float U;
//****************** Функция амплитуды ********************
void amplituda(void)
{
amp_sin = ((1400/(adc_rd/2)*5)/3);}
//+++++++++++++++++++++++ Прерывание по Т0 ++++++++++++++++++++++++++
void interrupt()
{
LATB6_bit ^= 1; //Выходная частота / 100
TMR0IF_bit = 0; // clear TMR0IF
index_a_sin += inc_ind; // увеличить index_a_sin на 1
if (index_a_sin ==85){index_a_sin=0;};
temp_8 = tab_sin[index_a_sin]*U;
temp_a = temp_8;
index_b_sin += inc_ind; // увеличить index_в_sin на 1
if (index_b_sin ==85){index_b_sin=0;};
temp_8 = tab_sin[index_b_sin]*U;
temp_b = temp_8;
index_c_sin += inc_ind; // увеличить index_с_sin на 1
if (index_c_sin ==85){index_c_sin=0;};
temp_8 = tab_sin[index_c_sin]*U;
temp_c = temp_8;
PDC0H = temp_a;
PDC0L = temp_a;
PDC1H = temp_b;
PDC1L = temp_b;
PDC2H = temp_c;
PDC2L = temp_c;
TMR0L = adc_rd; // display adc_rd[7..0] Изминение частоты 00 мин. FF макс.
TMR0H = 0xFF; //Hi(adc_rd); // display adc_rd[9..8]
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void main() {
// Инициализация портов
TRISA = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1)|(1<<0); // 0,1,2 PORTA на ввод АЦП
TRISB = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0); // PORTB на вывод
TRISC = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0); // PORTC на вывод
TRISD = (0<<7)|(0<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0); // 0-3,5 PORTD на вывод, 4,6,7 на ввод
//====================================================================
// CMCON |= 7; // turn off comparators
ADCON0 |= 0x0C;
ADCON1 |= 0x80; // Set AN2 channel pin as analog
ADCON2 |= 0x00;
TRISA0_bit = 1; // input
T0CON = (1<<7)|(1<<6)|(0<<5)|(0<<4)|(0<<3)|(1<<2)|(0<<1)|(0<<0); //0xC4; Set TMR0 in 8bit mode, assign prescaler to TMR0
// TMR0L = 96; // Timer0 initial value
INTCON = 0xA0;//(1<<7)|(0<<6)|(1<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0); // 0xA0 Enable TMRO interrupt
//====================================================================
// Регистры PTPERH - PTPERL переключения выходной частоты 0FFFH - 0FH.
PTPERH = 0x0D; //Регистр 4 bit
PTPERL = 0x00; //Регистр 8 bit
SEVTCMPH = 0x0F; //Регистр 4 bit 0 - 0F
SEVTCMPL = 0x00; //Регистр 8 bit 0 - F0
//====================================================================
RCON|= (1<<IPEN);
//********************************************************************
PTCON0 = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0); //Бит изменения частоты ШИМ
//********************************************************************
PTCON1|= (0<<PTDIR)|(1<<PTEN);
/*
PTCON1.PTDIR = 0; //1 - Запрет работы ШИМ
PTCON1.PTEN = 1; //1 - разрешаем работу ШИМ, 0 запрещаем
*/
//********************************************************************
PWMCON0 = (0<<7)|(1<<6)|(0<<5)|(0<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0); // 0x48 Разрешаем работу всех шесть ШИМ
PWMCON1 = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(1<<0);
FLTCONFIG = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0);
//*******************************************************************
DTCON = 0x0F; // DTCON регистр мертвого времени ШИМ
//*******************************************************************
T5CON = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(1<<0);
CAP1CON = (0<<7)|(1<<6)|(0<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1)|(1<<0);
DFLTCON = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<3)|(0<<2)|(1<<1)|(0<<0);
//TMR0IF_bit = 0; // clear TMR0IF
//PTMRL = 0xFF;
//PTMRH = 0xF1;
//Delay_ms(3000);
LATC0_bit = 1; // вкл. высокое напряжение
LATD0_bit = 1; // вкл. светодиод работа
while (1)
{
adc_rd = ADC_Read(1)/4; // get ADC value from 0nd channel
U = adc_rd/(amp_sin)/1.8;
if (U >= 5){U = 5;};
amplituda ();
};
}