/* ------------------------------------------------------------ mpx_2digit_demo.c 2 stellige gemultiplexte 7-Segmentanzeige mit gemeinsamer Anode MCU : attiny84 F_CPU : 8000000 07.02.2022 by R. Seelig ------------------------------------------------------------ */ #include #include #include #include #include "mpx_2conc.h" /* ATtiny 24 / 44 / 84 Anschlusspins IC +-----------+ Vcc | 1 A 14 | GND PB0 - PCINT8 - XTAL1 - SCI - CLKI | 2 T 13 | PA0 - ADC0 - AREF - PCINT0 PB1 - PCINT9 - XTAL2 | 3 t 12 | PA1 - ADC1 - AIN0 - PCINT1 PB3 - PCINT11 - /reset | 4 i 11 | PA2 - ADC2 - AIN1 - PCINT2 PB2 - PCINT10 - INT0 - OC0A / CKOUT | 5 n 10 | PA3 - ADC3 - T0 - PCINT3 PA7 - PCINT7 - ICP - OC0B - ADC7 | 6 y 9 | PA4 - ADC4 - USCK - SCL - T1 - SDO- PCINT4 PA6 - OC1A - SDA - SDI -MOSI - DI - ADC6 | 7 8 | PA5 - ADC5 - DO - MISO - OC1B - SII -PCINT5 +-----------+ */ // Zuordnung der Anschluesse der 7-Segmentanzeige zu den Portpins // des Controllers #define kseg1 A3 #define kseg0 A5 #define seg_a A1 #define seg_b A4 #define seg_c A7 #define seg_d B1 #define seg_e B0 #define seg_f A2 #define seg_g A6 #define seg_dp B2 /* -------------------------------------------------------- Framebuffer, dieses Bitmuster wird auf der 7-Segmentanzeige angezeigt. Zentrales Element, da lediglich auf diese beiden Bytes geschrieben werden muss, um Segmente auf der Anzeige zum Leuchten zu bringen -------------------------------------------------------- */ volatile uint8_t seg7_fb[2]; /* -------------------------------------------------------- Bitmuster fuer alphanumerische 7-Segmentanzeige 0..9, A..F seg7_bmp[16]= alle aus -------------------------------------------------------- */ uint8_t seg7_bmp[17] = { ~0x3F, ~0x06, ~0x5B, ~0x4F, ~0x66, ~0x6D, ~0x7D, ~0x07, ~0x7F, ~0x6F, ~0x77, ~0x7C, ~0x39, ~0x5E, ~0x79, ~0x71, ~0x00 }; uint8_t seg7_dpmask = 0x00; // Maske fuer anzuzeigende Dezimalpunkte // 0xff = alle DPs aus, 0x01 = rechter DP an, // 0x02 = linker DP an // 0x03 = beide DP an /* -------------------------------------------------------- seg7_allclr schaltet alle Segmente einer Anzeige aus, funktioniert schneller als seg7_setbmp(0) -------------------------------------------------------- */ void seg7_allclr(void) { a_segclr(); b_segclr(); c_segclr(); d_segclr(); e_segclr(); f_segclr(); g_segclr(); dp_segclr(); } /* -------------------------------------------------------- seg7_setbmp schaltet einzelne Segmente einer Anzeige an oder aus, je nachdem, welches Bitmuster uebergeben wurde; -------------------------------------------------------- */ void seg7_setbmp(uint8_t bmp) { if (bmp & 0x01) a_segset(); else a_segclr(); if (bmp & 0x02) b_segset(); else b_segclr(); if (bmp & 0x04) c_segset(); else c_segclr(); if (bmp & 0x08) d_segset(); else d_segclr(); if (bmp & 0x10) e_segset(); else e_segclr(); if (bmp & 0x20) f_segset(); else f_segclr(); if (bmp & 0x40) g_segset(); else g_segclr(); if (bmp & 0x80) dp_segset(); else dp_segclr(); } /* -------------------------------------------------------- seg7_initall initialisiert alle benoetigten GPIO Pins -------------------------------------------------------- */ void seg7_initall(void) { kseg0_init(); kseg1_init(); a_seginit(); b_seginit(); c_seginit(); d_seginit(); e_seginit(); f_seginit(); g_seginit(); dp_seginit(); } /* -------------------------------------------------------- fb_clear loescht den Framebuffer (alle LEDs aus) -------------------------------------------------------- */ void fb_clear(void) { seg7_fb[0]= 0; seg7_fb[1]= 0; } /* -------------------------------------------------------- fb_sethex beschreibt den Framebuffer mit einem 2 stelligen Hexadezimalwert -------------------------------------------------------- */ void fb_sethex(uint8_t val) { seg7_fb[0] = seg7_bmp[val & 0x0f]; seg7_fb[1] = seg7_bmp[(val & 0xf0) >> 4]; } /* -------------------------------------------------------- fb_setdez beschreibt den Framebuffer mit einem 2 stelligen Dezimalwert -------------------------------------------------------- */ void fb_setdez(uint8_t val) { seg7_fb[0] = seg7_bmp[val % 10]; seg7_fb[1] = seg7_bmp[val / 10]; } /* -------------------------------------------------------- Interruptvector Timer 1 Interruptroutine, multiplext die 7-Segmentanzeige -------------------------------------------------------- */ ISR (TIM1_COMPA_vect) { static uint8_t gk_cnt = 0; volatile uint8_t bmp_tmp; seg7_allclr(); switch (gk_cnt) { case 0 : kseg0_clr(); break; case 1 : kseg1_clr(); break; default : break; } gk_cnt++; gk_cnt = gk_cnt % 2; switch (gk_cnt) { case 0 : kseg0_set(); break; case 1 : kseg1_set(); break; default : break; } // Bitmapmuster des 7-Segmentdigits in Abhaengigkeit des // aktuell aktiven Segments laden bmp_tmp = seg7_fb[gk_cnt]; bmp_tmp |= 0x80; if (seg7_dpmask & (1 << gk_cnt)) bmp_tmp &= ~0x80; // Dezimalpunktanzeige seg7_setbmp(bmp_tmp); } /* -------------------------------------------------------- mxp_init initialisiert den Timerinterrupt und die Portpins, an den die 7-Segmentanzeige angeschlossen ist -------------------------------------------------------- */ void mpx_init(void) { TCCR1B = 1<