• slider image 442
  • slider image 483
  • slider image 484
  • slider image 485
  • slider image 486
  • slider image 487
  • slider image 488
  • slider image 491
:::


Browsing this Thread:   1 Anonymous Users






用c寫中斷的問題
#1
高級會員
高級會員


查看用戶資訊
請問用c寫的程式
在進入中斷或副程式前
如果變數宣告的愈多
進入中斷或副程式的時間就要愈久?
那麼想請問該如何有效的分配變數呢?

發表於: 2007/2/13 17:52
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 用c寫中斷的問題
#2
版主
版主


查看用戶資訊
在其它程式所使用到的變數應與中斷無關,主要是看你的中斷程式在運作時會是否會改變其它程式的變數,如會改到就需儲存起來。一般C都會自行運儲存,當然也可以特別指定去儲存。

變數的多寡與進入中斷或副程式的時間無關,如果是使用參數傳值的話就會增加進入函數的時間這使無法避免的 (中斷函數不可以帶有參數值)。

不是很清楚 "分配變數" 的意思?

發表於: 2007/2/14 9:55
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 用c寫中斷的問題
#3
高級會員
高級會員


查看用戶資訊
參照:

Ryang 寫到:
在其它程式所使用到的變數應與中斷無關,主要是看你的中斷程式在運作時會是否會改變其它程式的變數,如會改到就需儲存起來。一般C都會自行運儲存,當然也可以特別指定去儲存。

變數的多寡與進入中斷或副程式的時間無關,如果是使用參數傳值的話就會增加進入函數的時間這使無法避免的 (中斷函數不可以帶有參數值)。

版主對於您所說的我還是有點不清楚,您的意思是說中斷程式運作時有被影響到的變數才會在進入中斷時被儲存,我也用mplab試過了的確變數不同在進入中斷的時間是一樣的,可是再我使用icd2模擬後,多增加幾個變數,結果就不一樣了?可是我的程式看起來在中斷副程式中,會有影響的變數應該是一樣的,為什麼出來的結果就會有差呢?由於我的中斷副程式中與時間有關,是利用中斷來擷取timer的內容值,並在中斷中判斷timer內容值的大小作為條件,如果timer的內容值過小,就會因為我的主程式中多加了幾個變數而受到影響,所以我才會認為變數的多寡會影響進入中斷的時間。可以請版主幫我看看大概是為什麼嗎
#include <p18f452.h>
#include "diff_manchester.h"
#include "date.h"
#include "LCD1.h"
///////////////////////////////////////////////
void RFID_btoASCII(unsigned char *binary,unsigned char *country);
void isr_low(void);
void isr_high(void);
unsigned char T_STATUS;
///////////////////////////////////////////////
#pragma code high_vector=0x0008
void isr_high_direct(void)
{
_asm
    
goto isr_high
    _endasm
}
#pragma code
///////////////////////////////////////////////
#pragma code low_vector=0x0018
void isr_low_direct(void)
{
_asm
    
goto isr_low
    _endasm
}
#pragma code    
///////////////////////////////////////////////
#pragma interrupt isr_high
void isr_high(void)
{while(
PIR2bits.TMR3IF==1)
    {
PIR2bits.TMR3IF=0;
        
date_gen();}}
#pragma code
///////////////////////////////////////////////
#pragma interrupt isr_low
void isr_low(void)
{
diff_manchester();}
#pragma code
///////////////////////////////////////////////
const rom char LCD_MSG1[]={"Error"};
const 
rom char LCD_MSG2[]={"Set Time"};
const 
rom char LCD_MSG3[]={"Set Ok"};
const 
rom char LCD_MSG4[]={"Reading"};    
const 
rom char LCD_MSG5[]={"000101000000"};
const 
rom char LCD_MSG6[]={"yymmddH.M.S."};
unsigned char BCD_temp[2];
unsigned char DDaddr;    
unsigned char temp_k;
unsigned char time_display;

