Implement the design on Explorer 16. 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.
Where can I put the 3.5 seconds in the code below?
#define _XTAL_FREQ 8000000 // Specify the oscillator frequency
unsigned int count1 = 200;
unsigned int count2 = 200;
int main(void){
TRISA = 0x00; // Set PORTA as output
TRISDbits.TRISD6 = 1; // Set SW3 input
while(1) {
int i;
int j;
// Toggle RUN LED (D10) every 3.5 seconds using Timer1
LATDbits.LATD0 = !LATDbits.LATD0;
delayFunc();
// Knight Rider pattern from Left to Right direction
for(i = 0; i <= 6; i++) {
LATA = (1 << i);
delayFunc();
}
// Knight Rider pattern: Left to Right or Right to Left depending on SW3 state
if (PORTDbits.RD6 == 0) {
for(j = 7; j >= 0; j--) {
LATA = (1 << j);
delayFunc();
}
} else {
for(j = 0; j <= 7; j++) {
LATA = (1 << j);
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;
}
}
}
1 answer
First, include the necessary header files:
```c
#include <xc.h>
#include <pic16f877a.h>
```
Declare a global variable to keep track of the number of Timer1 overflows:
```c
unsigned int timer1Overflows = 0;
```
Configure Timer1 for the desired 3.5 second interval:
```c
T1CONbits.TMR1ON = 0; // Turn off Timer1
TMR1H = 0xFF; // Initialize Timer1 register
TMR1L = 0xFF;
T1CONbits.T1CKPS0 = 1; // Set Timer1 prescaler to 1:8
T1CONbits.T1CKPS1 = 1;
T1CONbits.TMR1CS = 0; // Set Timer1 clock source to internal oscillator
T1CONbits.TMR1ON = 1; // Turn on Timer1
```
Create an interrupt service routine that will be called whenever Timer1 overflows:
```c
void __interrupt() timer1ISR(void) {
if (PIR1bits.TMR1IF) {
PIR1bits.TMR1IF = 0; // Clear Timer1 overflow flag
timer1Overflows++;
}
}
```
Modify the delay function to use the timer instead of counting loops:
```c
void delayFunc(void) {
while (timer1Overflows < 35) {
// Do nothing
}
timer1Overflows = 0; // Reset Timer1 overflow count
}
```
In the main function, enable Timer1 interrupts:
```c
INTCONbits.PEIE = 1; // Enable peripheral interrupts
PIE1bits.TMR1IE = 1; // Enable Timer1 overflow interrupt
INTCONbits.GIE = 1; // Enable global interrupts
```
Now, the code will toggle the RUN LED (D10) every 3.5 seconds using Timer1.
Note: Make sure to enable Timer1 interrupts in the configuration bits as well.