會員登陸
帳號:

密碼:

記住我



忘記密碼?

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


正在流覽:   1 名訪客





如何在PIC16實作優先權中斷?
中級會員
註冊日期:
2014/09/29 12:04
所屬群組:
註冊會員
文章: 66
等級: 7; EXP: 2
HP : 0 / 150
MP : 22 / 1414
離線
各位好,我想要試著把問題明確地表達給各位先進,如果資訊有哪邊不完全或者文字敘述表達的不夠清楚,歡迎提出。
另外,如果在內文中發現觀念有誤,請提出來讓我知道,好讓我有頭緒該補足哪方面的不足。

我想要寫一隻程式,這隻程式總共有三個工作要做,分別是
1. I2C通訊(task 1)
2. 閃爍LED(task 2)
3. 判斷電池狀態流程(task 3)

task 1先利用通訊得知電池的資訊,task 3接收資訊後,判斷電池是在哪個狀態,task 2再決定要怎麼閃爍LED。

我現在的"想法"(還沒實作)是寫一個1ms的timer(TQ = 1ms),在中斷裡面設counter,然後主程式依序對這三個工作執行(multi-tasking)。

所謂的counter,即是在TMR的中斷副程式裡寫下(counter為全域變數):
counter++;
if(counter == 3){
counter = 0;
}
然後在main loop裡面寫:
if(counter % 3 == 1){
//do task 2
}

if(counter % 3 == 2){
//do task 3
}

if(counter % 3 == 0){
//do task 1
}

但是這裡有個問題。第二份工作(閃爍LED)一定要在1ms執行完,不行在中途被打斷(如果被打斷,使用者會看到LED亂閃)

所以我想要請教的是。
1.如何知道第二份工作有沒有辦法在1ms執行完?換言之,如何知道第二份工作的burst time?
2.假如第二份工作無法在1ms執行完,那如何使用PIC16實作有優先權的中斷?(Note:PIC18有高低優先權的中斷向量,PIC16則無)


關於第二個問題,我自己的想法如下:
如果我要讓第二份工作不被打斷,勢必要有兩個中斷源,那我就必須再加一組timer近來。以XC8來說,當進入中斷時會把GIE = 0,離開中斷才會再把GIE = 1。那...意思是我要自己寫到底層(組語)把這個流程關掉嗎?感覺有點不切實際,還是PIC16本身就是因為這個限制,才沒有辦法支援優先權的中斷源?

(附註:其實如果沒辦法使用有優先權的中斷,也是有其他的替代方案可以選擇,比如加快CPU速度、延長TQ的時間。但想說未來CPU的task變多時,還是會遇到這個問題,故先行發文與先進們討教)

謝謝各位撥冗看完此篇發文,如有不足麻煩指點後輩。

12月05日 14:04:12

firststop0 於 2017年12月05日 14:22:37
轉換PDF檔 列印


Re: 如何在PIC16實作優先權中斷?
資深會員
註冊日期:
2004/07/23 16:25
所屬群組:
註冊會員
文章: 1178
等級: 29; EXP: 96
HP : 0 / 724
MP : 392 / 28352
離線
想太多,要什麼優先權? 如果是 i2c master 中斷不用,一直loop 就可

pseudo code 大概就這

i2c_isr
()
{
    
收資料
    
    
if 資料收完
        set data_flag
}



main_LOOP(){

    if(
data_flag=1){
        
data_flag=0
        資料分析
        
        led_status_renew
()
    }

    if
time0_flag(set){    //4ms 中斷一次
        
time0_flag_clear
        ex
:電池正`瓻G、電剩一半 500ms  on off 切換 、 快沒電了 500ms off/ 50ms on
        
        if led_status= 正
`
            
led =on
        
else if led_status = @{
            
led_count--
            
            if(
led_count=0){
                if
led_on{
                    
led_off
                    led_count
= 500/4
                
}
                else {
                    
led_on
                    led_count
= 500/4
                
}
                
            }
        }else if
led_status = 快沒電{
            
led_count--
            
            if(
led_count=0){
                if
led_on{
                    
led_off
                    led_count
= 500/4
                
}
                else {
                    
led_on
                    led_count
= 50/4
                
}
                
            }
        }        
    }

}



如果是 i2c master ,整個都是由你主控,連i2c中斷都不用


main loop
{
    if
timer0_flag set{
        
timer0_flag clr    //4ms觸發一次
        
i2c_count--
        if
i2c_count =0{
            
i2c_count=250    //1sec 處理一次 i2c
            
            
i2c read / write / analyze  generate battery_status
        
}

        if
led_status= `    //4ms 處理一次
            led =on
        else if led_status = 一半
{
            led_count--
            
            if(led_count=0)
{
                if led_on
{
                    led_off
                    led_count= 500/4
                
}
                else
{
                    led_on
                    led_count= 500/4
                
}
                
            
}
        
}else if led_status = 快沒電{
            led_count--
            
            if(led_count=0)
{
                if led_on
{
                    led_off
                    led_count= 500/4
                
}
                else
{
                    led_on
                    led_count= 50/4
                
}
                
            
}
        
}        
        
    
    
}
}

12月05日 20:19:29
轉換PDF檔 列印






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

[進階搜尋]


搜尋
Microchip連結

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