Прерывания с помощью микроконтроллера PIC18f46k20

Я новичок в C ++ и у меня возникли проблемы. Инициализация необходимых резисторов, необходимых для моего проекта по управлению скоростью двигателя.
Я использовал таблицу данных (ссылка ниже), но не могу обойти проблему
PIC_datasheet

Две проблемы, с которыми я сталкиваюсь

  • прерываний не происходит. Код для обработки прерываний ниже

  • когда я включаю глобальные прерывания, то есть «INCONbits.GIE = ​​1», ничто не отображается на картинке (светодиоды и экран), как если бы оно находилось в спящем режиме.

Инициализация.

    void InitializeSystem(void)
{

OSCCON = 0b01110000;
OSCTUNEbits.PLLEN = 0;                  // turn off the PLL

// Setup I/O Ports.

ANSEL = 0x00;                          // all digital   check if needed*
TRISA = 0;                              // TRISA outputs
LATA = 0b11110000;                      // drive PORTA pins low

oled_res = 1;                           // do not reset LCD yet
oled_cs = 1;                            // do not select the LCD

TRISB = 0b11111111;LATC = 0b00101000;
TRISC = 0b00000000;

TRISD = 0;                              // TRISD is LED output
LATD = 0;                               // turn off LEDS

TRISE = 0b00000111;//configure buttons
WPUB = 0b00001111;
INTCON2bits.RBPU = 0;                   // turn on weak pull ups for RB0-RB3

INTCONbits.INT0IF = 0;                  // clear RB0 INT
INTCONbits.INT0IE = 1;                  // enable RB0 INT
INTCON2bits.INTEDG0 = 0;                // interrupt on falling edge

INTCON3bits.INT1IF = 0;                 // clear RB1 INT
INTCON3bits.INT1IE = 1;                 // enable RB1 INT
INTCON2bits.INTEDG1 = 0;                // interrupt on falling edgeINTCON3bits.INT2IF = 0;                 // clear RB2 INT
INTCON3bits.INT2IE = 1;                 // enable RB2 INT
INTCON2bits.INTEDG2 = 0;                // interrupt on falling edge// Setup TMR0
T0CON = 0b00000010;          // 16- bit prescaller 1:8
INTCONbits.TMR0IE=1;
INTCONbits.TMR0IF=0;
INTCON2bits.TMR0IP=0;

// Configure Timer 1
T1CON   = 0b11111101;// Configure MSSP for SPI master mode
SSPCON1 = 0b00110010;                   // clock idle high, Clk /64

SSPSTAT = 0b00000000;

PIR1bits.TMR1IF = 0;
PIE1bits.TMR1IE = 1;OSCCON = 0b01110000;
OSCTUNEbits.PLLEN = 1;  // Puts the PIC at 64MHz
CCP1CON = 0b00001100;
PSTRCON = 0b00010001;

// setup timer 2 for pwm
T2CON = 0b00000111;// Prescale = 1:16, timer on, postscale not used with CCP module
PR2 = 255;     // Configure the Timer2 period
TRISCbits.TRISC2  = 0;              // Make CCP1 pin as output
CCP1CON = 0x0C;           // Configure CCP1 module in PWM mode
T2CON = 0x01;             // Set Prescaler to be 4, hence PWM frequency is set to   4.88KHz.
T2CON |= 0x04;            // Enable the Timer2, hence enable the PWM.
SetPWMDutyCycle(pwm);       // Intialize the PWM to 0.5 duty cycle

// Set up global interrupts
IOCB = 1;
RCONbits.IPEN = 1;                    // Enable priority levels on   interrupts
INTCONbits.RBIE = 1;
INTCONbits.RBIF = 0;
INTCONbits.GIE = 1;

T0CONbits.TMR0ON = 1;   // START TIMER0} // end InitializeSystem
void SetPWMDutyCycle(unsigned int DutyCycle)      // Give a value in between 0 and      1024 for DutyCycle
{
CCPR1L   = DutyCycle>>2;            // Put MSB 8 bits in CCPR1L
CCP1CON &= 0xCF;                    // Make bit4 and 5 zero
CCP1CON |= (0x30&(DutyCycle<<4));   // Assign Last 2 LSBs to CCP1CON
}

Служба прерываний

#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow (void)
{
_asm
goto InterruptServiceLow //jump to interrupt routine
_endasm
}

//----------Interrupt Service Routine-------------------------------------
#pragma interrupt InterruptServiceHigh
void InterruptServiceHigh(void)
{

if(INTCONbits.RBIF)
{
INTCONbits.RBIF = 0;

if(PORTBbits.RB6!=0)
{
UpperCounter++; //increment UpperCounter if RB6 goes high
speed_counter++; // increment the counter used to calculate
//speed
LATDbits.LATD7=~LATDbits.LATD7;  // LED7 changes state each
//rising edge
Delay10TCYx(1);
}else if(PORTBbits.RB7!=0)
//count pulses from ch B
{
LowerCounter++; //increment LowerCounter if RB7 goes high
speed_counter++;
LATDbits.LATD0=~LATDbits.LATD0; //LED0 changes state each
//rising edge
Delay10TCYx(1);
}else if(PORTBbits.RB5 != 0)
//count pulses from ch Z
{
LowerCounter=0;  //reset LowerCounter
UpperCounter=0;   //reset UpperCounter
Delay10TCYx(1);
}
}
}

#pragma interruptlow InterruptServiceLow// "interruptlow" pragma for low priority
void InterruptServiceLow(void)
{

if(INTCONbits.TMR0IF)
{
position2=speed_counter;

speed=((((position2-position1)/64)*60)/2.1);
//calculate speed. TMR0 on 16bit prescalar1:8
TMR0H = 0;
//  clear timer - always write upper byte first
TMR0L = 0;
INTCONbits.TMR0IF = 0;
// clear (reset) flag
LATDbits.LATD2=~LATDbits.LATD2;
position1=speed_counter;
}
}

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]