void main(void)
{
    
unsigned char country[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    
//unsigned char id[]={0,0,0,0,0,0,0,0,0,0,0,0};
 
unsigned char j;
 
unsigned int i;    
 
unsigned char l;[color=CC0000]<----[/color]
 
unsigned int m;[color=CC0000]<-----這兩個變數拿掉,執行的結果就是正確的[/color]

    
/*initial*/
    
TRISD=0xfc;
    
PORTD=0x00;
    
INTCON=0b11000000;
    
OpenLCD(0b00101100);
    while(
BusyLCD());
    
WriteCmdLCD(0b00001111);
    while(
BusyLCD());
 
WriteCmdLCD(0x01);
 
j=0;
 while(
j<7)
 {while(
BusyLCD());
     
WriteDataLCD(LCD_MSG4[j]);
     
j++;}     
    
OpenTimer3(0b10000111);
    
init_date();
    
init_diff_manchester();
    
time_display=0;
    
/*main*/    
    
while(1)
    {if(
MCT.STATUSbits.dataok==1)
     {
i=cal_crc(DATA.form.message[12],10);
         if((
MCT.STATUSbits.ASCIIok==0)&&(i==0))
         {
RFID_btoASCII(&DATA.form.message[12],country);
             
MCT.STATUSbits.ASCIIok=1;
             if(
MCT.STATUSbits.dataok==1)
             {
                while(
BusyLCD());
             
WriteCmdLCD(0x01);
                
j=16;
                do
             {while(
BusyLCD());
                 
WriteDataLCD(country[j-1]);
                 
j--;}while(j!=0); }}
            else if((
MCT.STATUSbits.ASCIIok==0)&&(i!=0))
            {
MCT.STATUSbits.error=1;
                
MCT.STATUSbits.dataok=0;}}

        else
        {
MCT.STATUSbits.ASCIIok=0;}


發表於: 2007/2/14 10:56
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 用c寫中斷的問題
#4
版主
版主


查看用戶資訊
參照:

#pragma interrupt isr_high
void isr_high(void)
{while(PIR2bits.TMR3IF==1)
{PIR2bits.TMR3IF=0;
date_gen();}}
#pragma code
///////////////////////////////////////////////
#pragma interrupt isr_low
void isr_low(void)
{diff_manchester();}
#pragma code


不知道 date_gen( ) & diff_manchester( ) 這兩個函數做作什麼? 是否這兩個函數還有用到其它的變數。
中斷所使用的變數最好加上 Volatile 宣告,而且最好放在 Access Bank 這樣速度可以快很多。

發表於: 2007/2/14 11:32
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 用c寫中斷的問題
#5
高級會員
高級會員


查看用戶資訊
參照:


不知道 date_gen( ) & diff_manchester( ) 這兩個函數做作什麼? 是否這兩個函數還有用到其它的變數。
中斷所使用的變數最好加上 Volatile 宣告,而且最好放在 Access Bank 這樣速度可以快很多。

在date_gen()&diff_manchester()中是還有用到其他的變數,大部分的變數我的宣告成global的型態,是因為要給其他的程式來使用,不過中斷中並沒有使用到
unsigned char l;
unsigned int m;
這兩個參數無關。這兩個參數本來是有在我接下來的程式中有使用到。不過目前我把其他的程式都刪除,只留下來這兩個變數與未加這兩個變數的程式來做比較,才發現這個問題的。
還有想請問版主Volatile的宣告是有什麼作用呢?因為看了work shop401的講義後,還是看不懂。

發表於: 2007/2/14 13:43
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 用c寫中斷的問題
#6
版主
版主


查看用戶資訊
1. 用 ICD2 無法計算程式或中斷的時間,建議用 MPALB SIM & Stepwatch Window 來看才會準確。
2. while(PIR2bits.TMR3IF==1 ; 改為 IF 的判斷
3. 懷疑 Timer 的中斷時間太短,導致中斷程式還沒做完,下一個中斷旗號又被設為1 了

發表於: 2007/2/14 18:02
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 用c寫中斷的問題
#7
高級會員
高級會員


查看用戶資訊
後來我將main()中的主要的那段程式改成一個副程式_11785_decoder(),
並且將_11785_decoder()及中斷中所需要用到的變數,改成宣告在main()的下面,本以為這樣是代表是將這些變數變成該區域才能看到的副程式,可是再實際模擬時,我將斷點設在main()中時,還是可以在watch中看到這些變數,這個意思是這些變數的視野在main()中也可以看的到嗎??不過好像又不是這樣,因為如果我在main()中有用到這些變數的操作,再complier的時後又會出現error告知這個變數沒有被定義,因為我才剛開始學c所以很多地方不太清楚,可以麻煩知道的人幫我解釋嗎?
不過將我原來的程式改成這樣後,main()中或main()前就可以多定義幾個變數而不會像之前影響進入中斷的速度了,不過現在又發生了一個問題,就是會容易當機,當機後程式會停在program memory address 0x0000 goto _startup的地方,我有猜想可能是堆疊錯誤,看了stkptr這個暫存器他內容值為0b1100xxxx再對照了datasheet後發現應該是溢位了,結果我就reset發現他復位的值就是0xc0,請問不是要溢位了才會將stkptr的位元7設為1嗎?
#include <p18f452.h>
//#include "diff_manchester.h"
#include "date.h"
#include "LCD1.h"
///////////////////////////////////////////////
void RFID_btoASCII(unsigned char *binary,unsigned char *country);
void isr_low(void);
void isr_high(void);
///////////////////////////////////////////////
#pragma code high_vector=0x0008
void isr_high_direct(void)
{_asm
goto isr_high
_endasm
}
#pragma code
///////////////////////////////////////////////
#pragma code low_vector=0x0018
void isr_low_direct(void)
{_asm
goto isr_low
_endasm
}
#pragma code
///////////////////////////////////////////////
#pragma interrupt isr_high
void isr_high(void)
{if(PIR2bits.TMR3IF==1)
{PIR2bits.TMR3IF=0;
date_gen();}}
#pragma code
///////////////////////////////////////////////
#pragma interrupt isr_low
void isr_low(void)
{diff_manchester();}
#pragma code
///////////////////////////////////////////////
const rom char LCD_MSG1[]={"Error"};
const rom char LCD_MSG2[]={"Set Time"};
const rom char LCD_MSG3[]={"Set Ok"};
const rom char LCD_MSG4[]={"Reading"};
const rom char LCD_MSG5[]={"000101000000"};
const rom char LCD_MSG6[]={"yymmddH.M.S."};
unsigned char BCD_temp[2];
unsigned char temp_k;
unsigned char time_display;

void _11785_decoder(void);
void ASCII(unsigned char BCD);

void main(void)
{unsigned char i;
unsigned char j;
unsigned char m;
unsigned char l;
unsigned char g;
unsigned char e;
/*initial*/
TRISD=0xfc;
PORTD=0x00;
INTCON=0b11000000;
OpenLCD(0b00101100);
while(BusyLCD());
WriteCmdLCD(0b00001111);
while(BusyLCD());
WriteCmdLCD(0x01);
j=0;
while(j<7)
{while(BusyLCD());
WriteDataLCD(LCD_MSG4[j]);
j++;}
OpenTimer3(0b10000111);
init_date();
init_diff_manchester();
time_display=0;
/*main*/
while(1)
{
_11785_decoder();}

///////////////////////////////////////////////
union{
unsigned char bytes[15];
struct{
unsigned int head;
unsigned char message[13];
}form;
struct{
unsigned headbit0:1;
unsigned headbits7:7;
unsigned headbits15:8;
unsigned bit0:1;
}bits;
}DATA;
union{
unsigned char STATUS;
struct {
unsigned dataok:1;
unsigned findhead:1;
unsigned correct:1;
unsigned error:1;
unsigned onebitready:1;
unsigned lastbitlevel:1;
unsigned twobeonebit:1;
unsigned ASCIIok:1;
}STATUSbits;
}MCT;
unsigned char check_up;
unsigned char data_number;
void _11785_decoder(void)
{

near unsigned char country[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//unsigned char id[]={0,0,0,0,0,0,0,0,0,0,0,0};
unsigned char j;
unsigned int i;
if(MCT.STATUSbits.dataok==1)
{i=cal_crc(DATA.form.message[12],10);
if((MCT.STATUSbits.ASCIIok==0)&&(i==0))
{RFID_btoASCII(&DATA.form.message[12],country);
MCT.STATUSbits.ASCIIok=1;
if(MCT.STATUSbits.dataok==1)
{
while(BusyLCD());
WriteCmdLCD(0x01);
while(BusyLCD());
SetDDRamAddr(0x80);

j=16;
do
{while(BusyLCD());
WriteDataLCD(country[j-1]);
j--;}while(j!=0); }}
else if((MCT.STATUSbits.ASCIIok==0)&&(i!=0))
{MCT.STATUSbits.error=1;
MCT.STATUSbits.dataok=0;}}

else
{MCT.STATUSbits.ASCIIok=0;}}

發表於: 2007/2/15 13:22
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... ]

教育訓練中心

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