//*********************************************************************** // // rpm1.c // // Author: Jeremy Greenwood // // Microcontroller: ATtiny2313 // // Description: // // Calculate and display revolutions per minute of an optical // encoder with eight state changes per revolution. A millisecond // counter is used to determine the elapsed time. // // Changes: // //*********************************************************************** #define F_CPU 1000000UL // 1 MHz #include #include #include #include #include #include #define WAIT 2 // Define display outputs #define DB0 PB0 #define DB1 PB1 #define DB2 PB2 #define DB3 PB3 #define DB4 PB4 #define DB5 PB5 #define DB6 PB6 #define DB7 PB7 #define ENABLE PA0 #define RS PA1 // Define inputs #define IR PD2 // INT0 // Macro to initilize timer1 #define init_timer() {TCCR1B |= (1 << WGM12) | (0 << CS10) | (1 << CS11); OCR1A = 125; TIMSK |= (1 << OCIE1A);} // Macro to initialize interrupts #define init_interrupts() {MCUCR |= (0 << ISC01) | (1 << ISC00); GIMSK |= (1 << INT0); sei();} // Display macros #define enable() {on(ENABLE, A); _delay_ms( WAIT ); off(ENABLE, A);} #define init_display() {off(RS, A); PORTB = 0b1100; enable()} #define clear_display() {off(RS, A); PORTB = 0b1; enable();} #define return_home() {off(RS, A); PORTB = 0b10; enable();} #define write_display(val) {on(RS, A); PORTB = val; enable();} #define set_digit(dig) {off(RS, A); PORTB = 0b10000000 | dig; enable();} #define clear_str(str) {for( int z = 0; z < sizeof(str)/sizeof(char) - 1; z++ ) str[z] = 0;} #define write_number(num) write_display( 0b00110000 | num ); #define write_string(str) for( int z = 0; z < sizeof(str)/sizeof(char) - 1; z++ ) { if( str[z] == 0 ) break; write_display( str[z] );} #define write_string_right_adj(str,dig) int dig_val = dig; for( int z = sizeof(str)/sizeof(char) - 1; z >= 0; z-- ) { if( str[z] != 0 ){set_digit( dig_val-- );write_display( str[z] );}} char NAME[] = "Lets make robots", STATEMENT[] = "Wheel RPM:", BUFF[4]; volatile int tic = 0, count = 0, second_has_elapsed = 1; // 1ms timer interrupt ISR( TIMER1_COMPA_vect ) { tic++; // incremet 1ms counter // if( tic >= 1000 ) { if( tic >= 500 ) { tic = 0; second_has_elapsed = 1; } } ISR( INT0_vect ) { count++; } int main (void) { int digit, rpm; // define outputs DDRB = 0xff; // DB outputs out(ENABLE, A); out(RS, A); off(ENABLE, A); init_timer(); init_interrupts(); _delay_ms( 200 ); init_display(); clear_display(); set_digit(2); write_string( NAME ); _delay_ms( 2000 ); clear_display(); set_digit(3); write_string( STATEMENT ); digit = sizeof(STATEMENT)/sizeof(char) - 1; digit += 6; while(1) { if( second_has_elapsed ) { // calculate and display rpm every second set_digit(13); write_string(" "); // rpm = (count * 15) / 2; // calculation of rpm derived from 60 seconds / 8 state changes per revolution rpm = (count * 15); clear_str( BUFF ); itoa( rpm, BUFF, 10); write_string_right_adj( BUFF, digit ); second_has_elapsed = 0; count = 0; } } }