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.
1 answer
```C
#include <xc.h>
#define _XTAL_FREQ 16000000
unsigned int count1 = 200;
unsigned int count2 = 200;
bool toggleDirection = true;
bool pressed = false;
void main(void) {
TRISAbits.TRISA7 = 0; // Set pin A7 (RUN LED) as output
TRISB = 0xFF; // Set all pins in PORTB as input
TRISD = 0xFF; // Set all pins in PORTD as input
// Configure Timer1
TMR1 = 0; // Clear Timer1 register
T1CONbits.TMR1CS = 0; // Set Timer1 source as internal instruction cycle clock
T1CONbits.T1CKPS = 0b11; // Set Timer1 prescaler as 1:8
T1CONbits.TMR1ON = 1; // Enable Timer1
// Configure interrupt for Timer1
PIE1bits.TMR1IE = 1; // Enable Timer1 interrupt
INTCONbits.GIE = 1; // Enable global interrupts
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;
}
}
return -1;
}
void __interrupt() isr(void) {
if(PIE1bits.TMR1IE && PIR1bits.TMR1IF) {
// Toggle RUN LED (D10) using pin A7
LATAbits.LATA7 ^= 1;
// Load Timer1 with initial value to achieve 1.45 second delay
TMR1 = 3036; // 65536 - (1.45s / (1 / (16MHz / 4) / 8))
// Clear Timer1 interrupt flag
PIR1bits.TMR1IF = 0;
}
}
```
Note: This implementation assumes that the LED pattern is connected to pins RA7 (RUN LED) to RA1 (D3). If the pattern is connected to different pins, please update the code accordingly. Additionally, make sure to configure the correct port for the switch (S3) input.