main.c


1
#include <xc.h>
2
3
// CONFIG1
4
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
5
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
6
#pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
7
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
8
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
9
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
10
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
11
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
12
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
13
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
14
15
// CONFIG2
16
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
17
#pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
18
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
19
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
20
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
21
22
23
#define _XTAL_FREQ 32000000
24
25
const unsigned int sin_tab[250]={512,524,537,550,563,576,588,601,614,626,639,651,664,676,688,700,712,724,735,747,758,769,780,791,802,812,823,833,843,852,862,871,880,889,898,906,914,922,929,937,944,951,957,963,969,975,980,985,990,994,998,1002,1006,1009,1012,1014,1017,1019,1020,1022,1022,1023,1023,1023,1023,1022,1022,1020,1019,1017,1014,1012,1009,1006,1002,998,994,990,985,980,975,969,963,957,951,944,937,929,922,914,906,898,889,880,871,862,852,843,833,823,812,802,791,780,769,758,747,735,724,712,700,688,676,664,651,639,626,614,601,588,576,563,550,537,524,512,499,486,473,460,447,435,422,409,397,384,372,359,347,335,323,311,299,288,276,265,254,243,232,221,211,200,190,180,171,161,152,143,134,125,117,109,101,94,86,79,72,66,60,54,48,43,38,33,29,25,21,17,14,11,9,6,4,3,1,1,0,0,0,0,1,1,3,4,6,9,11,14,17,21,25,29,33,38,43,48,54,60,66,72,79,86,94,101,109,117,125,134,143,152,161,171,180,190,200,211,221,232,243,254,265,276,288,299,311,323,335,347,359,372,384,397,409,422,435,447,460,473,486,499,};
26
unsigned char tab_counter=0;
27
28
PWM_Set_DC(unsigned int dc);
29
int main()
30
{
31
  OSCCONbits.SPLLEN=1;    // 4x PLL Is enabled
32
  OSCCONbits.IRCF=0b1110;    // 8 MHz or 32 MHz HF
33
  OSCCONbits.SCS=0;      // Clock determined by FOSC<2:0> in config
34
35
  ANSELA=0x00;        // All IOs digital
36
  TRISA=0x00;          // All IOs output
37
  LATA=0x00;          // All outputs to '0'
38
39
  //Timer 0 Init
40
  OPTION_REGbits.PS=0b001;  // 1:4 Prescaler
41
  OPTION_REGbits.PSA=0;    // Prescaler is assigned to the Timer0 module
42
  OPTION_REGbits.TMR0CS=0;  // Internal instruction cycle clock (FOSC/4)
43
44
  INTCONbits.GIE=1;      // Enables all active interrupts
45
  INTCONbits.PEIE=1;      // Enables all active peripheral interrupts
46
  INTCONbits.T0IF=0;      // Clear T0IF, just in case
47
  INTCONbits.T0IE=1;      // Enables the Timer0 interrupt
48
49
  //Init PWM
50
  APFCONbits.CCP1SEL=1;    // CCP1/P1A function is on RA5
51
  APFCONbits.P1BSEL=1;    // P1B function is on RA4
52
53
  PR2=0xFF;
54
  T2CONbits.T2CKPS=0;      // Prescaler 1:1+PR2=0xFF --> 10bit, 31.25 kHz PWM @ Fosc=32MHz
55
  T2CONbits.TMR2ON=1;      // Timer2 is on
56
57
  CCP1CONbits.CCP1M=0b1100;  // PWM mode: P1Aactive-high; P1B active-high
58
  CCP1CONbits.P1M=0b10;    // Half-Bridge output; P1A, P1B modulated with dead-band control
59
  PWM1CONbits.P1DC=4;    // 4*125ns = 500ns Dead Time @ 32MHz
60
  while(1);
61
}
62
63
void interrupt ISR()
64
{
65
  INTCONbits.T0IF=0;      // Clear T0IF
66
  TMR0=99;          // Interrupt every 80µs
67
  PWM_Set_DC(sin_tab[tab_counter]);
68
  tab_counter++;
69
  if(tab_counter>249)      //250*80µs=20ms
70
    tab_counter=0;
71
}
72
73
74
PWM_Set_DC(unsigned int dc)
75
{
76
  CCP1CONbits.DC1B=dc;
77
  CCPR1L=dc>>2;
78
}