Here is a short and simple code to implement the given functionality using Timer 1 module for toggling the RUN LED and controlling the Knight Rider pattern.
```c
#include <xc.h>
#pragma config FNOSC = PRIPLL // Primary Oscillator (XT, HS, EC)
#pragma config POSCMOD = HS // Primary Oscillator Configuration Bits (HS osc mode)
#pragma config FPLLMUL = MUL_20 // PLL Multiplier Value (Multiplier 20x)
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (2x Divider)
#pragma config FPBDIV = DIV_2 // Peripheral Clock divisor (Pb_Clk is Sys_Clk/2)
#pragma config FPLLODIV = DIV_1 // PLL Output Divider (PLL Divide by 1)
#define SWITCH_DOWN PORTDbits.RD7 // Switch connected to RD7 pin
#define RUN_LED LATAbits.LATA0 // RUN LED connected to RA0 pin
void delay_ms(unsigned int milliseconds){
unsigned int count = 0;
while(count < milliseconds){
// Each asm instruction takes 4 cycles
// Assuming a clock frequency of 24 MHz, one instruction takes 0.166667us
// Therefore, 4 instructions will take 0.66667us
// Approximately 1500us is required for 1.45 seconds delay
asm("repeat #2998"); // Repeat 4 instructions 3000 times
asm("nop"); // No operation
count++;
}
}
void setup(){
ANSELA = 0; // Configure PORTA pins as digital
LATA = 0; // Clear PORTA pins
ANSELB = 0; // Configure PORTB pins as digital
LATB = 0; // Clear PORTB pins
ANSELD = 0; // Configure PORTD pins as digital
LATD = 0; // Clear PORTD pins
TRISA = 0xFF00; // Configure pins 0-7 of PORTA as outputs (for LEDs)
TRISB = 0xFFFF; // Configure all pins of PORTB as inputs (for switches)
T1CON = 0; // Clear Timer 1 control register
// Configure Timer 1 with a prescaler of 256 and enable the timer
T1CONbits.TCKPS = 3; // Set prescaler to 256
T1CONbits.TON = 1; // Enable Timer 1
// Set Timer 1 period register to generate an interrupt every 1.45 seconds
PR1 = 36864; // 36864 = 1.45 seconds / (1.36us * 256)
// Clear Timer 1 interrupt flag and enable Timer 1 interrupt
IFS0bits.T1IF = 0; // Clear Timer 1 interrupt flag
IPC1bits.T1IP = 1; // Set Timer 1 interrupt priority to 1
IEC0bits.T1IE = 1; // Enable Timer 1 interrupt
}
void __attribute__((interrupt, auto_psv)) _T1Interrupt(void){
IFS0bits.T1IF = 0; // Clear Timer 1 interrupt flag
// Toggle RUN LED
RUN_LED = !RUN_LED;
// Check switch state
if(SWITCH_DOWN){
// Knight Rider pattern from Left to Right
LATA = 0x00FF; // Turn on LEDs D9-D3
delay_ms(100); // Delay to show the pattern
LATA = 0x0000; // Turn off all LEDs
} else {
// Knight Rider pattern from Right to Left
LATA = 0x0080; // Turn on LED D3
delay_ms(100); // Delay to show the pattern
LATA = 0x0000; // Turn off all LEDs
}
}
int main(void) {
setup();
while (1) {
// Infinite loop
}
return 0;
}
```
You can add this code to your project on the Explorer 16 development board and it should implement the desired functionality.
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 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.
Can you make a short and simple code?
1 answer