|
- #include <stdbool.h>
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #define F_CPU 20000000UL //20 MHz
- #include <util/delay.h>
-
- /* 7-Segment display: */
- #define NUM_DIGITS 3U //3 Digits
- #define DIGIT_TENS 2U //left
- #define DIGIT_ONES 1U //middle
- #define DIGIT_UNIT 0U //right
- #define SELECT_DIGIT(digit) (1U << digit)
-
- #define TEMP_MIN 0U
- #define TEMP_MAX 50U
-
- #define BUTTON_THRESHOLD 50U //software debounce
-
- /* Symbol indexes: */
- #define SYM_n 10U
- #define SYM_o 11U
- #define SYM_E 12U
- #define SYM_R 13U
- #define SYM_DEG_CELCIUS 14U
- #define SYM_P_P 15U
- #define SYM_OFF 16U
- #define SYM_DASH 17U
-
- /*
- 7-Segment Layout:
-
- A
- F B
- G
- E C
- D P
-
- Pin 7 6 5 4 3 2 1 0
- Segment A F B E D C G P
- */
- static uint8_t g_au8Symbols[18U] =
- {
- /* 00 */ 0b11111100U, //0 (ABCDEF)
- /* 01 */ 0b00100100U, //1 (BC)
- /* 02 */ 0b10111010U, //2 (ABDEG)
- /* 03 */ 0b10101110U, //3 (ABCDG)
- /* 04 */ 0b01100110U, //4 (BCFG)
- /* 05 */ 0b11001110U, //5 (ACDFG)
- /* 06 */ 0b11011110U, //6 (ACDEFG)
- /* 07 */ 0b10100100U, //7 (ABC)
- /* 08 */ 0b11111110U, //8 (ABCDEFG)
- /* 09 */ 0b11101110U, //9 (ABCDFG)
- /* 10 */ 0b00010110U, //n (CEG) SYM_n
- /* 11 */ 0b00011110U, //o (CDEG) SYM_o
- /* 12 */ 0b11011010U, //E (ADEFG) SYM_E
- /* 13 */ 0b00010010U, //r (EG) SYM_r
- /* 14 */ 0b10101101U, //degC (ABCDP) SYM_DEG_CELCIUS
- /* 15 */ 0b11110011U, //P. (ABEFGP) SYM_P_P
- /* 16 */ 0b00000000U, //OFF SYM_OFF
- /* 17 */ 0b00000010U //- (G) SYM_DASH
- };
-
- static uint8_t g_u8WaterTemperature = 24U; //Water temperature, default 24 degree celcius
- static uint8_t g_u8CountIncs = 0U; //'+' button counter
- static uint8_t g_u8CountDecs = 0U; //'-' button counter
-
- uint8_t g_u8ISRDigitSelect = 0U;
- uint8_t g_au8Digits[3U] =
- {
- SYM_OFF, //unit
- SYM_OFF, //ones
- SYM_OFF //tens
- };
-
- void vInit( void );
- void vSetValue( uint8_t u8Value, uint8_t u8Unit );
- void vSetDisplayDigits( uint8_t u8Tens, uint8_t u8Ones, uint8_t u8Unit );
- void vReadButtons( void );
- void vCalculate( void );
-
- /************************************************************************/
- /* Timer1 ISR - show values on display */
- /************************************************************************/
- ISR ( TIMER1_COMPA_vect )
- {
- PORTB = 0;
- PORTD = 0;
- _delay_us(2);
- PORTB = SELECT_DIGIT(g_u8ISRDigitSelect);
- PORTD = g_au8Symbols[g_au8Digits[g_u8ISRDigitSelect]];
- g_u8ISRDigitSelect++;
- if (g_u8ISRDigitSelect > 2U)
- {
- g_u8ISRDigitSelect = 0U;
- }
- }
-
- /************************************************************************/
- /* main() */
- /************************************************************************/
- int main(void)
- {
- /* Init I/O: */
- vInit();
-
- /* Set default value: */
- vSetDisplayDigits( SYM_DASH, SYM_DASH, SYM_DASH );
-
- /* wait 3 seconds */
- _delay_ms(3000);
-
- /* Set default value: */
- vSetValue( g_u8WaterTemperature, SYM_DEG_CELCIUS );
-
- while ( 1 )
- {
- vReadButtons();
- vCalculate();
- _delay_ms(3);
- }
-
- return 0;
- }
-
- /************************************************************************/
- /* Initialize inputs and outputs */
- /************************************************************************/
- void vInit( void )
- {
- /* Port D - Pins 0-7: Outputs */
- DDRD = 0b11111111U;
-
- /* Port B - Pins 0-2: Outputs */
- DDRB = 0b00000111U;
-
- /* Port C - Pins 4-5: Inputs with internal Pull-up */
- PORTC = 0b00110000U;
-
- /* 16-bit TIMER1 in CTC mode
- * prescaler = 8
- * 20 MHz / 8 = 2.5 MHz
- * Compare value = 2500 => 1 ms IRQ
- */
- TCCR1A = 0U;
- TCCR1B = (1<<WGM12) | (1<<CS11);
- OCR1A = 2500U;
- TIMSK1 |= (1<<OCIE1A);
- sei();
-
- return; //void
- }
-
- /************************************************************************/
- /* */
- /************************************************************************/
- void vDigitTest( void)
- {
- PORTB = SELECT_DIGIT(DIGIT_TENS);
- PORTD = 0xFF;
- _delay_ms(1000);
- PORTD = 0;
- _delay_ms(100);
-
- PORTB = SELECT_DIGIT(DIGIT_ONES);
- PORTD = 0xFF;
- _delay_ms(1000);
- PORTD = 0;
- _delay_ms(100);
-
- PORTB = SELECT_DIGIT(DIGIT_UNIT);
- PORTD = 0xFF;
- _delay_ms(1000);
- PORTD = 0;
- _delay_ms(100);
-
-
-
- return; //void
- }
-
- /************************************************************************/
- /* Set new values to be shown on display */
- /************************************************************************/
- void vSetValue( uint8_t u8Value, uint8_t u8Unit )
- {
- uint8_t u8Tmp = u8Value / 10U;
- vSetDisplayDigits(u8Tmp, u8Value - (u8Tmp * 10U), u8Unit);
-
- return; //void
- }
-
- /************************************************************************/
- /* Set display digits individually */
- /************************************************************************/
- void vSetDisplayDigits( uint8_t u8Tens, uint8_t u8Ones, uint8_t u8Unit )
- {
- g_au8Digits[DIGIT_TENS] = u8Tens;
- g_au8Digits[DIGIT_ONES] = u8Ones;
- g_au8Digits[DIGIT_UNIT] = u8Unit;
-
- return; //void
- }
-
- /************************************************************************/
- /* Read button status */
- /************************************************************************/
- void vReadButtons( void )
- {
- if ( !(PINC & (1<<PINC4)) ) //if button '+' pressed
- {
- g_u8CountIncs++;
- }
- else
- {
- g_u8CountIncs = 0U; //reset button counter
- }
- if ( !(PINC & (1<<PINC5)) ) //if button '-' pressed
- {
- g_u8CountDecs++;
- }
- else
- {
- g_u8CountDecs = 0U; //reset button counter
- }
-
- return; //void
- }
-
- /************************************************************************/
- /* */
- /************************************************************************/
- void vCalculate( void )
- {
- bool blChanged = false;
-
- if ( g_u8CountIncs > BUTTON_THRESHOLD )
- {
- g_u8WaterTemperature++;
- if ( g_u8WaterTemperature > TEMP_MAX )
- {
- g_u8WaterTemperature = TEMP_MIN;
- }
- blChanged = true;
- g_u8CountIncs = 0U; //reset increment counter
- }
- if ( g_u8CountDecs > BUTTON_THRESHOLD )
- {
- if ( g_u8WaterTemperature == TEMP_MIN )
- {
- g_u8WaterTemperature = TEMP_MAX;
- }
- else
- {
- g_u8WaterTemperature--;
- }
- blChanged = true;
- g_u8CountDecs = 0U; //reset decrement counter
- }
-
- if ( blChanged )
- {
- vSetValue( g_u8WaterTemperature, SYM_DEG_CELCIUS );
- }
-
- return; //void
- }
|