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 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.

Cna you make the code simple?

1 answer

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

#include <xc.h>

// Function prototypes
void interrupt high_priority ISR(void);
void delayFunc(void);

// Variables
unsigned int count1 = 14600;
unsigned int count2 = 200;
unsigned char toggleDirection = 0;
unsigned char pressed = 0;

void main(void) {
// Configure Timer1
T1CON = 0x8030; // Enable Timer1, 1:256 prescaler

// Configure LEDs and switch
TRISD = 0b01000000; // Set RD6 as input, others as output
LATA = 0x01; // Set initial pattern

// Enable Timer1 interrupt
IEC0bits.T1IE = 1; // Enable Timer1 interrupt
TMR1 = 0; // Reset Timer1 value
PR1 = count1; // Set Timer1 period

// Enable high priority interrupts
INTCONbits.GIEH = 1;

while (1) {
// Check switch
bool sw = PORTDbits.RD6;

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

if (!sw) {
if (!pressed) {
toggleDirection = !toggleDirection;
LATA = toggleDirection ? 0x80 : 0x01;
pressed = 1;
}
}
else {
pressed = 0;
}

delayFunc();
}

return -1;
}

// Timer1 interrupt service routine
void interrupt high_priority ISR(void)
{
// Check if Timer1 overflowed
if (PIR1bits.TMR1IF) {
// Toggle RUN LED (D10)
LATAbits.LATA15 = !LATAbits.LATA15;

// Clear Timer1 interrupt flag
PIR1bits.TMR1IF = 0;
}
}

void delayFunc(void) {
int j, k;

for(j = 0; j < count1; j++) {
for(k = 0; k < count2; k++) {
asm("nop"); // No operation
}
}
}

This code simplifies the original code by eliminating unnecessary variables and conditions. It also uses Timer1 interrupt to toggle the RUN LED at the specified interval.