Re: 請教.....關於脈寬調變(PWM)
|
||||
---|---|---|---|---|
新會員
|
跟你建的sin table有關, 如果你的中斷是20kHz, 建的點數就要有20kHz/60Hz的點, 如此一點一點丟給duty, 還有就是你sin table的振幅(與counter的值比較)也要大一點, 90%~100%左右, 再加上dead time效應, 用示波器就可以看出明顯的60Hz了!
發表於: 2007/6/9 11:39
|
|||
|
Re: 請教.....關於脈寬調變(PWM)
|
||||
---|---|---|---|---|
新會員
|
我已經做出來會自動調變的PWM....
不過無法輸出60Hz的弦波..... 不知道是不是外部震盪器不足..... 因為請問震盪器6MHz需要搭配多少的電容值....
發表於: 2007/6/7 14:50
|
|||
|
Re: 請教.....關於脈寬調變(PWM)
|
||||
---|---|---|---|---|
新會員
|
既然會跟著改變, 那接著就建sin table 一點一點抓 不就okㄌ?
發表於: 2007/6/7 11:13
|
|||
|
Re: 請教.....關於脈寬調變(PWM)
|
||||
---|---|---|---|---|
新會員
|
我有試過如果輸入值變化...
Duty會跟隨著改變.... 但是無法達到自動變動的Duty.... 是否有哪邊可以改變嗎??? 或是有什麼程式可以達到簡單的PWM自動調變的方法嗎???
發表於: 2007/6/6 13:33
|
|||
|
Re: 請教.....關於脈寬調變(PWM)
|
||||
---|---|---|---|---|
新會員
|
建議你先從簡單的試試, 先給常數變化看duty是否跟著變, 範例程式只是參考, 因為每個condition都不一樣, 由小到大是比較好處理的!
發表於: 2007/6/6 11:14
|
|||
|
Re: 請教.....關於脈寬調變(PWM)
|
||||
---|---|---|---|---|
新會員
|
建議你先從簡單的試試, 先給常數變化看duty是否跟著變, 範例程式只是參考, 因為每個condition都不一樣, 由小到大是比較好處理的!
發表於: 2007/6/6 11:14
|
|||
|
Re: 請教.....關於脈寬調變(PWM)
|
||||
---|---|---|---|---|
新會員
|
可以請教....
我有找到用組語寫的PWM.... 程式裡有讀取 Sine table的值.... 不過測試時.... 卻只讀0值.... 而非整個 Sine table之值.... 可以請教怎麼修改嗎??? 下列是我所找到之程式.... ;****************************************************************************** ; * ; Filename : acim_vhz.s * ; * ;****************************************************************************** ; Notes: * ; ====== * ; The A/D is enabled to sample two pots on the dsPICDEM-MC1 demo board * ; connected to AN7 and AN12. VR1 is used to vary the V/Hz ratio of the * ; modulation. VR2 is used to vary the modulation frequency. By * ; experimenting with the two pot settings, you can find an optimal V/Hz * ; ratio to drive the motor. * ;****************************************************************************** ;*** This code has been modified to drive a split phase motor with a ;*** H bridge, OR with a single complementary output pair. .equ __30F2010, 1 .include "C:\pic30_tools\support\inc\p30f2010.inc" .global __reset ;.............................................................................. ;Configuration bits: ;.............................................................................. config __FOSC, CSW_FSCM_OFF & XT_PLL4 ;Turn off clock switching and ;fail-safe clock monitoring and ;use the XT osc and 4x PLL as ;system clock config __FWDT, WDT_OFF ;Turn off Watchdog Timer config __FBORPOR, PBOR_ON & BORV_27 & PWRT_16 & MCLR_EN ;Set Brown-out Reset voltage and ;and set Power-up Timer to 16msecs config __FGS, CODE_PROT_OFF ;Set Code Protection Off for the ;General Segment ;.............................................................................. ;Uninitialized variables in Near data memory (Lower 8Kb of RAM) ;.............................................................................. .section .nbss, "b" ; This variable is added to the 16-bit sine wave table pointer at each ; PWM period. A value of 246 will provide 60 Hz modulation frequency ; with 16 KHz PWM Frequency: .space 2 ; This variable is used to set the modulation amplitude and scales the ; value retrieved from the sine wave table. Valid values range from 0 ; to 32767 Amplitude: .space 2 ; This variable is the pointer to the sinewave table. It is incremented ; by the value of the Frequency variable at each PWM interrupt. Phase: .space 2 ;.............................................................................. ;Constants stored in Program space ;.............................................................................. .section .sine_table, "x" .align 256 ; This is a 64 entry sinewave table covering 360 degrees of the ; sine function. These values were calculated using Microsoft ; Excel and pasted into this program. SineTable: .hword 0,3212,6393,9512,12539,15446,18204,20787,23170,25329 .hword 27245,28898,30273,31356,32137,32609,32767,32609,32137,31356,30273,28898 .hword 27245,25329,23170,20787,18204,15446,12539,9512,6393,3212,0,-3212,-6393 .hword -9512,-12539,-15446,-18204,-20787,-23170,-25329,-27245,-28898,-30273 .hword -31356,-32137,-32609,-32767,-32609,-32137,-31356,-30273,-28898,-27245 .hword -25329,-23170,-20787,-18204,-15446,-12539,-9512,-6393,-3212 ;.............................................................................. ; Constants for this application ;.............................................................................. ; This constant is used to scale the sine lookup value to the valid range ; of PWM duty cycles. This is based on the value written to PTPER. We will ; PTPER = 230 for this application, which allows duty cycles between 0 and ; 460. The sine table data is signed, so we will multiply the table data ; by 230, then add a constant offset to scale the lookup data to positive ; values .equ PWM_Scaling, 230 ;.equ xd, 100 ; The pointer to the sign wave table is 16 bits. Adding 0x5555 to the ; pointer will provide a 120 degree offset and 0xAAAA will give a 240 ; degree offset. These offsets are used to get the lookup values for ; phase 2 and phase 3 of the PWM outputs. ;.equ Offset_120, 0x5555 ;*** Added this offset to drive the split phase motor. We need an output ;*** that is shifted by 180 degrees. .equ Offset_180,0x8000 ;.............................................................................. ;Code Section in Program Memory ;.............................................................................. .text ;Start of Code section __reset: MOV #__SP_init, W15 ;Initalize the Stack Pointer MOV #__SPLIM_init, W0 ;Initialize the Stack Pointer Limit Register MOV W0, SPLIM NOP ;Add NOP to follow SPLIM initialization CALL _wreg_init ;Call _wreg_init subroutine ;Optionally use RCALL instead of CALL call Setup ; Call the routine to setup I/O and PWM ;------------------------------------------------------------------------------ ; Variable initialization ;------------------------------------------------------------------------------ clr Frequency clr Amplitude ;------------------------------------------------------------------------------ ; Main loop code ; The PWM interrupt flag is polled in the main loop ;------------------------------------------------------------------------------ Loop: btss IFS2,#PWMIF ; poll the PWM interrupt flag bra CheckADC ; if it is set, continue call Modulation ; call the sinewave modulation routine bclr IFS2, #PWMIF ; Clear the PWM interrupt flag ;call Loop CheckADC: btss IFS0,#ADIF bra Loop call ReadADC bra Loop ;call Loop ;------------------------------------------------------------------------------ ; ADC processing subroutine ;------------------------------------------------------------------------------ ReadADC: push.d W0 push.d W4 mov ADCBUF0,W0 ; Read the ADC results into W0 mov ADCBUF1,W1 ; and W1. asr W0,#2,W4 ; Right shift by 2 bits to get the mov W4,Frequency ; modulation frequency. sl W1,#5,W4 ; Left shift AN7 and AN12 values to get sl W0,#5,W5 ; 1.15 fractional data. mpy W4*W5,A ; multiply frequency by V/Hz gain to get sac A,W0 ; mod. amplitude. Store result in W0 mov #28000,W1 ; Limit modulation amplitude to avoid cp W1,W0 ; dead-time induced distortion in PWM bra GE,NoLimit ; modulation. mov W1,W0 NoLimit: mov W0,Amplitude pop.d W4 pop.d W0 return ;------------------------------------------------------------------------------ ; PWM sine wave modulation subroutine ;------------------------------------------------------------------------------ Modulation: push.d W0 ; Save off working registers push.d W2 push.d W4 push.d W6 push.d W8 push.d W10 ; The next three instructions initialize the TBLPAG and pointer register ; for access to the sinewave data in program memory using table reads. mov #tblpage(SineTable),W0 mov W0,TBLPAG mov #tbloffset(SineTable),W0 ; The next block of instructions loads various constants and variables ; used in the sinewave modulation routine. mov Phase,W1 ; Load the sinewave table pointer ;*** Modified the offset to 180 degrees for split phase motor. mov #Offset_180,W4 ; This is the value for a 180 degree offset mov Amplitude,W6 ; Load the Amplitude scaling factor ;mov #1,W6 mov #PWM_Scaling,W7 ; Load the PWM scaling value mov Frequency,W8 ; Load the Frequency constant that will ; be added to the table pointer at each ; interrupt. ; This is the pointer adjustment code. The Frequency value is added ; to the sine pointer to move through the sine table. Then, offsets ; are added to this pointer to get the phase 2 and phase 2 pointers. ; Note: If different phase offsets are desired, other constant values ; can be used here. Add 0x4000 to get a 90 degree offset, 0x8000 will ; provide a 180 degree offset. Here, 0x5555 has been loaded to W4 ; to provide 120 degrees. add W8,W1,W1 ; Add the Frequency value to the sine pointer add W1,W4,W2 ; Add 180 degree offset value for phase 2 ;*** Don't need the following line for split phase motor ;add W2,W4,W3 ; Add another 120 degree offset for phase 3 ; The sine table has 64 entries, so the pointers are right shifted ; to get a 6-bit pointer value. lsr W1,#10,W9 ; Shift the phase 1 pointer right to get the upper 6 bits sl W9,#1,W9 ; Left shift by one to convert to byte address lsr W2,#10,W10 ; Shift the phase 2 pointer right to get the upper 6 bits sl W10,#1,W10 ; Left shift by one to convert to byte address ;*** Removed for split phase motor ;lsr W3,#10,W11 ; Shift the phase 3 pointer right to get the upper 6 bits ;sl W11,#1,W11 ; Left shift by one to convert to byte address ; Now, the pointer for each phase is added to the base table pointer ; to get the absolute table address for the lookup value. The lookup ; value is then scaled for the correct amplitude and for the range ; of valid duty cycles. The next block of instructions calculates ; the duty cycle for phase 1. The phase 2 and phase 3 code is the same. add W0,W9,W9 ; Form the table address for phase 1 tblrdl [W9],W5 ; Read the lookup value for phase 1 mpy W5*W6,A ; Multiply by the amplitude scaling sac A,W5 ; Store the scaled result mpy W5*W7,A ; Multiply by the PWM scaling factor sac A,W8 ; Store the scaled result add W7,W8,W8 ; Add the PWM scaling factor to produce 50% offset ;mov #xd,W8 mov W8,PDC1 ; Write the PWM duty cycle ; The next block of code calculates the duty cycle for phase 2. add W0,W10,W10 ; Form the table address for phase 2 tblrdl [W10],W5 ; Read the lookup value for phase 2 mpy W5*W6,A ; Multiply by the amplitude scaling sac A,W5 ; Store the scaled result mpy W5*W7,A ; Multiply by the PWM scaling factor sac A,W8 ; Store the scaled result add W7,W8,W8 ; Add the PWM scaling factor to produce 50% offset ;mov #xd,W8 mov W8,PDC2 ; Write the PWM duty cycle ; The next block of code calculates the duty cycle for phase 3. ;*** Don't need the following block of code for split phase motor. ;add W0,W11,W11 ; Form the table address for phase 3 ;tblrdl [W11],W5 ; Read the lookup value for phase 3 ;mpy W5*W6,A ; Multiply by the amplitude scaling ;sac A,W5 ; Store the scaled result ;mpy W5*W7,A ; Multiply by the PWM scaling factor ;sac A,W8 ; Store the scaled result ;add W7,W8,W8 ; Add the PWM scaling factor to produce 50% offset ;mov W8,PDC3 ; Write the PWM duty cycle ; Now, save off the adjusted sinewave table pointer so it can be ; used during the next iteration of this code. mov W1,Phase ;inc xd pop.d W10 ; restore working registers pop.d W8 pop.d W6 pop.d W4 pop.d W2 pop.d W0 return ; return from the subroutine ;------------------------------------------------------------------------------ ; PWM and ADC setup code ;------------------------------------------------------------------------------ Setup: ; The first thing we need to do before enabling the PWM is to ; configure the I/O and reset the power module. The control board ; has a driver IC that buffers the PWM control lines. The active ; low output enable for this buffer is on port RD11. ; The power module has an active high reset line which is connected ; to port RE9. clr PORTD clr PORTE mov #0xF7FF,W0 ; Make RD11 an output to drive PWM buffer mov W0,TRISD ; output enable. mov #0xFDFF,W0 ; mov W0,TRISE ; Make RE9 an output for power module reset ; Now, ensure the power module is reset by driving the reset line for ; a few usec. bset PORTE,#9 repeat #39 nop bclr PORTE,#9 ; Setup the ADC mov #0x0404,W0 ; scan inputs mov W0,ADCON2 ; 2 sample/converts per interrupt mov #0x0003,W0 ; mov W0,ADCON3 ; Tad is 2*Tcy clr ADCHS ; clr ADPCFG ; all A/D pins Analog mode clr ADCSSL ; bset ADCSSL,#7 ; enable scan of AN7 bset ADCSSL,#12 ; enable scan of AN12 mov #0x8066,W0 ; enable A/D, PWM trigger, auto sample mov W0,ADCON1 ; bclr IFS0,#ADIF ; clear A/D interrupt flag ; Now, setup the PWM registers ;*** Modified next line of code for split phase motor. mov #0x0033,W0 ; complementary mode, #1, #2 mov W0,PWMCON1 ; pairs are enabled mov #0x000F,W0 ; 2usec deadtime at 7.38 MIPS mov W0,DTCON1 mov #PWM_Scaling, W0 ; set period for 16KHz PWM at 7.38 MIPS mov W0,PTPER mov #0x0001,W0 ; mov W0,SEVTCMP ; setup the special event trigger for the ADC mov #0x0F00,W0 ; set the special event postscaler to 1:16 mov W0,PWMCON2 ; mov #0x8002,W0 ; PWM timebase enabled, center aligned mode mov W0,PTCON return ; return from the Setup routine ;.............................................................................. ;Subroutine: Initialization of W registers to 0x0000 ;.............................................................................. _wreg_init: CLR W0 MOV W0, W14 REPEAT #12 MOV W0, [++W14] CLR W14 RETURN ;--------End of All Code Sections --------------------------------------------- .end ;End of program code in this file
發表於: 2007/6/5 15:37
|
|||
|
Re: 請教.....關於脈寬調變(PWM)
|
||||
---|---|---|---|---|
新會員
|
我有試過裡面的Soure Core....
不過不知為何還是無法做調整..... 有沒有更明確的講法呢??? 還有我有找到感應馬達控制.... 不過依舊無法自動調變..... 是否ㄧ定要外加電壓作為調整才行呢??? 還有程式需要如何修改??? 下列是我所使用之範例程式.... // *********************************************************************** // File : EX15_3_MCPWM.C // Purpose : 練習如何使用 Microchip C30 提供的 PWM 函式庫 // // 使用的函式庫: // pwm // adc10 // // *********************************************************************** #define __dsPIC30F2010__ #include <p30F2010.h> #include <pwm.h> // 將pwm函式的原型宣告檔案含入 #define FCY 7372800 * 2 // 因為使用頻率為將外部 7.3728 MHz * 8 的模式 , 每一指令週期需 4 個 clock // 所以 FCY = (7.3728 * 8 / 4 ) MHz = 7372800* 2 _FOSC(CSW_FSCM_OFF & XT_PLL8); //XT with 8xPLL oscillator, Failsafe clock off _FWDT(WDT_OFF); //Watchdog timer disabled _FBORPOR(PBOR_OFF & MCLR_EN); //Brown-out reset disabled, MCLR reset enabled _FGS(CODE_PROT_OFF); //Code protect disabled void Init_MCPWM(void); const char My_String1[]="Ex 15 - MCPWM" ; // 宣告字串於 Program Memory (因為 const 宣告) char My_String2[]="VR1: VR2: " ; // 宣告字串於 Data Memory int main(void) { Init_MCPWM( ); while (1); } /******************************************************/ // Subroutine to configure the Motor Control PWM module void Init_MCPWM(void) { /* Holds the PWM interrupt configuration value*/ unsigned int config; /* Holds the value to be loaded into dutycycle register */ unsigned int period; /* Holds the value to be loaded into special event compare register */ unsigned int sptime; /* Holds PWM configuration value */ unsigned int config1; /* Holds the value be loaded into PWMCON1 register */ unsigned int config2; /* Holds the value to configure the special event trigger postscale and dutycycle */ unsigned int config3; /* The value of ‘dutycyclereg’ determines the duty cycle register(PDCx) to be written */ unsigned int dutycyclereg; unsigned int dutycycle; unsigned char updatedisable; /* Configure pwm interrupt enable/disable and set interrupt priorties */ config = (PWM_INT_DIS & PWM_FLTA_DIS_INT & PWM_INT_PR1 & PWM_FLTA_INT_PR0); ConfigIntMCPWM( config ); /* Configure PWM to generate square wave of 50% duty cycle */ SetMCPWMDeadTimeGeneration(PWM_DTA20 & PWM_DTAPS4 & PWM_DTB40 & PWM_DTBPS4); dutycyclereg = 1; dutycycle = 0x1FF; updatedisable = 0; // SetDCMCPWM(dutycyclereg,dutycycle,updatedisable); PDC1=0x1FF; PDC2=0x1FF; PDC3=0x1FF; period = 0x2ff; sptime = 0x0; config1 = (PWM_EN & PWM_IDLE_STOP & PWM_OP_SCALE1 & PWM_IPCLK_SCALE1 & PWM_MOD_FREE); config2 = (PWM_MOD1_COMP & PWM_MOD2_COMP & PWM_PDIS3H & PWM_PEN2H & PWM_PEN1H & PWM_PDIS3L & PWM_PEN2L & PWM_PEN1L); config3 = (PWM_SEVOPS1 & PWM_OSYNC_PWM & PWM_UEN); OpenMCPWM(period,sptime,config1,config2,config3); }
發表於: 2007/6/5 15:33
|
|||
|
Re: 請教.....關於脈寬調變(PWM)
|
||||
---|---|---|---|---|
新會員
|
pic 要自己建sin table, dspic如果速度夠快可用內建的sin function, 如果未來要做到閉迴路控制, 建sin table是比較好的
發表於: 2007/6/4 18:53
|
|||
|