Если не хватает ног...

Наткнулся я в очередной раз на типичную проблему. Надо было включить в схему несколько светодиодов, а ног нехватало. Переходить на другой процессор было неудобно, и пришлось выдумывать очередной финт (или "hint"?).

Оказалось, что можно включить светодиоды вот так:

Смотрите, если на одну ногу подать единичку, на другую - ноль, а третью оставить входом, загорится только один светодиод. Ну а уж про мультиплексный режим, я надеюсь, вам рассказывать не нужно.

Можно выдумать мультиплексный режим, при котором зажигаются одновременно по два светодиода. В таком случае общая яркость увеличится (скважность больше). К сожалению, при этом яркость каждого светодиода будет зависеть от светящейся комбинации. Хотя в большинстве случаев это несущественно.

Таким образом можно повесить шесть светодиодов на три ноги, двенадцать - на четыре и т.д. Впрочем, советую не увлекаться.

Особенно удобно использовать такую схему для включения двуцветных светодиодов, которые соединены внутри встречно-параллельно.

Ниже приведен пример программы. Он компилировался AVR-GCC 3.3 для ATmega163. Светодиоды были подключены к ногами PB.0 - PB.3. В этом примере одновременно зажигаются до двух светодиодов (скважность 1/3).

Собственно процедура регенерации выглядит примерно так:

unsigned char leds;           // Bits are the leds states

void LEDs_refresh(void)
{
static unsigned char state;   // Current refresh state    

  OFF();                      // Turn all pins to High-Z

  switch (state)
  {
  default:
    CLR_0();                  // Turn pin 0 low
    if (leds &  1) {SET_1();} // Turn pin 1 high for led 1
    if (leds &  2) {SET_2();} // Turn pin 2 high for led 2
    state=1;                  // Next state
    break;
  case 1:
    CLR_1();                  // Turn pin 1 low          
    if (leds &  4) {SET_0();} // Turn pin 0 high for led 3
    if (leds &  8) {SET_2();} // Turn pin 2 high for led 4
    state=2;                  // Next state
    break;
  case 2:
    CLR_2();                  // Turn pin 2 low          
    if (leds & 16) {SET_0();} // Turn pin 0 high for led 5
    if (leds & 32) {SET_1();} // Turn pin 1 high for led 6
    state=0;                  // Next state
    break;
  }
}

Эту процедуру нужно вызывать с частотой, скажем, герц сто, чтобы моргание светодиодов не было видно человеческим глазом. Это удобно делать из прерывания от таймера.

Целиком пример проекта можно скачать в виде архива: 6leds.zip