i am trying to understand a program but i have some questions, maybe you can help me. The microcontroller used is a ATMEL 2549 - 8bit. Thank you in advance.
Atmel-2549 8-bit AVR Microcontroller ATmega640 1280-1281-2560-2561 datasheet
Set up a stop watch with the following features:
• There are three push buttons: START, STOP, and RESET
• Your system generates an interrupt every 100ms by using Timer1.
• There is an LCD at port A. Use the usual library for controlling the LCD!
• On the LCD, you display the time that has elapsed since the START button was pushed. Show minutes, seconds and tenth of seconds.
• After 59 min 59.9 s, the display starts from scratch again.
#include <stdint.h>
#include <avr/io.h>
#include "lcd.h"
#include <stdio.h>
#include <avr/interrupt.h>
void timer1_config(void);
void exinterrupt_config(void);
void send_string(void);
display myLCD;
volatile char text[20];
volatile uint8_t minute=0,sekunde=0,zehnt=0;
ISR(TIMER1_COMPA_vect) { //Interrupt for a timer with minute, second and decisecond.
zehnt++; //from 0 to 59min 59,9sec. After that time is elapsed,
if (zehnt>9) { //it should be showed on LCD display.
zehnt=0;
sekunde=sekunde+1;
}
if (sekunde>59) {
sekunde=0;
minute=minute+1;
}
if (minute>59) {
minute=0;
sekunde=0;
zehnt=zehnt+1;
}
send_string();
}
ISR(INT0_vect) { //Interrupt for starting the timer.
// --- No. *1 ---
TCCR1B|= (1<<CS11);
}
ISR(INT1_vect) { //Interrupt for stopping the timer.
TCCR1B&=~((1<<CS10)|(1<<CS11)|(1<<CS12));
}
ISR(INT2_vect) { //Interrupt for resetting the timer.
minute=0; //Sets everything to 0 and shows time on LCD display.
sekunde=0;
zehnt=0;
TCNT1=0;
send_string();
}
int main(void) {
// --- No. *2 ---
DDRD&=~((1<<PIN0)|(1<<PIN1)|(1<<PIN2));
timer1_config(); //Load all three functions.
exinterrupt_config();
send_string();
lcd_init(&myLCD ,&PORTA); //Start the LCD display on port A.
lcd_send_string(&myLCD,"-------Watch-------",1,1);
sei();
for(;;){};
return(0);
}
void timer1_config(void){
TCCR1B|=(1<<WGM12);
OCR1A=12499;
// --- No. *3 ---
TIMSK1|=(1<<OCIE1A);
}
void exinterrupt_config(void){
EIMSK|=((1<<INT0)|(1<<INT1)|(1<<INT2)); //Enable all 3 interrupts.
// --- No. *4 ---
EICRA|=((1<<ISC01)|(1<<ISC11)|(1<<ISC21));
}
void send_string(void){ //Sends text to LCD display.
sprintf(text,"%i.min %i.sek %i.zehnt",minute,sekunde,zehnt);
lcd_send_string(&myLCD,text,3,1);
}
1: I understand this is the command to make the timer start counting, but on the description from the datasheet it says "clkI/O/8 (From prescaler)" for setting the bit CS11 high. I cant understand it and how it works.
2: Is it setting the bits from DDRD to input (0)? If so, why is it being done if port D inst even being used?
3: I dont understand what it does!
4: The description from the datasheet says "The falling edge of INTn generates asynchronously an interrupt request", but i dont really get what it does. Whats the difference to "The rising edge of INTn generates asynchronously an interrupt request"?
Thank you again!
From Table 17-6, it really sets the clock to clk(I/O)/8. That means it will increment the internal counter on every eighth tick of the internal I/O clock. Maybe you couldn't count every tick in the timer's register in a second, so you need to prescale it.
Those are for the buttons. The buttons must be on PIND of your panel, one bit for each button. Although the program does not read PIND, the external interrupt handler does, so the data direction must be set up accordingly.
Buttons, switches are inputs, leds are outputs. It depend's on your developer panel on which ports are they wired.
§17.11.36
• Bit 1 – OCIEnA: Timer/Countern, Output Compare A Match Interrupt Enable When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally enabled), the Timer/Countern Output Compare A Match interrupt is enabled. The corresponding Interrupt Vector (see “Interrupts” on page 101) is executed when the OCFnA Flag, located in TIFRn, is set.
The timer peripherial can operate in different modes. This setting is related to output compare mode, and it will tell the hardware to issue an interrupt when the timer's internal counter reaches a limit (the limit is set in OCR1A).
The timer is set to CTC (Clear Timer on Compare) mode in TCCR1B (Table 17-2), so it restarts counting when the limit is reached.
A falling edge is when a signal goes from high to low. A rising edge is when the signal goes from low to high. These buttons are usually Active-LOW, so a falling edge means the button is pressed. (and a rising edge means the button is released)