會員登陸
帳號:

密碼:

記住我



忘記密碼?

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


正在流覽:   1 名訪客





Input Capture 脈波寬度量測
新會員
註冊日期:
2月12日 19:41:18
所屬群組:
註冊會員
文章: 8
等級: 1; EXP: 73
HP : 0 / 18
MP : 2 / 41
離線
請教各位前輩:
在使用Input Capture時,選擇Edge Detect模式,
時脈來源為Fosc/2,Fosc為8MHz,
運用訊號產生器產生1KHz Duty為25%的訊號做為測試,
脈波寬度量測到的數值比較後相減,
然後打印至終端機檢查數值,
發現數值會出現100X與300X,
若使用Rising或Falling會讀到400x,
與實際1KHz用Fosc/2計算為4000,
代表著抓到了duty 25%與75%的數值,
但若只想要抓取Pluse的數值(25%),
在程式上有什麼技巧可以使用?

使用晶片為PIC24FV16KM202

5月30日 18:01:10
轉換PDF檔 列印


Re: Input Capture 脈波寬度量測
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14158
等級: 72; EXP: 52
HP : 1072 / 1788
MP : 4719 / 70895
離線
PIC24F & dsPIC33 等 16-bit 系列產品,單單研讀其 Data Sheet 是不夠詳細的,還是要下載 PIC24F 系列的 "PIC24f Timers" 下來研讀才能了解這 Timers 模組的各項使用放式。

在 PIC24FV16KM204 的主頁上,底下的 Documents 的選卡可以找到各周邊的詳細使用手冊:
http://ww1.microchip.com/downloads/en/DeviceDoc/39704a.pdf

1. 如果輸入的週期是固定的且知道的話,最簡單測量輸入的 Duty Cycle 的方式是: 使用 Timer1 的 Gate Time 功能來量測。
如圖所示,Gate Timer 的計時只會在輸入腳為 1 時才會進入計時量測,每當輸入訊號並下緣時就會發生 Gate Time 中斷,這時只要在中斷裡將技數值讀取後並清除。這樣就可以輕鬆測量輸入的 Duty Cycle 了。

2. 如果輸入訊號式可變得沒有固定週期的話,這就要用到 Input Capture 了。如圖二所示,選擇 0000 = Capture every rising/falling edge 的功能。分別抓下上/下緣的值就可以知道 Period 及 Duty Cycle 的值。

附加檔案:



jpg  擷取1.jpg (44.79 KB)
16_592e4c1ae32be.jpg 804X393 px

jpg  擷取.JPG (72.57 KB)
16_592e4e5db44c0.jpg 780X425 px

5月31日 12:52:11
轉換PDF檔 列印


Re: Input Capture 脈波寬度量測
新會員
註冊日期:
2月12日 19:41:18
所屬群組:
註冊會員
文章: 8
等級: 1; EXP: 73
HP : 0 / 18
MP : 2 / 41
離線
感謝板主回答:
需要的確實是週期會改變,所以使用input capture,
但是用edge detect 跟 Capture every rising/falling edge
兩者是相同的(Section.64有說明),
先使用 1Khz與25% Duty做為測試,
讀到的數值會有pulse寬度以及訊號為0的寬度,
該如何避免讀取到Pulse以外的訊號呢?

5月31日 15:32:58
轉換PDF檔 列印


Re: Input Capture 脈波寬度量測
資深會員
註冊日期:
2012/05/04 19:18
所屬群組:
註冊會員
文章: 183
等級: 12; EXP: 58
HP : 0 / 289
MP : 61 / 4699
離線
程式po出來看看~~

6月01日 12:19:06
轉換PDF檔 列印


Re: Input Capture 脈波寬度量測
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14158
等級: 72; EXP: 52
HP : 1072 / 1788
MP : 4719 / 70895
離線
引用:

AgentKan 寫道:
感謝板主回答:
需要的確實是週期會改變,所以使用input capture,
但是用edge detect 跟 Capture every rising/falling edge
兩者是相同的(Section.64有說明),
先使用 1Khz與25% Duty做為測試,
讀到的數值會有pulse寬度以及訊號為0的寬度,
該如何避免讀取到Pulse以外的訊號呢?


我之前用 PIC18F 的 Input Cature 做法是:

我是以 1:1 的 rising 的觸發為主,進入中斷時將 Timer1 清除為 0,並將 ECPR1H/ECCPE1L 存入 Period 的 Buffer,這時也同時變更為 falling 的中斷觸發並返回主程式。

接下來將產生 falling egde 的中斷,立即抓下 ECPR1H/ECCPE1L 存入 Duty 的 Buffer。更改下一次中斷觸發為 rising egde 做下一次新週期的抓取。

如此就有 Period 及 Duty 的計數值。當然你不用隨時隨地的都在中斷裡抓取數值,你可以在背景裡抓值,有需要時再拿來用。
或許也可以取一下平均值後再使用。

6月01日 15:50:31
轉換PDF檔 列印


Re: Input Capture 脈波寬度量測
新會員
註冊日期:
2月12日 19:41:18
所屬群組:
註冊會員
文章: 8
等級: 1; EXP: 73
HP : 0 / 18
MP : 2 / 41
離線
板主您好:
使用Rising進中斷後改成Falling,讀取到的數值會不正常,
但是在更改狀態的地方附加I/O控制用示波器觀察示對的,
以下是中斷常式
void __attribute__ ( ( interrupt, no_auto_psv ) ) _CCP1Interrupt ( void )
{

if(IFS0bits.CCP1IF)
{
if(FLAGbits.first)
{
FLAGbits.first = 0;
CCP1CON1Lbits.MOD = 0b0010;
GLED = 1;
}
else
{
FLAGbits.first = 1;
CCP1CON1Lbits.MOD = 0b0001;
GLED = 0 ;
}
InputCaptureB.IC_word[0] = MCCP1_CAPTURE_Data32Read();
InputCaptureB.IC_word[1] = MCCP1_CAPTURE_Data32Read();
InputCaptureA.IC_word[0] = MCCP1_CAPTURE_Data32Read();
InputCaptureA.IC_word[1] = MCCP1_CAPTURE_Data32Read();
IFS0bits.CCP1IF = 0;
}
}

