3.2 Bare Metal Code
First, the Watchdog Timer has to be disabled and Low-Voltage Programming (LVP) has to be enabled using the following pragma code:
#pragma config WDTE = OFF /* WDT operating mode->WDT Disabled */ #pragma config LVP = ON /* Low voltage programming enabled, RE3 pin is MCLR */
The following function initializes the system clock to have the HFINTOSC oscillator as input clock and to run at 1 MHz:
static void CLK_Initialize(void) { OSCCON1 = 0x60; /* set HFINTOSC as new oscillator source */ OSCFRQ = 0x00; /* set HFFRQ to 1 MHz */ }
The following function initializes the RE0 pin (corresponding to the on-board LED0) as output pin:
static void PORT_Initialize(void) { TRISEbits.TRISE0 = 0; /* configure RE0 as output */ }
The following function initializes Timer0 in 16-bit mode, sets the prescaler to 1:32, loads the TMR0H and TMR0L registers, clears the Interrupt flag and enables the interrupt and Timer0:
static void TMR0_Initialize(void)
{
T0CON1 = 0x95; /* select LFINTOSC, disable TMR0 sync, set prescaler to 1:32 */
TMR0H = 0xDA; /* set TMR0H reload value */
TMR0L = 0x29; /* set TMR0L reload value */
PIR0bits.TMR0IF = 0; /* clear the interrupt flag */
PIE0bits.TMR0IE = 1; /* enable TMR0 interrupt */
T0CON0 = 0x90; /* configure TMR0 in 16-bit mode and enable TMR0 */
}
The following function enables the Global and Peripheral interrupts:
static void INTERRUPT_Initialize(void) { INTCONbits.GIE = 1; /* Enable the Global Interrupts */ INTCONbits.PEIE = 1; /* Enable the Peripheral Interrupts */ }
static void TMR0_ISR(void)
{
PIR0bits.TMR0IF = 0; /* clear the TMR0 interrupt flag */
TMR0H = 0xDA; /* set TMR0H reload value */
TMR0L = 0x29; /* set TMR0L reload value */
}
void __interrupt() INTERRUPT_InterruptManager(void)
{
/* Check if TMR0 interrupt is enabled and if the interrupt flag is true */
if(PIE0bits.TMR0IE == 1 && PIR0bits.TMR0IF == 1)
{
TMR0_ISR();
}
}
SLEEP()
instruction. Additionally, prior to the main function, the
_XTAL_FREQ symbol must be defined and set to 1000000 (equivalent to the 1 MHz system
frequency) for the use of the __delay_ms()
function:#define _XTAL_FREQ 1000000UL
void main(void)
{
CLK_Initialize();
PORT_Initialize();
TMR0_Initialize();
INTERRUPT_Initialize();
while(1)
{
LATEbits.LATE0 = 0; /* turn LED ON */
__delay_ms(100); /* wait 100 ms */
LATEbits.LATE0 = 1; /* turn LED OFF */
SLEEP();
}
}