Код (C++): int dataPin = 5; int latchPin = 7; int clockPin = 6; int qqq=100; byte data = 0; void setup() { //устанавливаем режим OUTPUT pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop(){ set(3,3,3,3); //count(1,0); } void count(int m,int s){ if(s>9){ if(m>9){ set(m%10,m/10,s%10,s/10); } else{ set(0,m/10,s%10,s/10); } if(m>9){ set(m%10,m/10,0,s/10); } else{ set(0,m/10,0,s/10); } } if (s ==-1){ if(m!=0) { s=59; m--; } else{ return 0; } } delay(1000); s--; } void set(int a,int b,int c,int d) { digitalWrite(13,LOW); digitalWrite(12,HIGH); digitalWrite(11,HIGH); digitalWrite(10,HIGH); switch (a) { case 0: data = B11111100; break; case 1: data = B10100000; break; case 2: data = B11011010; break; case 3: data = B11110010; break; case 4: data = B10100110; break; case 5: data = B01110110; break; case 6: data = B01111110; break; case 7: data = B11100000; break; case 8: data = B11111110; break; case 9: data = B11110110; break; case 10://point . data = B00000001; break; } digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, data); digitalWrite(latchPin, HIGH); delay(qqq); digitalWrite(13,HIGH); digitalWrite(12, LOW); digitalWrite(11,HIGH); digitalWrite(10,HIGH); switch (b) { case 0: data = B11111100; break; case 1: data = B10100000; break; case 2: data = B11011010; break; case 3: data = B11110010; break; case 4: data = B10100110; break; case 5: data = B01110110; break; case 6: data = B01111110; break; case 7: data = B11100000; break; case 8: data = B11111110; break; case 9: data = B11110110; break; case 10://point . data = B00000001; break; } digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, data); digitalWrite(latchPin, HIGH); delay(qqq); digitalWrite(13,HIGH); digitalWrite(12,HIGH); digitalWrite(11,LOW); digitalWrite(10,HIGH); switch (c) { case 0: data = B11111100; break; case 1: data = B10100000; break; case 2: data = B11011010; break; case 3: data = B11110010; break; case 4: data = B10100110; break; case 5: data = B01110110; break; case 6: data = B01111110; break; case 7: data = B11100000; break; case 8: data = B11111110; break; case 9: data = B11110110; break; case 10://point . data = B00000001; break; } digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, data); digitalWrite(latchPin, HIGH); delay(qqq); digitalWrite(13,HIGH); digitalWrite(12,HIGH); digitalWrite(11,HIGH); digitalWrite(10,LOW); switch (d) { case 0: data = B11111100; break; case 1: data = B10100000; break; case 2: data = B11011010; break; case 3: data = B11110010; break; case 4: data = B10100110; break; case 5: data = B01110110; break; case 6: data = B01111110; break; case 7: data = B11100000; break; case 8: data = B11111110; break; case 9: data = B11110110; break; case 10://point . data = B00000001; break; } digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, data); digitalWrite(latchPin, HIGH); delay(qqq); digitalWrite(13, HIGH); digitalWrite(12, HIGH); digitalWrite(11, HIGH); digitalWrite(10, HIGH); //EEEENNNNDDDD } тут ссылка на реакцию дисплея и тд. (чёрная макетка, на ней схема рабочая, проверял. показывает нормально, проблема с выбором разряда.
Подключал 2 независимых индикатора каждый через свой сдвиговый регистр, см. фото: Как тут подключается не знаю, может тот же принцип. Возможно тебе поможет код: Код (C++): #define DATA 6 //К ВЫВОДУ 14 МИКРОСХЕМЫ #define LATCH 8 //К ВЫВОДУ 12 МИКРОСХЕМЫ #define CLOCK 10 //К ВЫВОДУ 11 МИКРОСХЕМЫ //ПОДГОТОВИТЬ МАССИВ С КОМБИНАЦИЯМИ СЕГМЕНТОВ //ДЛЯ ЦИФР 0-9 И БУКВ A-F int digits[]={252,96,218,242,102,182,190,224,254,246,238,62,156,122,158,142}; void setup() { Serial.begin(9600); pinMode(LATCH,OUTPUT); pinMode(CLOCK,OUTPUT); pinMode(DATA,OUTPUT); } void displayNumber(int n) { int left,right=0; if (n<10) { Serial.print("Left is "); Serial.print(0,1); Serial.print(" Right is "); Serial.print(n,1); digitalWrite (LATCH,LOW); shiftOut(DATA,CLOCK,LSBFIRST,digits[n]); shiftOut(DATA,CLOCK,LSBFIRST,252); digitalWrite(LATCH,HIGH); } else if(n>=10) { right=n%10; //остаток от деления числа на 10 left=n/10; //частное от деления числа на 10 Serial.print("Left is "); Serial.print(left,1); Serial.print(" Right is "); Serial.print(right,1); digitalWrite(LATCH,LOW); shiftOut(DATA,CLOCK,LSBFIRST,digits[right]); shiftOut(DATA, CLOCK,LSBFIRST,digits[left]); digitalWrite(LATCH,HIGH); } } void loop() { int i; for(i=0;i<100;i++) { displayNumber(i); Serial.print(" // Integer indicated "); Serial.println(i,1); delay(1000); } }
По правде говоря в нем тоже есть проблема: На правом индикаторе, который считает цифры (в коде переменная right), некоторые значения отображаются с точкой, что удивительно. Переменная right определяет порядковый номер в массиве digits. В массиве у меня указаны четные числа,т.е. сигнал на DP будет 0. Кто может подсказать, как это решить?
Картинка без крутилки переменника В общем надо сделать код таймера обратного отсчёта. И чтобы время можно было регулировать в переменной. Только в формате мм/сс. Ещё желательно на любой свободный пин реле прицепить.
Дорогой, искал индикатор и нашел решение твой проблемы=) http://arduino.ru/forum/proekty/vyv...mentnyi-indikator-pri-pomoshchi-dvukh-74hc595 Очень крутой и понятный код. Но в этом коде генерируются случайные числа, чтобы был обратный отсчет нужно немного поработать с кодом.
Код (C++): #define latchPin 8 //Пин "защелки" первого регистра подключен к ST_CP входу первого регистра отвечающего за сегменты #define latchPin2 9 //Пин "защелки" второго регистра подключен к ST_CP входу первого регистра отвечающего за разряды #define clockPin 12 //Пин подключен к SH_CP входу 74HC595 #define dataPin 11 //Пин подключен к DS входу 74HC595 int TimeLight = 5; //время для разогрева сегментов int sensorPin=A0; byte SegDisplay; // переменная для вывода символов на индикаторе byte RazrDisplay; // переменная для включения разрядов // Настройка комбинации для отображения каждого номера на дисплее. // Комбинация выбрана на основе таблицы отображаемого знака данным порта // Соответственно { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , dp, - } byte g_digits[12]={192,249,164,176,153,146,130,248,128,144,127,255}; //массив цифр, генерирующий из сегментов цифры byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды void setup() { Serial.begin (9600); // обозначаем все пины как выходы pinMode(latchPin, OUTPUT); pinMode(latchPin2, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void Segment(int x) //функция для записи в 1 регистр информации для генерации символов { digitalWrite(latchPin, LOW); // устанавливаем синхронизацию "защелки" на LOW SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре. shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay); // Записываем информацию в регистр digitalWrite(latchPin, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах } void Razryad(int r) //функция для записи во 2 регистр номера разряда индикатора { digitalWrite(latchPin2, LOW); // устанавливаем синхронизацию "защелки" на LOW RazrDisplay=g_registerArray[r]; // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре. shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию в регистр digitalWrite(latchPin2, HIGH); //"защелкиваем" регистр, тем самым устанавливая значения на выходах delay(TimeLight); // пауза, чтобы сегменты "разгорелись" } void loop() { int disp = 9999; //создаем переменную для вывода на экран for (disp=9999;disp<10000;disp--)//disp=НАЧАЛЬНОМУ ЗНАЧЕНИЮ ОТСЧЕТА. В ДАННОМ СЛУЧАЕТ ОБРАТНЫЙ ОТСЧЕТ НАЧНЕТСЯ С 9999 { delay(1000); Serial.print("NOW IS "); Serial.println(disp,1); } if (disp < 10) // если наша цифра меньше 10, то { Razryad(3); Segment(11); // пишем в первый разряд прочерк Razryad(0); Segment(11); // пишем во второй разряд прочерк Razryad(1); Segment(11); // пишем в третий разряд прочерк Razryad(2); Segment(disp); // пишем в четвертый разряд нашу цифру } else if (disp < 100) // если наша цифра меньше 100, то { Razryad(3); Segment(11); // пишем в первый разряд прочерк Razryad(0); Segment(11); // пишем во второй разряд прочерк Razryad(1); Segment(disp / 10); // пишем в третий разряд - цифру делёную на 10 Razryad(2); Segment(disp % 10); // пишем в четвертый разряд цифру оставшуюся от деления на 10 /* Допустим наша цифра 25. Если мы ее поделим на 10, то у нас получится 2,5. Цифры после запятой, в данном случае, у нас не остаются. Таким образом мы имеем в третем разряде цифру 2. В чевертый разряд мы, как раз и записываем цифру-остаток полученную в результате деления. В нашем случае это и есть та самая 5. Аналогичным образом разбивается наша цифра и далее. */ } else if (disp < 1000) { Razryad(3); Segment(11); Razryad(0); Segment(disp / 100); Razryad(1); Segment((disp % 100) / 10); Razryad(2); Segment(disp % 10); } else { Razryad(3); Segment(disp / 1000); Razryad(0); Segment((disp % 1000) / 100); Razryad(1); Segment((disp % 100) / 10); Razryad(2); Segment(disp % 10); } } Вот попробуй. Сейчас программа должна вычитать каждую секунду по единице из числа 9999. Если нужно поменять начальное значение, то в void loop в переменной disp меняешь значение. Если получится это транслировать на индикатор, то дальше сам подумай,как сделать именно часы, если нет, то я уже бессилен и смогу разобраться тогда,когда у меня будет 4-х разрядный индикатор.