判斷電位間隔的時間
|
||||
---|---|---|---|---|
高級會員
|
我想利用下面的程式去計算高電位或低電位維持的時間,我使用pic18f452 20MHz 而我RC2上接的信號頻率為240ms時 高電位維持120ms,低電位120ms
依照我的程式來看應該執行一個指令時間為0.2us 所以跑完下面的判斷式後 i 的值應該會為120,我在sim模式下模擬時,使用模擬RC2接腳的方式去模擬,確實 i 值為120但是用icd2模擬時,此值就不為120而是1到3這個範圍的值,不知道是哪裡出錯了,請各位幫幫忙 while(1) {i=0; while(PORTCbits.RC2==MCT.bit0) {Delay1KTCYx(5); i++;} MCT.bit0=PORTCbits.RC2;}
發表於: 2007/3/9 12:57
|
|||
|
Re: 用c寫中斷的問題
|
||||
---|---|---|---|---|
高級會員
|
後來我將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
|
|||
|
Re: 用c寫中斷的問題
|
||||
---|---|---|---|---|
高級會員
|
參照:
在date_gen()&diff_manchester()中是還有用到其他的變數,大部分的變數我的宣告成global的型態,是因為要給其他的程式來使用,不過中斷中並沒有使用到 unsigned char l; unsigned int m; 這兩個參數無關。這兩個參數本來是有在我接下來的程式中有使用到。不過目前我把其他的程式都刪除,只留下來這兩個變數與未加這兩個變數的程式來做比較,才發現這個問題的。 還有想請問版主Volatile的宣告是有什麼作用呢?因為看了work shop401的講義後,還是看不懂。
發表於: 2007/2/14 13:43
|
|||
|
Re: 用c寫中斷的問題
|
||||
---|---|---|---|---|
高級會員
|
參照:
版主對於您所說的我還是有點不清楚,您的意思是說中斷程式運作時有被影響到的變數才會在進入中斷時被儲存,我也用mplab試過了的確變數不同在進入中斷的時間是一樣的,可是再我使用icd2模擬後,多增加幾個變數,結果就不一樣了?可是我的程式看起來在中斷副程式中,會有影響的變數應該是一樣的,為什麼出來的結果就會有差呢?由於我的中斷副程式中與時間有關,是利用中斷來擷取timer的內容值,並在中斷中判斷timer內容值的大小作為條件,如果timer的內容值過小,就會因為我的主程式中多加了幾個變數而受到影響,所以我才會認為變數的多寡會影響進入中斷的時間。可以請版主幫我看看大概是為什麼嗎
#include <p18f452.h>
發表於: 2007/2/14 10:56
|
|||
|
用c寫中斷的問題
|
||||
---|---|---|---|---|
高級會員
|
請問用c寫的程式
在進入中斷或副程式前 如果變數宣告的愈多 進入中斷或副程式的時間就要愈久? 那麼想請問該如何有效的分配變數呢?
發表於: 2007/2/13 17:52
|
|||
|
Re: 請問timer3中斷的使用
|
||||
---|---|---|---|---|
高級會員
|
我將原本的
OpenTimer3(0b10000111); 改成這樣就可以了 TRISD=0xfc; PORTD=0x00; INTCON=0b11000000; OpenTimer3(0b10010111); 這樣應該是預分頻1:2
發表於: 2007/2/7 15:48
|
|||
|
請問timer3中斷的使用
|
||||
---|---|---|---|---|
高級會員
|
我使用p18f452寫了一個timer3的中斷程式
用32768hz的外部震盪,接在RC0跟RC1 想要每兩秒中斷一次,所以我TMR3L跟TMR3H都置0 (1/32768)*65536=2 然後我在中斷副程式中使用RD0去觀察輸出信號 每次進入中斷副程式就將RD0反相, 但是我在是波器上面看到信號每1.5秒左右就反相一次了, 後來我用脈波產生器調到32768Hz結果這次是1秒左右就反相了? 請問是什麼原因呢
發表於: 2007/2/7 14:49
|
|||
|
Re: 請問C中斷的問題
|
||||
---|---|---|---|---|
高級會員
|
恩 我有用到capture的功能了
我現在是要做差分曼徹斯特的解碼 所以我的想法是捕捉電位準的改變 然後去判斷他位準改變的時間是不是在合理的改變範圍內 例如有一個差分曼徹斯特碼為10 01 01 10 01--->0 1 0 1 1 我的解法是看作 1 00 10 11 00 1.... 遇到出現00 或 11時 解出為1 事實上是判斷發生中斷的時間 假設曼徹斯特碼01每次電位改變的時間為120uS 而001為240uS 當時間抓到為連續兩次的每次中斷時間間隔為120(+-10%)就判斷為0 當時間抓到為每次中斷時間間隔為240(+-10%)就判斷為1 超過這些時間就判斷為錯誤 這樣如果我是使用4MHz加中斷進入副程式的時間花掉101uS,因為進入中斷副程式花掉62uS, 離開中斷回到主程式花了52uS,這樣加起來就花掉了215uS 這樣就超過了我在解曼徹斯特0所需的時間了。 接下來還要處理移位(來接收完112bit)所需要處理的時間。 所以要解出0就無法解出了,雖然硬體可以判斷到中斷的發生,也抓的到每次中斷間隔的時間,但是來不及用這些數據去判斷1或0,我的想法是這樣,不知道有沒有錯。
發表於: 2007/2/5 14:34
|
|||
|
Re: 請問C中斷的問題
|
||||
---|---|---|---|---|
高級會員
|
果然是遇到大災難了
之前試好的程式只能單獨跑 不能加到我的主程式中 現在又回到原來的問題了 進入中斷後的處理時間不夠 造成我在取樣的時間沒辦法正確的解出我要的信號 除了換震盪器以外 請問還有什麼辦法呢
發表於: 2007/2/5 11:09
|
|||
|