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) {
while (1)
{

bool sw = PORTDbits.RD6;

if( toggleDirection ) {
LATA <<= 1;
}
else {
LATA >>= 1;
}

if( LATA == 0x80 ) toggleDirection = false;
if( LATA == 0x01 ) toggleDirection = true;

if( !sw ) {
if( !pressed ) {
if( toggleDirection ){
toggleDirection = false;
LATA = 0x80;
}
else {
toggleDirection = true;
LATA = 0x01;
}
pressed = true;
}
}
else {
pressed = false;
}

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.

Can you make more code simpler?

1 answer

Certainly! Here's a simplified version of the code:

#include <xc.h>

#define _XTAL_FREQ 8000000 // Set the oscillator frequency for delay function

bool toggleDirection = true; // True: Left to Right direction, False: Right to Left direction

void main(void) {
TRISD6 = 1; // Set RD6 as input
TRISA = 0x00; // Set PORTA as output
LATA = 0x01; // Initialize LATA with 0x01

T1CON = 0x30; // Configure Timer1 for 1:8 prescaler
TMR1 = 0; // Initialize Timer1 register to 0
PIE1bits.TMR1IE = 1; // Enable Timer1 interrupt
INTCONbits.GIE = 1; // Enable global interrupts

while (1) {
if (toggleDirection) {
LATA <<= 1;
} else {
LATA >>= 1;
}

if (LATA == 0x80) { // Leftmost LED reached
toggleDirection = false;
} else if (LATA == 0x01) { // Rightmost LED reached
toggleDirection = true;
}

__delay_ms(1);
if (!PORTDbits.RD6) { // Check if switch S3 is pressed
__delay_ms(100); // Debounce delay
if (!PORTDbits.RD6) { // Check switch S3 again
toggleDirection = !toggleDirection;
LATA = toggleDirection ? 0x01 : 0x80; // Set initial direction
}
}
}

return -1;
}

#pragma interrupt ISRHigh // Interrupt service routine for Timer1
void ISRHigh(void) {
if (PIR1bits.TMR1IF) { // Check if Timer1 overflow occurred
PIR1bits.TMR1IF = 0; // Clear Timer1 interrupt flag
TMR1 = 3036; // Load Timer1 register to achieve 1.46 seconds delay
}
}