會員登陸
網站導航
最新下載
- Microchip 程式... (Tue, 17-Apr-2018)
- Microchip 程式... (Mon, 09-Apr-2018)
- Microchip2018微... (Fri, 19-Jan-2018)
- Microchip 2018 ... (Tue, 19-Dec-2017)
- 2017 精英年會特... (Wed, 11-Oct-2017)
- 2017 秋 研討會... (Wed, 11-Oct-2017)
- 2017 暑期微控制... (Fri, 07-Jul-2017)
- ATM6 講義與實作... (Tue, 27-Jun-2017)
- ATM5 講義與實作... (Tue, 27-Jun-2017)
- ATM4 講義與實作... (Tue, 27-Jun-2017)
訪問統計 (自2012/5/3)
|
正在流覽:
1 名訪客
|
dsPIC30F4011之ADC中斷內算式對中斷時間之影響 |
|
新會員 
註冊日期: 2017/01/04 22:14
所屬群組:
註冊會員
文章: 3
等級: 1; EXP: 10 HP : 0 / 2 MP : 1 / 10
|
您好,我ADC中斷是以MCPWM裡設定的period作為觸發時脈(60KHz),在ADC中斷內變數ADC用來取ADCBUF的值,變數ADC1用來對ADC作計算,test則是定義成數位輸出用來測量中斷頻率,目前遇到的問題是當中斷內加上ADC1運算式時,會導致中斷頻率減少一半,只要將其反白就恢復正常,ADC1只是普通的加減乘除運算為何會讓中斷頻率減半?煩請各位先進指教指教。
以下是我的程式碼:
#include "C30EVM_LCD.h" // 將LCD函式的原型宣告檔案含入 #include <p30F4011.h> #include <timer.h> // 將Timer函式的原型宣告檔案含入 #include <adc10.h> // 將adc10函式的原型宣告檔案含入 #include <pwm.h> // 將pwm函式的原型宣告檔案含入 #include <uart.h> // 將UART函式的原型宣告檔案含入 #include <outcompare.h> // 將Compare函式的原型宣告檔案含入 #include <math.h> // 將Math函式的原型宣告檔案含入 #include <spi.h> // 納入SPI函式庫函式原型名稱定義 #include <incap.h> // 將Inputcapture函式的原型宣告檔案含入 #define __dsPIC30F4011__ #define FCY 7372800 * 4 // 因為使用頻率為將外部 7.3728 MHz * 8 的模式 , 每一指令週期需 4 個 clock
// 設定MCP4921相關腳位 #define TRIS4921_SDI TRISFbits.TRISF3 #define TRIS4921_SDO TRISFbits.TRISF2 #define TRIS4921_SCK TRISFbits.TRISF6 #define TRIS4921_CS TRISBbits.TRISB2 #define MCP4921_CS LATBbits.LATB2 #define test TRISBbits.TRISB3 #define test LATBbits.LATB3 //#define TRIS4921_LDAC TRISFbits.TRISFx //#define MCP4921_LDAC LATFbits.RFx
_FOSC(CSW_FSCM_OFF & XT_PLL16); // 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 __attribute__((__interrupt__ , auto_psv)) _ADCInterrupt(void); void Init_Port(void); void Init_MCPWM(void); void Init_ADC(void) ; void Show_ADC(void) ; void Init_SPI(void); void WriteSPI(unsigned int data_out);
unsigned int chanA=0x3000, spi_data, DAC_A;
signed int qq; float ADC,ADC1,ADC2; signed int a;
float valpha, vbeta, theta;
signed int valpha1, vbeta1;
double yat=0,yat1=0,yat2=0; double xat=0,xat1=0,xat2=0;
double ybt=0,ybt1=0,ybt2=0; double xbt=0,xbt1=0,xbt2=0;
const char My_String1[]="Ex 15 - MCPWM" ; // 宣告字串於 Program Memory (因為 const 宣告) char My_String2[]="VR1: VR2: " ; // 宣告字串於 Data Memory
int main(void) { Init_ADC( ) ; // 將ADC進行初始化設定
OpenLCD( ) ; // 使用 OpenLCD( )對 LCD 模組作初始化設定 Init_SPI(); Init_Port(); // 4 bits Data mode // 5 * 7 Character Init_MCPWM( );
while(1) { } }
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 */ //dutycyclereg = 1; //dutycycle = 0x7FFF; //updatedisable = 0; //SetDCMCPWM(dutycyclereg,dutycycle,updatedisable); //PDC1=0x0; //PDC2=0x0; //PDC3=0x0; period = 491.52; sptime = 0x00; config1 = (PWM_EN & PWM_IDLE_STOP & PWM_OP_SCALE1 & PWM_IPCLK_SCALE1 & PWM_MOD_FREE); config2 = (PWM_MOD1_COMP & PWM_MOD2_COMP & PWM_MOD3_COMP &//PWM_MOD2_IND //PWM1,2,3啟動互補 PWM_PEN3H & PWM_PEN2H & PWM_PEN1H & PWM_PEN3L & PWM_PEN2L & PWM_PEN1L); config3 = (PWM_SEVOPS1 & PWM_OSYNC_PWM & PWM_UEN); OpenMCPWM(period,sptime,config1,config2,config3); DTCON1=0x0508; //deadtime control }
void Init_ADC(void) {
unsigned int Channel, PinConfig, Scanselect, Adcon3_reg, Adcon2_reg, Adcon1_reg; //TRISB = 0XFFFF; //RB0~RB8作數位輸入用,給類比訊號輸入 ADCON1bits.ADON = 0; /* turn off ADC */
PinConfig = ENABLE_AN0_ANA; // Select port pins as analog inputs ADPCFG<15:0>
Adcon1_reg = ADC_MODULE_ON & // Turn on A/D module (ADON) ADC_IDLE_STOP & // ADC turned off during idle (ADSIDL) ADC_FORMAT_INTG & // Output in integer format (FORM) ADC_CLK_MPWM & // Conversion trigger by MCPWM (SSRC) ADC_SAMPLE_INDIVIDUAL & // Sample channels individually (SIMSAM) ADC_AUTO_SAMPLING_ON; // Sample trigger automatically (ASAM)
Adcon2_reg = ADC_VREF_AVDD_AVSS & // Voltage reference : +AVdd, -AVss (VCFG) ADC_SCAN_OFF & // Scan off (CSCNA) ADC_ALT_BUF_OFF & // Use fixed buffer (BUFM) ADC_ALT_INPUT_OFF & // Does not alternate between MUX A & MUX B (ALTS) ADC_CONVERT_CH0 & // Convert only channel 0 (CHPS) ADC_SAMPLES_PER_INT_1; // 1 sample between interrupt (SMPI)
Adcon3_reg = ADC_SAMPLE_TIME_10 & // Auto-Sample time (SAMC) ADC_CONV_CLK_SYSTEM & // Use system clock (ADRC) ADC_CONV_CLK_4Tcy; // Conversion clock = 4 Tcy (ADCS) // ADCS = 2*(154ns)/(1/Fcy)-1 = 3.5416
Scanselect = SCAN_NONE; // ADC scan no channel (ADCSSL)
OpenADC10(Adcon1_reg, Adcon2_reg, Adcon3_reg, PinConfig, Scanselect);
Channel = ADC_CH0_POS_SAMPLEA_AN0 & // CH0 Pos. : AN0, Neg. : Nominal Vref- Defined in ADCON2 ADC_CH0_NEG_SAMPLEA_NVREF ;// (ADCHS) SetChanADC10(Channel); //ConfigIntADC10(ADC_INT_DISABLE); IFS0bits.ADIF = 0; //清除AD中斷旗標 IEC0bits.ADIE = 1; //致能AD中斷旗標 ADCON1bits.ADON = 1; //開啟ADC
}
void __attribute__((__interrupt__ , auto_psv)) _ADCInterrupt(void) { test =! test; int i; a=a+1; IFS0bits.ADIF = 0; ADC = (ADCBUF0); // get ADC value ADC1 = ((ADC-430)/430)*155; if(a==3) { PDC1 = ADC; a=0; } }
void Init_Port(void) { ADPCFG = 0xfffe; TRISB = TRISB & 0xfff3; //TRIS4921_LDAC=0; // LDAC 腳位設為輸出 //test=0; TRIS4921_SDI=1; // SDI 腳位設為輸入 TRIS4921_SDO=0; // SDO 腳位設為輸出 TRIS4921_SCK=0; // SCK 腳位設為輸出 ADPCFGbits.PCFG2=1; //設定RB2為數位輸出入腳位 TRIS4921_CS=0; // Chip Select 腳位設為輸出 MCP4921_CS=1; // CS初始化為1 //MCP4921_LDAC=1; // LDAC初始化為1 }
1月10日 17:25:04
|
|
|
Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響 |
|
資深會員 
註冊日期: 2007/03/29 00:43
所屬群組:
註冊會員
文章: 183
等級: 12; EXP: 58 HP : 0 / 289 MP : 61 / 9368
|
不要在中斷函式裡做 數。學。運。算 還有所有一切 多餘的事。
報告完畢。
1月10日 19:34:39
|
|
|
Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響 |
|
新會員 
註冊日期: 2017/01/04 22:14
所屬群組:
註冊會員
文章: 3
等級: 1; EXP: 10 HP : 0 / 2 MP : 1 / 10
|
謝謝指教!我有嘗試將中斷內的計算過程全部搬到副程式內做計算,利用呼叫副程式的方式來執行,但是速度還是跟在中斷內計算差不多,沒有得到改善,請問是什麼原因?我要如何去改善呢?謝謝!
部分程式修改後如下: void __attribute__((__interrupt__ , auto_psv)) _ADCInterrupt(void) { test =! test; IFS0bits.ADIF = 0; add(); } void add(void) { ADC = (ADCBUF0); // get ADC value ADC1 = ((ADC-430)/430)*155; }
1月10日 23:09:46
|
|
|
Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響 |
|
資深會員 
註冊日期: 2012/05/04 19:18
所屬群組:
註冊會員
文章: 200
等級: 13; EXP: 18 HP : 0 / 304 MP : 66 / 5316
|
1/60kHz = 16uS,你必須確定你做完成除法不會超過16us? 你在中斷裡面加入乘除法運算,很可能就會影響了,就算你用呼叫副程式也是一樣,設一個旗標在Main的while(1)的回圈內去做adc的計算應該就會改善了!
1月11日 08:25:45
|
|
|
Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響 |
|
版主 
註冊日期: 2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者 註冊會員 MICROCHIP
文章: 14270
等級: 72; EXP: 70 HP : 1075 / 1792 MP : 4756 / 73250
|
void add(void) { ADC = (ADCBUF0); // get ADC value ADC1 = ((ADC-430)/430)*155; }
以上程式在哪裡執行所花的時間都是一樣的。最好是在主程式以 Flag 方式檢測後再執行此運算。
因為你在中斷裡有做數學運算,這意味著這些數學暫存區塊也需要 Push 起來以免主程式也在做述學運算時會共用到同一塊記憶體。這個 Buffer 的 Push & Pop 也會佔用不少終端的時間的。
1月11日 13:19:19
|
|
|
Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響 |
|
中級會員 
註冊日期: 2014/05/28 13:30
所屬群組:
註冊會員
文章: 50
等級: 5; EXP: 90 HP : 0 / 122 MP : 16 / 1400
|
小建議, 這行 ADC1 = ((ADC-430)/430)*155; 因為ADC1與ADC都已宣告為float, 最好還是養成習慣加上小數點, ADC1 = ((ADC-430.0)/430.0)*155.0;
而且你的Code #define test TRISBbits.TRISB3 #define test LATBbits.LATB3
這個地方Compiler不會跳出重複定義的錯誤嗎?
1月11日 16:02:19
|
|
|
Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響 |
|
新會員 
註冊日期: 2017/01/04 22:14
所屬群組:
註冊會員
文章: 3
等級: 1; EXP: 10 HP : 0 / 2 MP : 1 / 10
|
回Edison:我試過你的方式了,的確感善我的問題,非常感謝!! 回Ryang:感謝教導!! 回energy:感謝建議!!我以後會注意
1月11日 17:42:44
|
|
您無法在此發表文章
您可以在此觀看文章
您無法回覆文章
您無法編輯自己的文章
您無法刪除自己的文章
您無法發起投票調查
您無法在此投票
您無法上傳附加檔案
您無法不經審核直接發表文章
|
搜尋
Microchip連結
網頁捷徑
2018 Winter Elite 報名
教育訓練
其它網站連結
|