Задача: Отобразить цифры от 0 до 9 на семисегментном индикаторе
Исходный материал: PIC16f628a, семисегментный индикатор с общим катодом, breadboard
В этом эксперименте я пойду немного не стандартным путем и не буду использовать 8 ног мк чтобы подключить один лишь индикатор, жалко ног столько зря терять. Поэтому добавим к схеме еще сдвиговый регистр, например 74нс164, очень полезная штука. Теперь вместо восьми ног нам понадобится всего 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. В этой программе хреново используется массив, это я в начале своего обучения допустил такой косячок, но править мне уже лень)))
Источник: http://diymicro.ru/?p=59 |