/** * Драйвер модуля LED-индикаторов */ #include "stm8s.h" #include "led.h" #define GPIO_HIGH(a,b) a->ODR |= b #define GPIO_LOW(a,b) a->ODR &= ~b #define GPIO_TOGGLE(a,b) a->ODR ^= b uint8_t LedDigits[LED_DIGITS_NUM] = {0xff}; // digits to dsplay uint8_t LedPoint[LED_DIGITS_NUM] = {0, 1, 0, 0, 0, 0, 0, 1}; // dots for digits /* 1 2 3 4 5 6 7 8 */ static const uint8_t led_num[LED_DIGITS_NUM] = {0x08, 0x04, 0x02, 0x01, 0x10, 0x20, 0x40, 0x80}; static void led_SelectDigit (const uint8_t pos); /* * Output current value to next led */ void led_OutputValue(void) { static uint8_t ledn = 0; /* all off */ LED_OUT_OFF; /* Fire on nex led */ led_SelectDigit(ledn); /* out next value */ switch (LedDigits[ledn]) { case 0: LED_OUT_0; break; case 1: LED_OUT_1; break; case 2: LED_OUT_2; break; case 3: LED_OUT_3; break; case 4: LED_OUT_4; break; case 5: LED_OUT_5; break; case 6: LED_OUT_6; break; case 7: LED_OUT_7; break; case 8: LED_OUT_8; break; case 9: LED_OUT_9; break; case led_A: LED_OUT_A; break; case led_B: LED_OUT_B; break; case led_C: LED_OUT_C; break; case led_D: LED_OUT_D; break; case led_E: LED_OUT_E; break; case led_F: LED_OUT_F; break; case led_H: LED_OUT_H; break; case led_U: LED_OUT_U; break; case led_Plus: LED_OUT_PL; break; case led_Minus: LED_OUT_MM; break; case led_O: LED_OUT_O; break; case led_Off: break; default: LED_OUT_MM; } if(LedPoint[ledn] != 0) { LED_OUT_DP; } ledn ++; if (ledn >= LED_DIGITS_NUM) { ledn = 0; } } /* * Select LED Digit. * led digits sequence (b - bottom, t - top): * t1, t2, t4, t3, b1, b2, b3, b4. */ static void led_SelectDigit (const uint8_t pos) { uint8_t i; uint8_t data = led_num[pos]; for (i=0; i<8; i++) { GPIO_LOW(SPI_PORT, SPI_SCK); // prepare CLK if (data & 0x80) { // if msb == 1 GPIO_HIGH(SPI_PORT, SPI_DATA); // DATA = 1 } else { GPIO_LOW(SPI_PORT, SPI_DATA); // DATA = 0 } GPIO_HIGH(SPI_PORT, SPI_SCK); // shift bit data <<= 1; } /* hack for LATCH */ GPIO_LOW(SPI_PORT, SPI_DATA); GPIO_LOW(SPI_PORT, SPI_SCK); GPIO_HIGH(SPI_PORT, SPI_SCK); }