与pic16f18875单片机对接

问题描述

我目前正在尝试使用按钮作为中断。但是我正在努力。我已经在数据表中看到我应该启用:PIE0的INTE位,INTCON的INTEDG和PIE的GIE。 我还看到我必须使用INTPPS寄存器将引脚配置为中断,因此我想使用RB0作为中断,然后使用PIR0bits.INTF检查ISR中的interupt = true。我做到了:

void ledLoop(unsigned char *ptr){
    unsigned char *tmp = ptr;
    while(*tmp<64){
        LATB = *tmp;
         *tmp *= 2;
         __delay_ms(200);
    }
}

void __interrupt() high_isr(void){
    INTCONbits.GIE = 0;
    if( PIR0bits.INTF){
        LATB = ~LATB;
        PIR0bits.INTF = 0; 
    }
    INTCONbits.GIE = 1;
}

void launch(void){
    unsigned char run = 1;
    while(1){
        if(PORTDbits.RD7==1){
            unsigned char tmp = 1;
            ledLoop(&tmp);
        }
        if(PORTDbits.RD6==1){
            LATB=0xff;
        }
      
        
        else{
            LATB=0;
        }
    }
}
void main(void)
{
    ANSELDbits.ANSD7=0;
    ANSELDbits.ANSD6=0;
    TRISB=0;
    TRISA=0;
    LATA=0x00;
    TRISDbits.TRISD7=1;
    TRISDbits.TRISD6=1;
    
    TRISBbits.TRISB0=1;
    
     //GIE: Global Interrupt Enable bit
    //PEIE: Peripheral Interrupt Enable bit
    PIE0bits.INTE = 1;
    INTCONbits.GIE = 1;
    INTCONbits.INTEDG = 1;
    INTPPSbits.INTPPS = 0x08;
  
    launch();   
}

有什么不好的主意吗?

使用:

  • MPLABX IDE
  • XC8编译器
  • PIC16F18875

解决方法

您发布的代码有三件事:

  1. 没有配置字,因此代码不会按发布的方式构建
  2. 更改ISR内部的GIE位
  3. PORTB引脚RB0未配置为数字输入

使用/ * * /查看我的评论,以修正代码:

/*
 * File:   main.c
 * Author: dan1138
 *
 * Created on September 24,2020,2:23 PM
 */

// PIC16F18875 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FEXTOSC = OFF    // External Oscillator mode selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1) (FOSC = 32 MHz))
#pragma config CLKOUTEN = OFF   // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
#pragma config CSWEN = ON       // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable bit (FSCM timer enabled)

// CONFIG2
#pragma config MCLRE = ON       // Master Clear Enable bit (MCLR pin is Master Clear function)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config LPBOREN = OFF    // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF      // Brown-out reset enable bits (Brown-out reset disabled)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF,and 2.45V on F Devices)
#pragma config ZCD = OFF        // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = OFF    // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)

// CONFIG3
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF       // WDT operating mode (WDT Disabled,SWDTEN is ignored)
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC      // WDT input clock selector (Software Control)

// CONFIG4
#pragma config WRT = OFF        // UserNVM self-write protection bits (Write protection off)
#pragma config SCANE = available// Scanner Enable bit (Scanner module is available for use)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)

// CONFIG5
#pragma config CP = OFF         // UserNVM Program memory code protection bit (Program Memory code protection disabled)
#pragma config CPD = OFF        // DataNVM code protection bit (Data EEPROM code protection disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#define _XTAL_FREQ (32000000ul)

void ledLoop(unsigned char *ptr){
    unsigned char *tmp = ptr;
    while(*tmp<64){
        LATB = *tmp;
         *tmp *= 2;
         __delay_ms(200);
    }
}

void __interrupt() high_isr(void){
    //INTCONbits.GIE = 0;  /* <= do not do this in an interrupt service routine */
    if((PIE0bits.INTE) && ( PIR0bits.INTF)){ /* check that the interrupt is enabled AND asserted */
        LATB = ~LATB;
        PIR0bits.INTF = 0; 
    }
    //INTCONbits.GIE = 1;  /* <= do not do this in an interrupt service routine */
}

void launch(void){
    unsigned char run = 1;
    while(1){
        if(PORTDbits.RD7==1){
            unsigned char tmp = 1;
            ledLoop(&tmp);
        }
        if(PORTDbits.RD6==1){
            LATB=0xff;
        }
      
        
        else{
            LATB=0;
        }
    }
}
void main(void)
{
    ANSELDbits.ANSD7=0;
    ANSELDbits.ANSD6=0;
    TRISB=0;
    TRISA=0;
    LATA=0x00;
    TRISDbits.TRISD7=1;
    TRISDbits.TRISD6=1;
    
    TRISBbits.TRISB0=1;
    ANSELBbits.ANSB0=0; /* make RB0 a digital input */
    
     //GIE: Global Interrupt Enable bit
    //PEIE: Peripheral Interrupt Enable bit
    PIE0bits.INTE = 1;
    INTCONbits.GIE = 1;
    INTCONbits.INTEDG = 1;
    INTPPSbits.INTPPS = 0x08; /* assign INT input to RB0 */
  
    launch();   
}