拿取數值的程式放在判if(FLAGbits.first)判斷式內,也會有錯誤。

使用原本的edge detect 與更改 Rising/Falling量測到的I/O波形都是正確的!
edge detect 總是會量到Falling to Rising 那一段。
附圖有
edge detect mode Duty顯示
量測到的中斷波型

附加檔案:



jpg  UART_Duty.jpg (73.72 KB)
50944_593124a042d5d.jpg 717X842 px

jpg  170602_163422.jpg (93.39 KB)
50944_593124d82d324.jpg 640X454 px

6月02日 16:42:29
轉換PDF檔 列印


Re: Input Capture 脈波寬度量測
資深會員
註冊日期:
2012/05/04 19:18
所屬群組:
註冊會員
文章: 183
等級: 12; EXP: 58
HP : 0 / 289
MP : 61 / 4699
離線
(1)我是認為假設你是要量duty,程式在initialize的時候就先預設模式為rising,那你就必須等待rising中斷的發生,發生中斷之後將buffer的值拿出來,並改成falling等待中斷,fall中斷後再將buffer的值拿出來,兩筆數值再進行運算,可能會有前後兩筆誰大誰小的問題,要用環狀的概念來想你兩筆數據的運算,打個比方,時針指向50分然後20分鐘後時針指向10分,兩筆差值只有20分鐘,你可別用50 - 10 = 40來計算,
(2)不懂你怎麼需要一次讀四筆的資料呢?而且你的IC_word[0]及IC_word[1]會被覆蓋掉,怎麼感覺程式的寫法有些問題
InputCaptureB.IC_word[0] = MCCP1_CAPTURE_Data32Read();
InputCaptureB.IC_word[1] = MCCP1_CAPTURE_Data32Read();
InputCaptureA.IC_word[0] = MCCP1_CAPTURE_Data32Read();
InputCaptureA.IC_word[1] = MCCP1_CAPTURE_Data32Read();

6月03日 08:35:17
轉換PDF檔 列印


Re: Input Capture 脈波寬度量測
新會員
註冊日期:
2月12日 19:41:18
所屬群組:
註冊會員
文章: 8
等級: 1; EXP: 73
HP : 0 / 18
MP : 2 / 41
離線
在初始化有嘗試改成Rising中斷後再改Falling,但第一次中斷就拿的數值讀出來是不正確的。
一次讀四筆資料是一次拿取4層FIFO的數值,參考CE365 的中斷去改寫
以下是CE365的Input Capture 中斷
void __attribute__((interrupt,no_auto_psv)) _IC1Interrupt(void)
{
cap1 = IC1BUF;
cap2 = IC1BUF;
IFS0bits.IC1IF = 0;
}
而我使用32bit timer時,4層FIFO(16bit)只會有2筆資料量的存放。

現在使用edge detect在主程式內有的延遲迴圈會使input capture 抓到的數值正確,但還是有個小bug,Timer的溢位。
有在中斷內做程式判斷與清除TMR ,但似乎無效。

6月03日 16:55:58
轉換PDF檔 列印


Re: Input Capture 脈波寬度量測
資深會員
註冊日期:
2012/05/04 19:18
所屬群組:
註冊會員
文章: 183
等級: 12; EXP: 58
HP : 0 / 289
MP : 61 / 4699
離線
所以你目前的方式還是讓人感覺怪怪的,用你宣告的兩個RAM連續去拿FIFO,
FIFO(first in first out)這句話代表說你可能一開始拿兩筆的是正確的,
後面拿的不代表你buffer已經寫滿?不知道有沒有數值已經寫進去FIFO?
InputCaptureB.IC_word[0] = MCCP1_CAPTURE_Data32Read();
InputCaptureB.IC_word[1] = MCCP1_CAPTURE_Data32Read();
InputCaptureA.IC_word[0] = MCCP1_CAPTURE_Data32Read();
InputCaptureA.IC_word[1] = MCCP1_CAPTURE_Data32Read();

我看CE365很簡單,單純用來計算頻率,而且他程式中還有判定
if (((cap1==0)&&(cap2!= 0)) || (cap1>cap2))
{// reset Timer3 if cap1 is greater than cap2
T3CONbits.TON = 0;
TMR3=0;
T3CONbits.TON = 1;
}
很明顯的CAP1拿到的值是First in 的值,因此第二筆CAP2應該要比第一筆的值大,若否,應該是有發生溢位了!
相對地你用來計算週期只要RISING & FALLING持續的TOGGLE就可以了,
同樣的觀念套用近來,應該不會有多大的差異才對!

請注意你中斷為幾次RISING幾次FALL EDGE發生一次?這跟你拿FIFO的時間點有關
CE365程式當中有設定以下
void capinit1(void)
{
IC1CONbits.ICM = 3; //capture edge every rising edge
IC1CONbits.ICI = 1; //兩次CAPTURE發生一次中斷
IC1CONbits.ICTMR = 0; //used tmr3
IC1CONbits.ICSIDL = 0;
}

還是建議你將CODE再仔細檢查一下,應該寫法有些錯誤!

6月05日 11:23:14
轉換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