會員登陸
帳號:

密碼:

記住我



忘記密碼?

現在註冊!
網站導航
最新下載
訪問統計 (自2012/5/3)


正在流覽:   1 名訪客





dsPIC30F4011之ADC中斷內算式對中斷時間之影響
新會員
註冊日期:
2017/01/04 22:14
所屬群組:
註冊會員
文章: 3
等級: 1; EXP: 10
HP : 0 / 2
MP : 1 / 11
離線
您好,我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
轉換PDF檔 列印


Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響
資深會員
註冊日期:
2007/03/29 00:43
所屬群組:
註冊會員
文章: 183
等級: 12; EXP: 58
HP : 0 / 289
MP : 61 / 9503
離線
不要在中斷函式裡做 數。學。運。算 還有所有一切 多餘的事。

報告完畢。

1月10日 19:34:39
轉換PDF檔 列印


Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響
新會員
註冊日期:
2017/01/04 22:14
所屬群組:
註冊會員
文章: 3
等級: 1; EXP: 10
HP : 0 / 2
MP : 1 / 11
離線
謝謝指教!我有嘗試將中斷內的計算過程全部搬到副程式內做計算,利用呼叫副程式的方式來執行,但是速度還是跟在中斷內計算差不多,沒有得到改善,請問是什麼原因?我要如何去改善呢?謝謝!

部分程式修改後如下:
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
轉換PDF檔 列印


Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響
資深會員
註冊日期:
2012/05/04 19:18
所屬群組:
註冊會員
文章: 203
等級: 13; EXP: 28
HP : 0 / 307
MP : 67 / 5504
離線
1/60kHz = 16uS,你必須確定你做完成除法不會超過16us?
你在中斷裡面加入乘除法運算,很可能就會影響了,就算你用呼叫副程式也是一樣,設一個旗標在Main的while(1)的回圈內去做adc的計算應該就會改善了!

1月11日 08:25:45
轉換PDF檔 列印


Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14341
等級: 72; EXP: 81
HP : 1077 / 1795
MP : 4780 / 74198
離線
void add(void)
{
ADC = (ADCBUF0); // get ADC value
ADC1 = ((ADC-430)/430)*155;
}

以上程式在哪裡執行所花的時間都是一樣的。最好是在主程式以 Flag 方式檢測後再執行此運算。

因為你在中斷裡有做數學運算,這意味著這些數學暫存區塊也需要 Push 起來以免主程式也在做述學運算時會共用到同一塊記憶體。這個 Buffer 的 Push & Pop 也會佔用不少終端的時間的。

1月11日 13:19:19
轉換PDF檔 列印


Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響
中級會員
註冊日期:
2014/05/28 13:30
所屬群組:
註冊會員
文章: 47
等級: 5; EXP: 67
HP : 0 / 116
MP : 15 / 1389
離線
小建議,
這行 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
轉換PDF檔 列印


Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響
新會員
註冊日期:
2017/01/04 22:14
所屬群組:
註冊會員
文章: 3
等級: 1; EXP: 10
HP : 0 / 2
MP : 1 / 11
離線
回Edison:我試過你的方式了,的確感善我的問題,非常感謝!!
回Ryang:感謝教導!!
回energy:感謝建議!!我以後會注意

1月11日 17:42:44
轉換PDF檔 列印


Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響
資深會員
註冊日期:
2007/06/05 21:45
所屬群組:
註冊會員
文章: 973
等級: 27; EXP: 68
HP : 0 / 667
MP : 324 / 21531
離線
不是很了解你的問題是什麼...
ADC1 = ((ADC-430)/430)*155;

但如果是 ADC轉換問題,可以參考以前討論過的文章...
(但一樣,不要放在 "中斷"時 去執行...)

http://www.microchip.com.tw/modules/n ... t_id=44930#forumpost44930

1月14日 17:24:12
轉換PDF檔 列印


Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響
新會員
註冊日期:
2006/03/21 23:03
所屬群組:
註冊會員
文章: 7
等級: 1; EXP: 60
HP : 0 / 15
MP : 2 / 540
離線
n26051144 您好, 請問你是使用ICD2與dsPIC30F4011 相連???

你連接時有以下問題

ICDWarn0020: Invalid target device id (expected=0x101, read=0x0)

你的MPLAB及C30是什麼版本???

謝謝你

6月06日 13:31:40
轉換PDF檔 列印


Re: dsPIC30F4011之ADC中斷內算式對中斷時間之影響
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14341
等級: 72; EXP: 81
HP : 1077 / 1795
MP : 4780 / 74198
離線
不知你的 dsPIC30F4011 是自己做的板子還是 APP020 Plus 的實驗板。

因為找不到 Device ID 是連線上的問題, 可以點一下紅色的錯誤號碼即可查閱問題所在 ICDWarn0020: Invalid target device id (expected=0x101, read=0x0)

另外也更新一下 ICD2 的本身的韌體看看。

6月07日 17:59:36
轉換PDF檔 列印






無法在此發表文章
可以在此觀看文章
無法回覆文章
無法編輯自己的文章
無法刪除自己的文章
無法發起投票調查
無法在此投票
無法上傳附加檔案
無法不經審核直接發表文章

[進階搜尋]


搜尋
Microchip連結

網頁捷徑
2018 Winter Elite 報名
教育訓練
其它網站連結
電話: 02-25000405
產品技術問題產品技術支援專線:0800-717718 台北02-25088600 新竹03-5778366 Ext. 8600 高雄07-2137830 MicrochipDIRECT 專線: 07-2137830
Powered by XOOPS © 2001-2012 The XOOPS Project