«

»

Распечатать Запись

Динамическая индикация 9 разрядного индикатора по последовательной шине (ATmega8, 74HC595D, C)

Индикатор 9 разрядный семисегментный с последовательной шиной, выполнен на двух микросхемах 74HC595D. Индикатор стоял в телефоне с АОН русь 27, до того как по нему прошлась гроза, да так что, восстановлению телефон не подлежал, индикатору тоже досталось, сгорели все 2 микросхемы. Проверить его оказалось просто. При рабочих микросхемах и поданном питании, если прикоснуться к линиям данных, на индикаторе бегает всякая ерунда (при условии что линии висят в воздухе). Индикатор с динамической индикацией, то есть для отображения информации последовательно зажигаем каждую цифру на определенное время, например на 2 миллисекунды. Сложностей с ним почти нет, если не учитывать что выходов у 74HC595D восемь, а цифр на индикаторе девять. Девятая цифра подключена к выводу Q7' последовательный выход данных. Какие выводы и для чего они нужны, читайте в DATASHEET на микросхему.

Здесь я просто расскажу, как я решил проблему вывода 8 и 9 цифры. Работать с этими микросхемами просто. Для того чтобы загрузить данные, устанавливаем, бит данных на выводе DS serial data input, и сдвигаем (загружаем) положительным импульсом SHcp shift register clock input. Для сохранения и вывода данных в регистре подаем положительный импульс на STcp storage register clock input. Неувязка получается при выводе 8 и 9 цифры. Индикатор здесь с общим катодом, чтобы включить, например 4 цифру, нужно загрузить число 0b11110111, при этом на выходе Q7' будет сдвинутое значение из Q6, в данном случае 1, то, что нужно. Значение Q6 по положительному импульсу SHcp сдвигается в Q7'. При выводе восьмой цифры ноль сдвигается в Q7 и Q7' (Q7'=1 0b10111111 Q7'=0 0b01111111), в итоге у нас включены 8 и 9 разряд, импульсом STcp сохраняем и выводим это значение, теперь если дать импульс SHcp копейка из Q6 переместится в Q7', 9 разряд потушен. Для включения 9 разряда нужно загрузить число 0b11111111, вывести его импульсом STcp, затем загружаем в регистр нули до тех пор, пока ноль из Q6 не переместится в Q7'.1Может быть все это можно сделать проще. У меня индикатор заработал, и я на этом успокоился. Сейчас он работает в часах. В часах есть возможность регулировки яркости индикатора. Период включения каждой цифры 2 ms. Что бы уменьшить яркость индикатора, цифру можно включать, например на 1 ms, оставшиеся время она будет потушена. При этом яркость свечения снижается.

// WinAvr
#include <avr/io.h>
#include <avr/interrupt.h>

#define DATA  PD5
#define SHIFT PD6
#define STORAGE PD7
#define PORTSERIAL PORTD
#define PORTBUT  PORTD
#define PINBUT  PIND
#define DDRSERIAL  DDRD
#define button   BIT(0)
#define BIT(bit)  (1<<(bit))

unsigned char lcd_buffer[9]={0xEB, 0x48, 0x73, 0x7A, 0xD8, 0xBA, 0xBB, 0x73, 0x68};

//*************************************************************
void data_shift(unsigned char data)
{
// выводим бит данных, сдвигаем и так 8 раз.
  unsigned char i=0;

  for(i=8; i ; i--){
  if (data & BIT(7) )  PORTSERIAL|=BIT(DATA);    // выводим бит данных

                    else   PORTSERIAL&=~BIT(DATA);
  data<<=1;
  PORTSERIAL|=BIT(SHIFT); // сдвиг данных

  PORTSERIAL&=~BIT(SHIFT);
 }
}
//*************************************************************
void num_out(unsigned char znmesto)

{
 PORTSERIAL|=BIT(STORAGE);// выводы микросхем в Z состояние
 data_shift(lcd_buffer[znmesto]);// загружаем символ в первый регистр

 data_shift(~(1<<(znmesto)));// вывод знакоместа, символ сдвигается в второй регистр
 // ~(1<<(znmesto)) - число в бит места (пример 0х3->0b11110111)

 PORTSERIAL&=~BIT(STORAGE);

 PORTSERIAL|=BIT(STORAGE);    // сохранили
 PORTSERIAL&=~BIT(STORAGE);    // и вывели

 if (znmesto==7){// 7 знакоместо
    PORTSERIAL|=BIT(SHIFT);

    PORTSERIAL&=~BIT(SHIFT);
    //shift нужен потому что 0 переместился из Q6 в -Q7`
    }
 if (znmesto==8)   data_shift(0x0);//9 разряд.

  //Сейчас все выходы первого регистра уст в 1,
  //загружаем регистр нулями в итоге -Q7 = 0, но не сохраняем.

  PORTSERIAL&=~(BIT(DATA)|BIT(SHIFT)|BIT(STORAGE));

}
//*************************************************************
int main( void )
{
unsigned char i=0;

    PORTSERIAL|=BIT(STORAGE);
    DDRSERIAL=0xf0;
    PORTBUT|=button;

    TCCR0=3;
    while(1){
        TCNT0=127;

        while( !(TIFR & BIT(TOIE0)) );// Задержка ~2ms
        TIFR|=1;

        //if ( !(PINBUT & button) ) //если включить то вывод цифры
        {
        //while ( !(PINBUT & button) );// будет только по нажатию
        num_out(i);

        if (++i>8) i=0;
        }
    }

}

Постоянная ссылка на это сообщение: http://meandr.org/archives/1730

Добавить комментарий