|
關於dsPIC30F4011記憶體使用問題
|
||||
|---|---|---|---|---|
|
新會員
![]() |
各位先進前輩們,小弟現在遇到個問題還請各位多多指導,謝謝~
我現在要宣告一個"矩陣變數"將控制器輸出結果記錄起來,變數格式為int,希望記錄資料點數為 2000 點。 但在程式compiler時出現錯誤: D:\ExperimentCode\dsPIC4011_SpeedControl.o: Link Error: Could not allocate section .ndata, size = 3218 bytes, attributes = data near Link Error: Could not allocate data memory 然後我在 MPLAB IDE v7.21中發現有個功能叫做 Memory Usage Gauge。 我使用的device為 dsPIC30F4011(申請的樣品),從規格書上看到其具有 48Kbytes Program memory 和 2Kbytes Data RAM,但如附圖所示,從Memory Usage Gauge可以看到尚無完全發揮但compiler即出現錯誤 想請問各位先進們,這問題跟我使用的 C30 compiler有關嗎?還是跟自己變數宣告有關?亦或是使用的為Microchip的樣品而有所限制呢? 那關於大量的變數資料點的紀錄,有何解決辦法嗎?想請各位前輩給小弟一點建議,謝謝~ 最後想再請問關於Memory Usage Gauge中標示的Program memory為何total只有16384呢?不是應該有48Kbytes嗎? Attach file: (0.00 KB)
發表於: 2009/3/15 16:57
|
|||
|
||||
|
Re: 程式會自動停止,想請問如何除錯?
|
||||
|---|---|---|---|---|
|
新會員
![]() |
參照:
謝謝e大的回答 , 對於e大說的 Q格式運算 , 我自己也有試著了解並做了一些實驗 , 但不知道自己的觀念是否正確 , 還請e大幫我檢查我的思維 , 謝謝 Q.15小數格式 是指在做 " 乘法運算 "時 , 若乘數為一小數值 -1.00 ~ +0.9998 , 透過 Q.15格式 運算達到相似於 浮點數 運算的結果是嗎? ex : 被乘數為 signed int格式 12267 乘數 0.68393 -> 則 Q.15 表示為 22411 因此我程式寫法 Ans = ((long)12267 * 22411 ) >> 15; 我利用Watch(Debug mode with ICD2)觀看運算結果得知 Ans = 8389 , 此結果相當於 浮點數運算 12267 * 0.68393 = 8389.769 想請問e大 , Q.15小數乘法是這樣使用的嗎? 假設上述方法可行 , 那還有另一個問題 , 當 " 乘數 " 是大於1.0的小數值時 , 是否就不能用 Q.15 格式了? 因為我現今PI控制器設計完後 Kp = 1.3679 , 大於Q.15表示的小數範圍 , 而我自己的想法是將 Kp 視為 Kp = 2 * 0.68395 則如此乘2的部分利用左偏1bit , 而 乘0.68395 則同樣利用 Q.15的運算方法 -> 0.68395 的Q.15表示為 22411 ex : 和上述相同 假設 被乘數為 (signed int) 12267 我的程式寫法 Ans = ((long)12267 * 22411 ) >> 15 << 1; 相當於 = ((long)12267 * 22411 ) >> 14; 利用Watch觀看 , 運算結果 Ans = 16779 , 結果和浮點數運算 12267 * 1.3679 = 16780.0293 結果相近. 但我知道 大於1.0的Q.15小數乘法 , 相乘結果好像會遇到 " 溢位 " 的問題. ex : 這次假設 被乘數(signed int)為 26653 , 運算結果Ans也宣告為signed int 利用上述的程式寫法 Ans = ((long)26653 * 22411 ) >> 14; 利用Watch觀看 , 運算結果Ans = 36457 . 但這運算結果 Ans 在 signed int 中卻會被視為 "負數" 吧?!(超出32767 , 正數*正數結果卻產生負數) 如此再將此Ans做後續的處理 , 好像會造成無法預期的馬達控制響應(不穩定的震盪) 我現在想到的處理方法為 Ans運算後再加上 範圍判斷限制 ex : Err = 26653; // Err : signed int , Ans : signed int Ans = ((long)26653 * 22411 ) >> 14; // Ans = Err * 1.3679 if( (unsigned int)Ans > 32767 && Err >0 ) Ans = 32767; // 正數*正數 , 結果 Ans不應該為負 else if( (unsigned int)Ans < 32768 && Err <0 ) Ans = -32768; // 負數*正數 , 結果 Ans不應該為正 想請問我程式這樣的想法正確嗎? 因為小弟我學寫程式的功力和經驗還很淺 , 還請各前輩們多多指導!! 謝謝
發表於: 2008/8/2 11:48
|
|||
|
||||
|
Re: 程式會自動停止,想請問如何除錯?
|
||||
|---|---|---|---|---|
|
新會員
![]() |
很感謝大家熱心的回答 ^^
1.首先很謝謝版主提供的 Trap 範例... 但因為我沒用過 Trap,點開範例來看發現程式部分是不是只有 Trap 的中斷服務程式而已阿? Trap不需要先去致能初始化嗎? (像ADC中斷須先致能) 然後還想請教版主,例如當 算數Trap 發生時,會進到相對應的ISR中 void _ISR _MathError(void) { INTCON1bits.MATHERR = 0; while(1); } 想請問 ISR內程式只有這兩行程式 , 如此dsPIC不會reset 但就會一直卡在while(1)那行嚕? 如此意思是說我們可以將中斷點 ( debuge mode with ICD2 ) 放在while(1)那行,檢驗是否是算數錯誤以找到我們程式錯誤的地方嗎? 還請版主教導 ^^ 2.另外說明一下我為何想採用 float 做為PI控制器的運算 原本我將AD中斷設為10KHz處理一次 ( 包含回授訊號處理+電流PI+PWM調變輸出 ) , PI控制器的部份採用整數格式運算 ( Q.15格式應用在需小數相乘的部分 ) 但是經由控制器的設計後 , 得到PI控制器參數為 Kp = 1.36 因為我想說 Q.15 能夠表示的小數範圍為 -1.000~+0.998 , 沒辦法表示大於1.0的小數 , 所以想採用float格式做乘法運算 , 但只針對電流PI控制器的部份採用float格式 . ex : err * 1.36 (err為int轉換成float格式 : 數值範圍 -32768 ~ +32767 ) 但因為加上 耗時的 float格式運算 , 發現只好將我的AD中斷頻率降低為 5KHz . 我是利用 一隻I/O腳位輸出High low訊號(進出AD ISR) , 利用示波器看我AD中斷的處理時間 , 有滿足在1/5K (s)以內. 本想說這樣即使中斷(取樣)頻率較慢 , 但閉迴路系統應該還是可以正常運作吧?! 但結果卻是發生了 程式自己停止的情況 囧rz...
發表於: 2008/8/2 10:45
|
|||
|
||||
|
Re: 程式會自動停止,想請問如何除錯?
|
||||
|---|---|---|---|---|
|
新會員
![]() |
抱歉補充一下 , 我採用的MCU 是 dsPIC30F4011
我將PI控制器寫在 AD中斷內(5KHz) 有確保過 執行完 AD中斷服務程式 時間仍在 1/5K (s)以內
發表於: 2008/7/28 20:40
|
|||
|
||||
|
程式會自動停止,想請問如何除錯?
|
||||
|---|---|---|---|---|
|
新會員
![]() |
各位前輩們 , 我最近寫了馬達電流控制的程式
在電流控制器的部分採用基本的 PI 控制器 我是用 浮點數(float)格式做運算 最後控制器輸出結果再換回 整數(int)格式 再去調變產生 PWM 輸出 控制Inverter 我的問題是 : 利用浮點數做運算,我的程式會執行到一半自動停止 , 但看不到程式停在哪裡(沒有看到綠色箭頭) , 想請問這是哪部份出了錯嗎? 我的PI控制器是參考文件 AN1078 所寫的 我的程式部分如下 : //只有Ref_Id , Id , Vde為signed int格式 , 其餘皆為float格式 Id_command = Ref_Id; // Id_command : float , // Ref_Id : signed int Id_feedback = Id; // Id_feedback : float , // Id : signed int Id_error = Id_command - Id_feedback; // Ki_F = 0.09216 , Kp_F = 1.3679 (float) Id_sum_F = Id_sum_F + Id_Ki_F * Id_error; // Id_sum_F為積分項 Id_U_F = Id_sum_F + Id_Kp_F * Id_error; // Id_U_F 為PI控制器輸出 if(Id_U_F > 18917) // 經過輸出飽和限制 , 產生電壓命令 Vde = 18917; else if(Id_U_F < -18917) Vde = -18917; else Vde = Id_U_F; // Vde : signed int 不知道各位前輩們有沒有遇到過相似的問題 , 可否教小弟我如何 除錯解決問題嗎? 謝謝各位 P.S. 我有試過將 PI 控制器內全部改採用 整數格式 運算 , 程式就不會停止了 , 那這樣是跟浮點數運算有關嗎?
發表於: 2008/7/28 20:36
|
|||
|
||||
|
dsPIC4011-AD轉換格式的問題
|
||||
|---|---|---|---|---|
|
新會員
![]() |
各位前輩好,小弟有個問題困擾我好久了
在dsPIC4011中的AD我們可以去設定他將類比電壓轉換成 1.有號分數 2.分數 3.有號整數 4.整數 四種格式的數位資料 而我規劃板子使 Vref- = GND(0V) , Vref+ = Vcc(5V) 在板上有討論到 轉換的結果存放到ADCBUF的值為 ADCBUFx = (Va+ - 0) / (Vcc - 0) * 1024 - 1 , 令Va- = Vref- 但這是針對 " 整數 " 格式計算的吧? 如果我是採用 " 有號分數 " 格式的話呢? 計算是還是一樣嗎? 我現在只知道 他會將 類比輸入 2.5V 轉換成 0x0000(0b0000 0000 0000 0000) ; 類比電壓 5V 轉換成 0x7FC0(0b0111 1111 1100 0000) 類比電壓 0V 轉換成 0x8000(0b1000 0000 0000 0000) 但中間的數值我都不知道該怎麼換算 也有像上述的電壓換算成數位值的公式嗎?還請各位前輩開導小弟了 感謝~! 另外我看了一下 dsPIC30F Family Reference Manual中的ADC章節 P.17-49頁 表17-23 我覺得他在 16-bit Signed Fractional Format那欄是不是有寫錯 0111 1111 1100 0000 應該是等於 0.998047 吧?(Q15計算) 但書上寫 = 0.499 ?? 看不是很懂呢 那這些煩雜問題麻煩各位了 再次謝謝熱心回答了
發表於: 2008/3/20 9:23
|
|||
|
||||
|
30F4011 - 關於ADC-10bits的問題
|
||||
|---|---|---|---|---|
|
新會員
![]() |
各位先進大家好:
對於dsPIC30F4011的ADC 10bits有個問題 在先前的上課講義上規格為 500 K sps 想問一下各位 這代表什麼意思呢? 但我今天去Microchip美國網站上 看他產品的規格列表 但在ADC 10bits 為 1000 K sps 所以這是 新製作的4011 AD速率更快? 還是網站上打錯了? 謝謝各位的回答了~
發表於: 2008/3/12 22:04
|
|||
|
||||