Вы находитесь на странице: 1из 6

/* Description: An AVR ATmega8 based Digital Stop Watch Project.

________________________________________________________ Author: Avinash Gupta Date: 04 July 09 Web www.eXtremeElectronics.co.in */ #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay_basic.h> #define true 1 #define false 0 #define SEVEN_SEGMENT_PORT PORTD #define SEVEN_SEGMENT_DDR DDRD volatile uint8_t digits[4]; //Global volatile volatile volatile volatile variable unsigned unsigned unsigned unsigned for the clock system int clock_millisecond=0; char clock_second=0; char clock_minute=0; char clock_hour=0;

//Display hiding system uint8_t hide_display = false; //Blinking system uint8_t blink_display = true;

void SevenSegment(uint8_t n,uint8_t dp) { /* This function writes a digits given by n to the display the decimal point is displayed if dp=1 Note: n must be less than 9 */ if(n<11) { switch (n) { case 0: SEVEN_SEGMENT_PORT=0b00000011; break; case 1: SEVEN_SEGMENT_PORT=0b10011111; break;

case 2: SEVEN_SEGMENT_PORT=0b00100101; break; case 3: SEVEN_SEGMENT_PORT=0b00001101; break; case 4: SEVEN_SEGMENT_PORT=0b10011001; break; case 5: SEVEN_SEGMENT_PORT=0b01001001; break; case 6: SEVEN_SEGMENT_PORT=0b01000001; break; case 7: SEVEN_SEGMENT_PORT=0b00011111; break; case 8: SEVEN_SEGMENT_PORT=0b00000001; break; case 9: SEVEN_SEGMENT_PORT=0b00001001; break; case 10: //A BLANK DISPLAY SEVEN_SEGMENT_PORT=0b11111111; break; } if(dp) { //if decimal point should be displayed //make 0th bit Low SEVEN_SEGMENT_PORT&=0b11111110; } } else { //This symbol on display tells that n was greater than 10 //so display can't handle it SEVEN_SEGMENT_PORT=0b11111101; } } void Wait() { uint8_t i; for(i=0;i<10;i++) { _delay_loop_2(0); }

} void Print(uint16_t num) { /* This function breaks apart a given integer into separete digits and writes them to the display array i.e. digits[] */ uint8_t i=0; uint8_t j; if(num>9999) return; while(num) { digits[i]=num%10; i++; num=num/10; } //Fill with leading 0s for(j=i;j<4;j++) digits[j]=0; }

void main() { uint16_t i; // Prescaler = FCPU/1024 TCCR0|=(1<<CS02); //Enable Overflow Interrupt Enable TIMSK|=(1<<TOIE0); //Initialize Counter TCNT0=0; //Port c[3,2,1,0] as out put DDRC|=0b00001111; PORTC=0b00001110; //Port D SEVEN_SEGMENT_DDR=0XFF; //Turn off all segments SEVEN_SEGMENT_PORT=0XFF; //Set up the timer1 as described in the //tutorial //TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10); //initailly stop the timer by setting clock source =000 TCCR1B&=(~((1<<CS12)|(1<<CS11)|(1<<CS10))); OCR1A=250;

//Enable the Output Compare A interrupt TIMSK|=(1<<OCIE1A); //Enable interrupts globally sei(); //Continuasly display the time while(1) { int disp; //disp=(clock_hour*100)+clock_minute; disp=(clock_minute*100)+clock_second; Print(disp); if(!(PINB & (1<<PB2))) { //RESET PRESSED clock_millisecond=0; clock_second=0; clock_minute=0; clock_hour=0; } if(!(PINB & (1<<PB1))) { //halt pressed //stop the timer TCCR1B&=(~((1<<CS12)|(1<<CS11)|(1<<CS10))); //Start blinking the display blink_display=true; } if(!(PINB & (1<<PB0))) { //start pressed //start the timer //Set up the timer1 as described in the //tutorial TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10); //Stop blinking the display blink_display=false; //Show the display hide_display=false; } _delay_loop_2(0); _delay_loop_2(0); } } ISR(TIMER0_OVF_vect) {

/* This interrup service routine (ISR) Updates the displays */ static uint8_t i=0; if(i==3) { //If on last display then come //back to first. i=0; } else { //Goto Next display i++; } //Acivate a display according to i PORTC=~(1<<i); if(hide_display) { //Show a blank display SevenSegment(10,0); } else { //Write the digit[i] in the ith display. SevenSegment(digits[i],0); } //Handle blinking if(!blink_display) return; static uint8_t blink_counter=0; blink_counter++; if(blink_counter == 16) { blink_counter =0; hide_display=!hide_display; } } //The output compate interrupt handler //We set up the timer in such a way that //this ISR is called exactly at 1ms interval ISR(TIMER1_COMPA_vect) { clock_millisecond++; if(clock_millisecond==1000)

{ clock_second++; clock_millisecond=0; if(clock_second==60) { clock_minute++; clock_second=0; } if(clock_minute==60) { clock_hour++; clock_minute=0; } } }

Вам также может понравиться