PIC мк. Эксперимент №4. Подключение семисегментного индикатора.

Задача: Отобразить цифры от 0 до 9 на семисегментном индикаторе

Исходный материал: PIC16f628a, семисегментный индикатор с общим катодом, breadboard

В этом эксперименте я пойду немного не стандартным путем и не буду использовать 8 ног мк чтобы подключить один лишь индикатор, жалко ног столько зря терять. Поэтому добавим к схеме еще сдвиговый регистр, например 74нс164, очень полезная штука. Теперь вместо восьми ног нам понадобится всего 4:

  1. На тактирование.
  2. На сброс.
  3. На данные.
  4. На питающий транзистор.

Экономия – налицо! Работу сдвигового регистра я описывать не буду, всегда можно заглянуть в даташит – там все предельно понятно расписано. Для начала соберем тестовую схему, а потом напишем код, который будет отображать наши цифры с периодом 1 с (этакий простой секундомерчик до 10 секунд).

Итак для начала соберем тестовую схему:

Кнопку я добавил, чтобы четко определять старт программы. Ну и еще резистор R11 по сути там не нужен, но протеус, собака такая, отказывался нормально моделировать без него. В принципе сложного ничего нету, единственный момент, на который стоит обратить внимание – это то, что я с целью экономии памяти расположил массивы чисел в ROM.

#include htc.h
#define _XTAL_FREQ 4000000
#define CK RB2
#define RESET RB1
#define DATA RB3
#define TRIG RB7
__CONFIG(MCLREN &UNPROTECT & WDTDIS);
void tick() {
             CK = 1;
             __delay_us(100);
             CK = 0;
             __delay_us(100);
             }
void vpih(unsigned char digit[8]) {
unsigned char i=0;
TRIG = 0;
for (i=0;i<8;i++) {
                  DATA = digit[i];
                  tick();
                  }
TRIG = 1;
}
const char point[8] = {1,0,0,0,0,0,0,0};    // Точка
const char one[8] = {0,0,0,0,0,1,1,0};      // Один
const char two[8] = {0,1,0,1,1,0,1,1};      // Два
const char three[8] = {0,1,0,0,1,1,1,1};    // Три
const char four[8] = {0,1,1,0,0,1,1,0};     // Четыре
const char five[8] = {0,1,1,0,1,1,0,1};     // Пять
const char six[8] = {0,1,1,1,1,1,0,1};      // Шесть
const char seven[8] = {0,0,0,0,0,1,1,1};    // Семь
const char eight[8] = {0,1,1,1,1,1,1,1};      // Восемь
const char nine[8] = {0,1,1,0,1,1,1,1};      // Девять
const char zero[8] = {0,0,1,1,1,1,1,1};      // Ноль
void main() {
unsigned char i=0;
TRISB = 0b00000001;
DATA = 0;
RESET = 0;
tick();
RESET = 1;
for (;;) {
          if (RB0 == 0) {
                         __delay_ms(30); if (RB0 == 0) {
                         vpih(zero);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                         vpih(one);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                         vpih(two);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                         vpih(three);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                         vpih(four);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                         vpih(five);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                         vpih(six);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                         vpih(seven);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                         vpih(eight);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                         vpih(nine);
                         for(i=0;i<10;i++){ __delay_ms(100);    }
                   }
          }
  }
}

PS. В этой программе хреново используется массив, это я в начале своего обучения допустил такой косячок, но править мне уже лень :)

Исходники здесь

PIC мк. Эксперимент №4. Подключение семисегментного индикатора.: 11 комментариев

  1. Смахивает на какой то быдлокод, мне для отображения одной цифры достаточно одной ячейки чар,а тут целых восемь!
    Разговор шел про экономию памяти, а на самом деле ее больше затрачено, чем необходимо.Только оперативную сэкономили.

    Ответить

  2. так и есть, для всех цифр достаточно было бы одного определения массива (о чем я кстати в конце написал)

    const unsigned char digits[9] =
    {0b10000000,
    0b00000110,
    ….
    };

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

    Ответить

  3. Если прописать таким образом массив ,
    const unsigned char digits[9] = {
    0b10000000,
    0b00000110,
    …. };
    тогда как будет воспринимать сдвиговый регистр нули и единицы? У меня таким образом ничего не получилось. Зато удачно получилось с двумерным массивом. Или я где ошибся и это нерационально? Код у меня этот работает отлично:

    const unsigned char digit[10][8]={
    {0,0,1,1,1,1,1,1}, //0
    {0,0,0,0,0,1,1,0}, //1
    {0,1,0,1,1,0,1,1}, //2
    {0,1,0,0,1,1,1,1}, //3
    {0,1,1,0,0,1,1,0}, //4
    {0,1,1,0,1,1,0,1}, //5
    {0,1,1,1,1,1,0,1}, //6
    {0,0,0,0,0,1,1,1}, //7
    {0,1,1,1,1,1,1,1}, //8
    {0,1,1,0,1,1,1,1}, //9
    };
    void main() {
    TRISB = 0b00000001;
    DATA = 0;
    RESET = 0;
    RESET = 1;
    for (;;){
    for (n=0; n<10; n++){
    for (i=0; i<8; i++){
    DATA = digit[n][i];
    tick();
    }
    __delay_ms(50);
    }
    }
    }

    Ответить

    sarge Ответил:

    Он будет их воспринимать ровно так как вы ему скажете, модернизируйте функцию до уровня определения каждого бита и все будет ок.
    Двумерный массив это еще хуже чем моя первая версия и я не понимаю зачем его здесь в принципе использовать.
    Повторяем 8 раз
    1. Взяли последний бит
    2. Выпихнули
    3. Сдвинули байт на одну позицию вправо

    Ответить

  4. Исправьте мое сообщения.
    В строке №17 наверное, ошибка – for(i=0;i<8;i++) {
    Возможно, там должно быть – for (i=0;i<8;i++) {

    Ответить

  5. Указал на ошибку в своем сообщении, но при загрузке она автоматически исправляется. Уже третий раз не буду указывать место ошибки Вы, наверное, сами найдете.

    Ответить

    sarge Ответил:

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

    Ответить

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">