Implement the design on Explorer 16 as Project 1. LED D10 will be used as the RUN LED indicator.

Knight rider code:
unsigned int count1 = 200;
unsigned int count2 = 200;

void main(void) {
TRISA = 0x00;
LATA = 0x00;

while(1) {
int i;
int j;

// Right to Left sequence
for(i=0; i<8; i++) {
LATA |= (1 << i);
delayFunc();
}

// Left to Right sequence
for(j=7; j>=-1; j--) {
LATA |= (1<<j);
delayFunc();
}

// Left to Right sequence if SW3 is pressed
if(PORTDbits.RD6 == 0) {
LATA = 0x00;
for(j=8; j>=-1; j--) {
LATA |= (1<<j);
delayFunc();
}
}

}

return -1;
}

void delayFunc(void)
{
int j,k;
int a;

for(j = 0; j < count1; j++)
{
for(k=0; k < count2; k++)
{
a = 0;
}
}

}

Using the knight rider code above, do the following:
Write an simple application (in C) which does the following:
1. Make the RUN LED(D10) toggle at every 1.45 Seconds (exact) interval using one of the Timer (Timer 1) module of the Microcontroller.
2. The Knight Rider pattern now consists of 7 LEDs (D9-D3). If the switch (S3) is open, the pattern is from Left to Right direction. If the switch (S3) is closed, the pattern is from Right to Left direction.
3. Repeat the whole process in an infinite way.
4. To toggle the RUN LED, precisely at 1.45 Seconds interval, you need to use the interrupt mechanism for the Timer1.

1 answer

#include <xc.h>

// Define the delay for toggling the RUN LED
#define RUN_LED_DELAY 1450

// Define the LED pins
#define LED_MASK 0xFE
#define LED_REGISTER TRISD
#define LED_PORT PORTD

// Define the switch pin
#define SWITCH_PIN RD6

// Initialize Timer1 for interrupt every 1 ms
void timer1_init() {
T1CONbits.TMR1CS = 0; // Select internal clock source
T1CONbits.T1CKPS = 0b11; // Set prescaler to 1:8
TMR1 = 0x0000; // Clear Timer1 register
PR1 = 18431; // Set period for 1 ms interrupt
IEC0bits.T1IE = 1; // Enable Timer1 interrupt
IPC0bits.T1IP = 7; // Set Timer1 interrupt priority
IFS0bits.T1IF = 0; // Clear Timer1 interrupt flag
T1CONbits.TMR1ON = 1; // Turn on Timer1
}

// Toggle the RUN LED
void toggle_run_led() {
LATAbits.LATA0 = !LATAbits.LATA0;
}

// Knight rider pattern
void knight_rider() {
// Right to Left sequence
for(int i = 0; i < 7; i++) {
LED_PORT = (LED_PORT & LED_MASK) | (1 << (i + 3));
__delay_ms(100);
}

// Left to Right sequence
for(int j = 6; j >= 0; j--) {
LED_PORT = (LED_PORT & LED_MASK) | (1 << (j + 3));
__delay_ms(100);
}

// Left to Right sequence if switch is pressed
if(SWITCH_PIN == 0) {
LED_PORT = (LED_PORT & LED_MASK) | (1 << 3);
__delay_ms(100);

for(int j = 0; j < 7; j++) {
LED_PORT = (LED_PORT & LED_MASK) | (1 << (j + 3));
__delay_ms(100);
}
}
}

// Timer1 interrupt service routine
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt(void) {
IFS0bits.T1IF = 0; // Clear Timer1 interrupt flag
toggle_run_led();
knight_rider();
}

int main(void) {
// Configure LED pins as outputs
LED_REGISTER = 0;

// Configure switch pin as input
TRISDbits.TRISD6 = 1;

// Configure RUN LED
TRISAbits.TRISA0 = 0;

// Initialize Timer1
timer1_init();

// Enable global interrupts
INTCONbits.GIE = 1;

while(1) {
// Infinite loop
}

return 0;
}