Re: PIC16 Interrup
|
||||
---|---|---|---|---|
資深會員
|
我在使用 XC8 寫 PIC16F 的時候也遇到這個問題,一開始我也是如同 XC8 講義 Page 116 那樣宣告中斷函數:
void interrupt ISR(void){ } 結果也是出現樓主的錯誤訊息一直編譯不通過,後來去 Google 發現這兩個帖子: https://bbs.21ic.com/icview-2546270-1-1.html https://bbs.csdn.net/topics/392505791 把 void interrupt 中斷名(void) 改為 void __interrupt() 中斷名(void),下劃線是兩個,於是我的中斷函數改成這樣子: void __interrupt() ISR(void){ } 這樣就編譯通過了,為什麼要這樣子宣告才行,是 XC8 講義寫錯了嗎?有人知道原因嗎?
發表於: 2021/7/1 16:52
|
|||
|
Re: PIC16 Interrup
|
||||
---|---|---|---|---|
版主
|
請在main( ) 函數外加入 void interrupt ISR(void) ; 的原型函數宣告。
要使用
#include <xc8.h>
發表於: 2021/6/24 13:05
Edited by Ryang on 2021年07月02日 14:37:39
|
|||
|
Re: PIC16 Interrup
|
||||
---|---|---|---|---|
版主
|
XC8 底下的 PIC16F 及 PIC18F 的中斷函數有特定的語法,建議可以到教育訓練光碟下下載 "XC8" 及 "PIC101" 的教材來研讀。
試著將底下的中斷宣告 "void interruptISR(void) {" 修改成 void interrupt ISR(void) { 如附圖所示: 教育訓練光碟網址: http://www.microchip.com.tw/RTC/RTC_DVD/ 在" 8-Bits MCU 相關課程" 下,下載底下的課程: 1. PIC101 X IDE & MCC& XC8 基礎課程 2. XC8T v1.0
發表於: 2021/6/23 10:54
|
|||
|
PIC16 Interrup
|
||||
---|---|---|---|---|
新會員
|
第一次使用PIC,官網下載範例中斷程式,編譯後卻得到"未呼叫中斷副程式"、請問要如何修正? # used PIC16F1829
以下是該程式 #include #define _XTAL_FREQ 500000 //Used by the XC8 delay_ms(x) macro #define DOWN 0 #define UP 1 #define SWITCH PORTAbits.RA2 #define LED_RIGHT 1 #define LED_LEFT 0 #define PULL_UPS //if this is uncommented, the trace under JP5 can be cut //with no affect on the output //config bits that are part-specific for the PIC16F1829 // CONFIG1 #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled) #pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled) // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = OFF // PLL Enable (4x PLL disabled) #pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset) #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) /* -------------------LATC----------------- * Bit#: -7---6---5---4---3---2---1---0--- * LED: ---------------|DS4|DS3|DS2|DS1|- *----------------------------------------- */ unsigned char _direction; //a global variable void main(void) { //general init OSCCON = 0b00111000; //500KHz clock speed TRISC = 0; //PortC are outputs LATC = 0; //PortC in OFF state LATCbits.LATC3 = 1; //DS4 is lit //RC3 output=1 _direction = LED_RIGHT; //start with LEDs rotating from right to left //setup switch (SW1) TRISAbits.TRISA2 = 1; //switch as input //RA2 are Input pin ANSELAbits.ANSA2 = 0; //digital switch //ADC Func Off //by using the internal resistors, you can save cost by eleminating an external pull-up/down resistor #ifdef PULL_UPS WPUA2 = 1; //enable the weak pull-up for the PortA nWPUEN = 0; //enable the global weak pull-up bit #endif //setup TIMER0 as the delay //1:256 prescaler for a delay of: (insruction-cycle * 256-counts)*prescaler = ((8uS * 256)*256) =~ 524mS OPTION_REG = 0b00000111; //setup TIMER0 // Prescaler Rate Select bits = 0b111 = 256 INTCONbits.TMR0IE = 1; //enable the TMR0 rollover interrupt //setup interrupt on change for the switch INTCONbits.IOCIE = 1; //enable interrupt on change global IOCANbits.IOCAN2 = 1; //when SW1 is pressed, enter the ISR INTCONbits.GIE = 1; //enable global interupts while (1) { continue; //can spend rest of time doing something critical here } } void interruptISR(void) { if (IOCAF) { //SW1 was just pressed //INTERRUPT-ON-CHANGE PORTA FLAG REGISTER IOCAF = 0; //must clear the flag in software __delay_ms(5); //debounce by waiting and seeing if still held down if (SWITCH == DOWN) { _direction ^= 1; //change directions } } if (INTCONbits.T0IF) { // When Timer 0 rolls over, rotate the LED INTCONbits.T0IF = 0; //T0IF : Timer0 Overflow Interrupt Flag bit if (_direction == LED_RIGHT) { LATC >>= 1; //rotate right if (STATUSbits.C == 1) //when the last LED is lit, restart the pattern //STATUS: STATUS REGISTER ; C= 1 : A carry-out from the Most Significant bit of the result occurred LATCbits.LATC3 = 1; } else{ LATC <<= 1; //rotate left if (LATCbits.LATC4 == 1) //when the last LED is lit, restart the pattern LATCbits.LATC0 = 1; } } }
發表於: 2021/6/23 10:07
|
|||
|