0
\$\begingroup\$

I am trying to use Timer0 to control a blinking LED, but I am having some difficulties... the LED never turns on.

I referred to this tutorial to set things up, but I still can't understand it, could you please tell me where the problem is?

#include "mcc_generated_files/mcc.h"
#include <stdint.h>
#define SBIT_PS2 2

volatile unsigned char value = 0;

void timer_isr(void)
{
  if (TMR0IF == 1)
  {
    value =~ value; // complement the value for blinking the LEDs
    TMR0 = 101; // Load the timer value. Note: Timervalue is 101 instead of 100 as Timer0 needs two instruction cycles to start incrementing TMR0
    TMR0IF=0; // Clear timer interrupt flag 
  }
}

/*
Main application
*/
void main(void)
{
  // initialize the device
  SYSTEM_Initialize();

  // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
  // Use the following macros to:
  // Enable the Global Interrupts
  INTERRUPT_GlobalInterruptEnable();
  // Enable the Peripheral Interrupts
  INTERRUPT_PeripheralInterruptEnable();
  // Disable the Global Interrupts
  //INTERRUPT_GlobalInterruptDisable();
  // Disable the Peripheral Interrupts
  //INTERRUPT_PeripheralInterruptDisable();
  uint16_t dutycycle;
  TRISD=0x00; // Configure PORTD as output to blink the LEDs

  OPTION_REG = (1<<SBIT_PS2); // Timer0 with external freq and 32 as prescalar
  TMR0 = 0; // Load the time value for 1ms delay
  TMR0IE = 1; // Enable timer interrupt bit in PIE1 register
  GIE = 1; // Enable Global Interrupt
  PEIE = 1; // Enable the Peripheral Interrupt 
     
  while (1) {
    WB_PORT = value;
    LR1_PORT = value;
  }
}

Supplement: my pin settings:

enter image description here

enter image description here

enter image description here

Because there is too little information about PIC in Chinese...

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

It could be the classic missing volatile bug. Change the declaration to volatile unsigned char value = 0;

You should also make a habit of using stdint.h and uint8_t instead. The char type in C has implementation-defined signedness, so it is unsuitable for binary arithmetic and also non-portable.

\$\endgroup\$
4
  • \$\begingroup\$ I've modified and tried it, but it still doesn't work, thanks for your answer! \$\endgroup\$
    – Judy11432
    Aug 16, 2022 at 9:39
  • \$\begingroup\$ @Judy11432 Is the interrupt firing at all? Did you try to set a breakpoint inside the ISR? \$\endgroup\$
    – Lundin
    Aug 16, 2022 at 9:55
  • \$\begingroup\$ Hi Lundin,I don't understand how to interrupt firing, sorry I just learned this stuff \$\endgroup\$
    – Judy11432
    Aug 19, 2022 at 0:56
  • \$\begingroup\$ @Judy11432 If you don't know how to use a debugger, you are probably better off learning the basics on a PC before moving on to embedded systems. But it isn't hard to learn, every debugger out there works similar no matter target. \$\endgroup\$
    – Lundin
    Aug 19, 2022 at 6:24
2
\$\begingroup\$

timer_isr() isn't set up as interrupt service routine.

You need to add the interrupt keyword:

void interrupt timer_isr(void)
{
    ...
}

Without the interrupt keyword, timer_isr() is a regular function, which is never referenced in your program.


EDIT:

void interrupt timer_isr(void) is the correct syntax.

Deviations like void __interrupt() timer_isr(void) and void __interrupt() INTERRUPT_InterruptManager(void) are wrong.

The error message main.c:49:: error: (1506) multiple interrupt functions (_timer_isr and _INTERRUPT_InterruptManager) defined at interrupt level 1 states that the timer interrupt service routine has already been defined somewhere else.

I've never used the MPLAB Code Configurator (MCC) before, but I strongly suspect that the corresponding code is being included with #include "mcc_generated_files/mcc.h". Have a look at that file to see if you can find the other definition of the timer interrupt service routine

\$\endgroup\$
1
  • \$\begingroup\$ I tried chang to void interrupt timer_isr(void) and void __interrupt() timer_isr(void) The following error occurs : main.c:49:: error: (1506) multiple interrupt functions (_timer_isr and _INTERRUPT_InterruptManager) defined at interrupt level 1 So I chang to : void __interrupt() INTERRUPT_InterruptManager(void) this error will occur : main.c:49:: error: (1098) conflicting declarations for variable "_INTERRUPT_InterruptManager" (mcc_generated_files/interrupt_manager.c:52) I have checked a lot of information, and my understanding is that variables cannot be added to it, right? \$\endgroup\$
    – Judy11432
    Aug 19, 2022 at 0:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.