Re: c18中斷副程式使用除法運算
|
||||
---|---|---|---|---|
資深會員
|
謝謝大家的幫忙,問題已經解決了,因為我的中斷副程式裡有一個Timer2中斷,他的時間只有100us,因為多加了這條件判斷及運算式,造成在中斷副程式還沒跳出之前,Timer2又中斷了,我將Timer2中斷時間延長就可以跳出中斷副程式了,我的作法可能會將運算式寫在主程式或者將系統的時脈調高,在此感謝大家的幫忙。
發表於: 2008/5/2 11:24
|
|||
|
Re: c18中斷副程式使用除法運算
|
||||
---|---|---|---|---|
資深會員
|
謝謝你提供的方法,但uns16_spd及sp_count我本來就是宣告全域變數其型態為unsigned int,或許你的方法可行,但這樣也太麻煩了,這就失去用C寫的意義了,更何況uns16_spd=6083/sp_count;在中斷副程式根本沒執行,難道這樣也會造成系統一直在中斷迴圈裡打轉嗎?
發表於: 2008/5/2 10:42
|
|||
|
Re: c18中斷副程式使用除法運算
|
||||
---|---|---|---|---|
資深會員
|
你好,感謝你的回覆,原本是沒有&& 0,但我為了確保uns16_spd=46083/sp_count;不會被執行才加上去的,原本沒有&& 0也是會當機的。
1.我又將GIEH=0使中斷關掉,此時硬體可以正常執行,所以應不是我先前所說中斷副程式與主程式互相覆蓋的問題,現在可以肯定的是只要在中斷副程式裡加了uns16_spd=46083/sp_count;不管他有沒有被執行,系統一定會當機,當然若將GIEH=0中斷關掉則不會。 2.我試著用軟體模擬的方式,發限止要加上uns16_spd=46083/sp_count;程式就無法跳出中斷迴圈,程式執行到最後又返回0008H中斷的開頭執行。
發表於: 2008/4/30 10:19
|
|||
|
Re: c18中斷副程式使用除法運算
|
||||
---|---|---|---|---|
中級會員
|
這... 你的程式中只有這裡特別不一樣
你要不要把它去掉試一下...
#pragma interrupt isr_high nosave=section(".tmpdata")//save=PROD//,section(".tmpdata"),TABLAT,TBLPTR,PCLATH,PCLATU
--------------------------------------------------- 多了這幾個字, INT0 好像會不執行, 如果 INT0 不執行, INT0IF 也不會被清除, 那就會卡在中斷不執行主程式了.
發表於: 2008/4/29 16:22
|
|||
|
Re: c18中斷副程式使用除法運算
|
||||
---|---|---|---|---|
資深會員
|
版主你好,我已加入nosave=section(".tmpdata"),可是結果還是一樣,且你看我的程式其除法運算根本不會執行,而我的狀況是當機而非資料錯誤或被修改,能否告知還有其他可能嗎?以下是我的中斷程式
#pragma interrupt isr_high nosave=section(".tmpdata")//save=PROD//,section(".tmpdata"),TABLAT,TBLPTR,PCLATH,PCLATU void isr_high(void) { uns16 uns16_temp; if(TMR0IF && TMR0IE) //Timer0 interrupt,250ms interrupt one time { TMR0H=0xc2; TMR0L=0xf7; bit_flash=!bit_flash; _250ms_count++; union_led_ram_map.led_ram_map[30].bit3=0;//no display time dot union_led_ram_map.led_ram_map[30].bit4=0; if(_250ms_count>=4) //1 sec { bit_1_sec=TRUE; _250ms_count=0; union_led_ram_map.led_ram_map[30].bit3=1; //display time dot union_led_ram_map.led_ram_map[30].bit4=1; } if(bit_end==TRUE) BZ=!BZ; TMR0IF=0; } if(ADIE && ADIF) { key_in_ad_val=ADRESH; key_in_ad_val=key_in_ad_val<<8; key_in_ad_val=key_in_ad_val + ADRESL; ADIF=0; } if(TMR1IE && TMR1IF)//10ms interrupt one time { TMR1H=0xd8; //4MHz/4=1MHz,1000000Hz/100Hz=10000,65536-10000=55536=0xD8F0->10ms TMR1L=0xf0; GO=1; TMR1IF=0; } if(TMR2IE && TMR2IF)//100us interrupt one time { TMR2=198; TMR2IF=0; } if(INT0IE && INT0IF && 0) { stop_count=0; if(mode_select==0)//not setup mode { bit_start=TRUE; uns16_spd=46083/sp_count; } INT0IF=0; } if(INT1IE && INT1IF) { INT1IF=0; } } #pragma code
發表於: 2008/4/29 16:05
|
|||
|
Re: c18中斷副程式使用除法運算
|
||||
---|---|---|---|---|
版主
|
參考以前的回答:
其實這個問題已經很多客戶都有反應過,因為 Temp Data 的關係。因為在主程式下因 C 在叫用一些運算式時會使用到一些暫時儲存的 RAM ( temp data) 如果這時發生中斷,且中斷程式又做這些數學的計算時也會使用到相同的 Temp data 區域,所以原先的資料就被壞了。 所以中斷程式裡有用用到計算時就要特別小心,C18 裡有提供此 temp data 的 context saving 的功能 (紅色部分)。 User 自行定義的變數 : #pragma interrupt high_interrupt_service_routine save=myint 儲存自訂的 myint 變數 pragma interrupt high_interrupt_service_routine save=section("mydata") 儲存自訂變數節區 mydata 的變數 #pragma interrupt high_interrupt_service_routine nosave=section(".tmpdata") 儲存 temp data 區的資料 所以加入 .tempdata 這個節區的背景儲存就可以避免資料被破壞。重要! 重要! 書上都有說的。 http://www.microchip.com.tw/modules/n ... php?topic_id=5107&forum=1
發表於: 2008/4/29 15:31
|
|||
|
Re: c18中斷副程式使用除法運算
|
||||
---|---|---|---|---|
資深會員
|
在中斷副程式加上除法運算後,發現系統當機了,而且這個除法運算根本不可能執行,因為我這樣寫
if(INT0IF & INT0IE && 0) { uns16_spd=46083/sp_count; INT0IF=0; } 感覺好像是中斷或者主程式彼此覆蓋造成系統當機
發表於: 2008/4/29 15:09
|
|||
|
Re: c18中斷副程式使用除法運算
|
||||
---|---|---|---|---|
中級會員
|
檢查一下全域變數和區域變數上是否有衝突吧
或是使用不同變數名稱以策安全
發表於: 2008/4/29 14:04
|
|||
|
c18中斷副程式使用除法運算
|
||||
---|---|---|---|---|
資深會員
|
原本程式的LED都可以正常顯示,但在中斷裡加了16位元的除法運算之後,LED顯示便不正常了,但此16位元除法加在主程式,LED顯示也正常,好像是中斷裡使用16位元除法會改變主程式的LED相關的變數,請問需在中斷的進入點加入其他參數以保持其他在主程式變數的安全嗎?
發表於: 2008/4/29 13:40
|
|||
|