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 | }
|