Re: PIC16F1823 中斷應用
|
||||
---|---|---|---|---|
版主
|
當然 OVP & OCP (Over Current Protection) 是要用比較器來完成,這樣速度才會夠快達到保護的工能。一般使用 ADC 是用來控制輸出的電壓或電流,不要那來當過壓及過流的保護。如此一來 ADC 的轉換速度就不用太快了。
發表於: 2021/7/30 23:19
|
|||
|
Re: PIC16F1823 中斷應用
|
||||
---|---|---|---|---|
版主
|
1. 如果你有在主程式呼叫ADC轉換函數的話,那就不能在中斷裡有呼叫 ADC 函數的動作,因為當主程式呼叫 ADC 函數時,也 ADC 模駔正作用到抹個階段而被中斷的 ADC 搶宿執行權限,這樣會造成時正常時不正常的轉換動作。所以不可同時在主程式及中斷裡共同使用同一個函數。
2. 1us 的中斷似乎太快了,你先查一下PIC16F1823 的 Data Sheet 上所標示的最短取樣時間再加上 12tad 的轉換時間,這就是 ADC 真正所需的時間。PIC16F1xxxx 系列無法有這麼快的轉換時間。如過要這麼快可以找PIC18F Q 系列看看。不知道你的應用為何?需要到 1uS 的轉換時間。 3. 通常使用旗號來通知主程式做某件事情是很常用的也是必須學會的技巧。Timer1 是 Reload 的架構,建議改用 Timer2 。因為 Timer2 是屬於比較模式,計數器會自動歸零不用重新載入數值,可以縮短中斷處理的整體時間。 4. 先確定 ADC 函數可以在主程式下正常執再改成以ADC中斷放市執行方式執行,ADC 中斷函數只作兩件事 : 1. 清除 ADCIF 旗號 2. 將 ADC Result 存入Buffer 中 3. Return (只要將 while( ) 那行刪除)。
發表於: 2021/7/30 10:50
|
|||
|
Re: PIC16F1823 中斷應用
|
||||
---|---|---|---|---|
資深會員
|
參照:
ADC 不是也有中斷 ? 用ADC 中斷去做你想做的行為不就好了?
發表於: 2021/7/29 23:12
|
|||
|
PIC16F1823 中斷應用
|
||||
---|---|---|---|---|
新會員
|
各位好,我剛入門C也是第一次用PIC16F1823,開發環境為 MPLAB X IDE 5.50+XC8 2.31+MCC 4.2.3
我有一個功能是藉由ADC轉換後再針對其值判斷而做不同的行為,但我需要每1us就去偵測判斷 所以我想到了使用中斷執行。如果我用timr0去做1us的時間中斷,再去讀取ADC(使用MCC產生的ADC_GetConversion函式) 但是我在主程式中也有用到ADC_GetConversion這個函式,假如我進入中斷前剛好在執行這個ADC_GetConversion函式,會不會影響我中斷執行時的轉換?是否需要在另外寫一個給中斷使用? 另外,因為我怕中斷程式時間太長導致又觸發中斷,所以我想在中斷產生一個旗標,然後在結束中斷後直接跳去該旗標的地方執行其他程式,請問該怎麼去寫這段? 還是我只要將ISR中INTCONbits.TMR0IF = 0;移到中斷程式的最後一步就可以等全部都做完後再開始重新計數timer0? 如下為兩個用到的函式 ----------------------------------------------------------------------------------------------------------- MCC ADC 函式: adc_result_t ADC_GetConversion(adc_channel_t channel) { // select the A/D channel ADCON0bits.CHS = channel; // Turn on the ADC module ADCON0bits.ADON = 1; // Acquisition time delay __delay_us(ACQ_US_DELAY); // Start the conversion ADCON0bits.GO_nDONE = 1; // Wait for the conversion to finish while (ADCON0bits.GO_nDONE) { } // Conversion finished, return the result return ((adc_result_t)((ADRESH << 8) + ADRESL)); } ----------------------------------------------------------------------------------------------------------- timer0 isr void TMR0_ISR(void) { uint16_t ADC_OVP; // Clear the TMR0 interrupt flag INTCONbits.TMR0IF = 0; TMR0 = timer0ReloadVal; if(TMR0_InterruptHandler) { TMR0_InterruptHandler(); } // add your TMR0 interrupt custom code ADC_OVP = ADC_GetConversion(channel_AN5); ............. ............. ............. }
發表於: 2021/7/29 11:51
|
|||
|