Bài 6: PWM
Làm thế nào để tạo PWM trên dspic33f
Bài toán: tạo xung PWM với chu kì 1ms, duty = 60%.
Đầu tiên, cấu hình dao động
Ta sẽ sử dụng cấu hình dao động nội là Fcy = 40Mhz =>Fosc =80MHz.
như sau:
_FOSCSEL(FNOSC_FRC);
// Enable Clock Switching and Configure
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF);
.....
// Configure PLL prescaler, PLL postscaler, PLL divisor
PLLFBD = 41; // M = 43
CLKDIVbits.PLLPOST=0; // N2 = 2
CLKDIVbits.PLLPRE=0; // N1 = 2 //Fosc = 80MHz
// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC!= 0b001);
Tiếp theo cấu hình các chân xuất PWM là output:
_TRISB10 = 0;
_TRISB11 = 0;
_TRISB12 = 0;
_TRISB13 = 0;
_TRISB14 =0;
_TRISB15 = 0;
Ta tạo 1 hàm để setup cấu hình PWM mong muốn
setup_PWM();
Các thông số sẽ được tính toán như sau:
Ta sử dụng các bit thiết lập đầu tiên:
PTCONbits.PTOPS = 1; // bit này để lựa chọn chu kì xảy ra ngắt
PTCONbits.PTCKPS = 0; // chọn bô chia tần số với Tcy 1:1
PTCONbits.PTMOD = 2; // chọn chế độ PWM
ta có bảng lựa chọn cài đặt như sau:
PTOPS<3:0>: PWM Time Base Output Postscale Select bits
1111 = 1:16 postscale
•••
0001 = 1:2 postscale
0000 = 1:1 postscale
PTCKPS<1:0>: PWM Time Base Input Clock Prescale Select bits
11 = PWM time base input clock period is 64 TCY (1:64 prescale)
10 = PWM time base input clock period is 16 TCY (1:16 prescale)
01 = PWM time base input clock period is 4 TCY (1:4 prescale)
00 = PWM time base input clock period is TCY (1:1 prescale)
PTMOD<1:0>: PWM Time Base Mode Select bits
11 = PWM time base operates in Continuous Up/Down Count mode with interrupts for double PWM updates
10 = PWM time base operates in Continuous Up/Down Count mode
01 = PWM time base operates in Single Event mode
00 = PWM time base operates in Free Running mode
Tiêp theo, cấu hình chân PWM
PWM1CON1bits.PMOD1 = 0;
PWM1CON1bits.PMOD2 = 0;
PWM1CON1bits.PMOD3 = 0;
PWM1CON1bits.PEN1H = 1; //dau ra 1 muc cao
PWM1CON1bits.PEN2H = 1;
PWM1CON1bits.PEN3H = 1;
PWM1CON1bits.PEN1L = 1;
Cấu hình lựa chọn sử dụng tần số thời gian chết (hoạt động ở chế độ free running)
P1DTCON1bits.DTAPS = 0b00;
P1DTCON1bits.DTBPS = 0b00; //chọn tần số thực hiện thời gian chết
/* Dead time value for Dead Time Unit A */
/* Dead time value for Dead Time Unit B */
P1DTCON1bits.DTA = 10;
P1DTCON1bits.DTB = 20; //set thoi gian chết
Tiếp theo ta sử dụng công thức để tính chu kì nửa chu kì là 500us
Chú ý : đối với chế độ Free Running thì công thức này là để tính cả 1 chu kì
ta có 500x 10^-6 = 1/Fcy x(P1TPER - 1)
=> P1TPER = (500 x 10^-6 x 40x10^6) - 1 = 19999
Suy ra chu kì của PWM là 1ms thì tương ứng với 2xP1TPER.
Để tạo Duty là 60% thì P1DC1 là: 2*P1TPER *60/100 = 23998
P1TPER = 19999; // chinh chu ki
P1DC1 = 23998; //chinh do rong xung
Cuối cùng là bật bit kích hoạt PWM
P1TCONbits.PTEN = 1;
Đo xung PWM tại chân PWM tương ứng, ta sẽ thấy rõ thông số tính toán.
hoàn thành!!!
Bài toán: tạo xung PWM với chu kì 1ms, duty = 60%.
Đầu tiên, cấu hình dao động
Ta sẽ sử dụng cấu hình dao động nội là Fcy = 40Mhz =>Fosc =80MHz.
như sau:
_FOSCSEL(FNOSC_FRC);
// Enable Clock Switching and Configure
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF);
.....
// Configure PLL prescaler, PLL postscaler, PLL divisor
PLLFBD = 41; // M = 43
CLKDIVbits.PLLPOST=0; // N2 = 2
CLKDIVbits.PLLPRE=0; // N1 = 2 //Fosc = 80MHz
// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC!= 0b001);
Tiếp theo cấu hình các chân xuất PWM là output:
_TRISB10 = 0;
_TRISB11 = 0;
_TRISB12 = 0;
_TRISB13 = 0;
_TRISB14 =0;
_TRISB15 = 0;
Ta tạo 1 hàm để setup cấu hình PWM mong muốn
setup_PWM();
Các thông số sẽ được tính toán như sau:
Ta sử dụng các bit thiết lập đầu tiên:
PTCONbits.PTOPS = 1; // bit này để lựa chọn chu kì xảy ra ngắt
PTCONbits.PTCKPS = 0; // chọn bô chia tần số với Tcy 1:1
PTCONbits.PTMOD = 2; // chọn chế độ PWM
ta có bảng lựa chọn cài đặt như sau:
PTOPS<3:0>: PWM Time Base Output Postscale Select bits
1111 = 1:16 postscale
•••
0001 = 1:2 postscale
0000 = 1:1 postscale
PTCKPS<1:0>: PWM Time Base Input Clock Prescale Select bits
11 = PWM time base input clock period is 64 TCY (1:64 prescale)
10 = PWM time base input clock period is 16 TCY (1:16 prescale)
01 = PWM time base input clock period is 4 TCY (1:4 prescale)
00 = PWM time base input clock period is TCY (1:1 prescale)
PTMOD<1:0>: PWM Time Base Mode Select bits
11 = PWM time base operates in Continuous Up/Down Count mode with interrupts for double PWM updates
10 = PWM time base operates in Continuous Up/Down Count mode
01 = PWM time base operates in Single Event mode
00 = PWM time base operates in Free Running mode
Tiêp theo, cấu hình chân PWM
PWM1CON1bits.PMOD1 = 0;
PWM1CON1bits.PMOD2 = 0;
PWM1CON1bits.PMOD3 = 0;
PWM1CON1bits.PEN1H = 1; //dau ra 1 muc cao
PWM1CON1bits.PEN2H = 1;
PWM1CON1bits.PEN3H = 1;
PWM1CON1bits.PEN1L = 1;
Cấu hình lựa chọn sử dụng tần số thời gian chết (hoạt động ở chế độ free running)
P1DTCON1bits.DTAPS = 0b00;
P1DTCON1bits.DTBPS = 0b00; //chọn tần số thực hiện thời gian chết
/* Dead time value for Dead Time Unit A */
/* Dead time value for Dead Time Unit B */
P1DTCON1bits.DTA = 10;
P1DTCON1bits.DTB = 20; //set thoi gian chết
Tiếp theo ta sử dụng công thức để tính chu kì nửa chu kì là 500us
Chú ý : đối với chế độ Free Running thì công thức này là để tính cả 1 chu kì
ta có 500x 10^-6 = 1/Fcy x(P1TPER - 1)
=> P1TPER = (500 x 10^-6 x 40x10^6) - 1 = 19999
Suy ra chu kì của PWM là 1ms thì tương ứng với 2xP1TPER.
Để tạo Duty là 60% thì P1DC1 là: 2*P1TPER *60/100 = 23998
P1TPER = 19999; // chinh chu ki
P1DC1 = 23998; //chinh do rong xung
Cuối cùng là bật bit kích hoạt PWM
P1TCONbits.PTEN = 1;
Đo xung PWM tại chân PWM tương ứng, ta sẽ thấy rõ thông số tính toán.
hoàn thành!!!
Nhận xét
Đăng nhận xét