Here is a possible implementation of the described application in C:
```c
#include <xc.h>
// Configuration bits
#pragma config FNOSC = PRIPLL // Oscillator Selection bits (Primary Osc with PLL)
#pragma config POSCMOD = HS // Primary Oscillator Configuration bits (HS oscillator mode)
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_16 // PLL Multiplier (16x Multiplier)
#pragma config FPLLODIV = DIV_1 // PLL Output Divider (PLL Divide by 1)
#pragma config FPBDIV = DIV_2 // Peripheral Clock divisor (Pb_Clk is Sys_Clk/2)
#pragma config FWDTEN = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disabled)
// Function prototypes
void timer1Delay(float seconds);
void toggleLed(void);
void knightRiderPattern(int direction);
// Constants
#define LED_RUN LATBbits.LATB10
#define LED_KNIGHT_LEFT LATBbits.LATB9
#define LED_KNIGHT_RIGHT LATBbits.LATB3
#define SWITCH_S3 PORTGbits.RG6
int main(void) {
// Initialize LEDs as output
TRISBbits.TRISB10 = 0; // LED_RUN
TRISBbits.TRISB9 = 0; // LED_KNIGHT_LEFT
TRISBbits.TRISB3 = 0; // LED_KNIGHT_RIGHT
// Initialize switch as input
TRISGbits.TRISG6 = 1; // SWITCH_S3
while (1) {
// Toggle LED_RUN every 3.5 seconds
toggleLed();
timer1Delay(3.5);
// Check switch state and update knight rider pattern accordingly
if (SWITCH_S3 == 0) { // Switch open, left to right direction
knightRiderPattern(1);
} else { // Switch closed, right to left direction
knightRiderPattern(-1);
}
}
return 0;
}
// Delay function using Timer 1
void timer1Delay(float seconds) {
TMR1 = 0;
PR1 = (int)(seconds / (1.0/8000000.0) + 0.5); // Calculate the period based on desired delay
// Configure Timer 1 settings
T1CONbits.TCS = 0; // Internal clock source
T1CONbits.TCKPS = 0b00; // Prescaler 1:1
T1CONbits.TON = 1; // Enable Timer 1
// Wait until the Timer 1 interrupt flag is set
while (!IFS0bits.T1IF);
// Clear the Timer 1 interrupt flag
IFS0bits.T1IF = 0;
}
// Toggle LED_RUN state
void toggleLed() {
LED_RUN = !LED_RUN;
}
// Knight rider pattern function
void knightRiderPattern(int direction) {
// Calculate next LED position based on direction
static int position = 0; // Start from first LED
position += direction;
// Check if position exceeds LED range
if (position < 0) {
position = 1; // Skip LED_KNIGHT_RIGHT
} else if (position > 6) {
position = 5; // Skip LED_KNIGHT_LEFT
}
// Update LED states accordingly
LED_KNIGHT_LEFT = (position >= 3) ? 1 : 0;
LED_KNIGHT_RIGHT = (position <= 3) ? 1 : 0;
}
```
This code uses Timer 1 to implement the delay for toggling the RUN LED every 3.5 seconds. It also reads the state of switch S3 to determine the direction of the knight rider pattern. The pattern starts from left to right if the switch is open, and from right to left if the switch is closed.
Note that this implementation assumes that the necessary peripheral library and configuration bits are set correctly for the specific microcontroller being used. Also, the code assumes that the LEDs and the switch are connected to the specified port pins on the Explorer 16 board. Please review the board's documentation and adjust the port pin assignments if needed.
Implement the design on Explorer 16 as Project 1. LED D10 will be used as the RUN LED indicator.
Write an application (in C) which does the following:
1. Make the RUN LED(D10) toggle at every 3.5 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.
1 answer