• slider image 514
  • slider image 516
  • slider image 517
  • slider image 518
  • slider image 519
:::


Browsing this Thread:   2 Anonymous Users






Re: c18中斷副程式使用除法運算
#10
資深會員
資深會員


查看用戶資訊
謝謝大家的幫忙,問題已經解決了,因為我的中斷副程式裡有一個Timer2中斷,他的時間只有100us,因為多加了這條件判斷及運算式,造成在中斷副程式還沒跳出之前,Timer2又中斷了,我將Timer2中斷時間延長就可以跳出中斷副程式了,我的作法可能會將運算式寫在主程式或者將系統的時脈調高,在此感謝大家的幫忙。

發表於: 2008/5/2 11:24
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: c18中斷副程式使用除法運算
#9
資深會員
資深會員


查看用戶資訊
謝謝你提供的方法,但uns16_spd及sp_count我本來就是宣告全域變數其型態為unsigned int,或許你的方法可行,但這樣也太麻煩了,這就失去用C寫的意義了,更何況uns16_spd=6083/sp_count;在中斷副程式根本沒執行,難道這樣也會造成系統一直在中斷迴圈裡打轉嗎?

發表於: 2008/5/2 10:42
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: c18中斷副程式使用除法運算
#8
中級會員
中級會員


查看用戶資訊
那麼以下供你參考, 取代 uns16_spd=46083/sp_count;
(事實上就是無號16 bit 除法的計算展開, 避免主程式與中斷都有使用除法的一些問題產生)

(使用的變數宣告為全域好了...)

union unsigned long _DIV_long;
        
unsigned int  _DIV_int[2];
      } 
_DIV_SHIFT;
#define  _DIV_A       _DIV_SHIFT._DIV_int[0]
#define  _DIV_R       _DIV_SHIFT._DIV_int[1]
unsigned int  _DIV_B_DIV_Q;
unsigned char _DIV_N;

   .
   .
   .

if(
INT0IE && INT0IF)
  {
    
stop_count=0;
    if(
mode_select==0)//not setup mode
      
{
        
bit_start=TRUE; [color=CC0000]

       
_DIV_A 46083;        // _DIV_Q = _DIV_A / _DIV_B
       
_DIV_B sp_count;
       
_DIV_Q 0;
       
_DIV_R 0;
       for(
_DIV_N 0_DIV_N 16_DIV_N++)
           { 
_DIV_SHIFT._DIV_long <<= 1;
             
_DIV_Q <<= 1;
             if(
_DIV_R >= _DIV_B)
               { 
_DIV_R -= _DIV_B;
                 
_DIV_Q++;
               }
           }    
        
uns16_spd _DIV_Q; [/color]

      }
    
INT0IF=0;
}

-----------------------------------------------------------
最後, 請注意!
不管是使用 c 語言的除法 或 自行構成的除法, 都會蠻有一段執行時間的.(因為 pic18 是 8 bit MCU 的關係)
請注意是否會對你的程式造成影響.

發表於: 2008/4/30 17:04
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: c18中斷副程式使用除法運算
#7
資深會員
資深會員


查看用戶資訊
你好,感謝你的回覆,原本是沒有&& 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
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: c18中斷副程式使用除法運算
#6
中級會員
中級會員


查看用戶資訊
這... 你的程式中只有這裡特別不一樣
你要不要把它去掉試一下...

#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[color=CC0000] && 0[/color])
{
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


---------------------------------------------------
多了這幾個字, INT0 好像會不執行,
如果 INT0 不執行, INT0IF 也不會被清除, 那就會卡在中斷不執行主程式了.

發表於: 2008/4/29 16:22
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: c18中斷副程式使用除法運算
#5
資深會員
資深會員


查看用戶資訊
版主你好,我已加入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
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: c18中斷副程式使用除法運算
#4
版主
版主


查看用戶資訊
參考以前的回答:
其實這個問題已經很多客戶都有反應過,因為 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
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: c18中斷副程式使用除法運算
#3
資深會員
資深會員


查看用戶資訊
在中斷副程式加上除法運算後,發現系統當機了,而且這個除法運算根本不可能執行,因為我這樣寫
if(INT0IF & INT0IE && 0)
{
uns16_spd=46083/sp_count;
INT0IF=0;
}
感覺好像是中斷或者主程式彼此覆蓋造成系統當機

發表於: 2008/4/29 15:09
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: c18中斷副程式使用除法運算
#2
中級會員
中級會員


查看用戶資訊
檢查一下全域變數和區域變數上是否有衝突吧

或是使用不同變數名稱以策安全

發表於: 2008/4/29 14:04
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


c18中斷副程式使用除法運算
#1
資深會員
資深會員


查看用戶資訊
原本程式的LED都可以正常顯示,但在中斷裡加了16位元的除法運算之後,LED顯示便不正常了,但此16位元除法加在主程式,LED顯示也正常,好像是中斷裡使用16位元除法會改變主程式的LED相關的變數,請問需在中斷的進入點加入其他參數以保持其他在主程式變數的安全嗎?

發表於: 2008/4/29 13:40
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部







You can view topic.
不可以 發起新主題
You cannot reply to posts.
You cannot edit your posts.
You cannot delete your posts.
You cannot add new polls.
You cannot vote in polls.
You cannot attach files to posts.
You cannot post without approval.
You cannot use topic type.
You cannot use HTML syntax.
You cannot use signature.
You cannot create PDF files.
You cannot get print page.

[進階搜尋]


:::

Microchip連結

https://www.facebook.com/microchiptechnologytaiwan/
http://www.microchip.com.tw/modules/tad_uploader/index.php?of_cat_sn=13
https://mu.microchip.com/page/tmu
http://elearning.microchip.com.tw/modules/tad_link/index.php?cate_sn=1
https://page.microchip.com/APAC-PrefCenters-TW.html
http://www.microchip.com/
http://www.microchip.com/treelink
http://www.microchipdirect.com/
http://www.microchip.com.cn/newcommunity/index.php?m=Video&a=index&id=103
http://www.microchip.com.tw/modules/tad_uploader/index.php?of_cat_sn=2
http://www.microchip.com.tw/Data_CD/eLearning/index.html
http://www.microchip.com.tw/RTC/RTC_DVD/
https://www.microchip.com/development-tools/
https://www.youtube.com/user/MicrochipTechnology
[ more... ]

教育訓練中心

!開發工具購買
辦法說明 [業界客戶] [教育單位]
----------------------------------
!校園樣品申請
辦法說明 [教師資格] [學生資格]
----------------------------------