//Jan Sosin
//Mikroprocesory i systemy wbudowane - Test 4
//W projekcie nie wykorzystałem żadnych dodatkowych bibliotek,
//ani zewnętrznego zegara czasu rzeczywistego, ponieważ nie
//wiedziałem czy ich użycie jest dozwolone.
//Opis działania
/*
Pojedyncza cyfra wyświetlacza 7-segmentowego wymaga 8 połączeń do działania.
Gdybyśmy chcieli podłączyć 4 takie cyfry oddzielnie, potrzebowalibyśmy aż 64 połączeń.
Dlatego praktycznie wszystkie urządzenia wykorzystują sztuczkę polegającą na
zapalaniu tylko jednej cyfry jednocześnie. Wyświetlana cyfra jest zmieniana na tyle
szybko, że tworzy wrażenie jakby wszystkie cyfry były zapalone.
Wielocyfrowe wyświetlacze są zbudowane tak, że każda cyfra ma własną połączoną
anodę (żadziej katodę). Odpowiednio ustawiając wyjścia dla poszczególnych
anod i katod w stan przeciwny, możemy kontrolować która cyfra będzie wyświetlana.
Mikrokontroler zastosowany w Arduino UNO, ma wbudowane układy czasowe.
Standardowa biblioteka arduino udostepnia ich odzczyt funkcjami micros() i millis().
Na ich podstawie można mierzyć upływ czasu.
Gdybyśmy chcieli wykonać projekt w rzeczywistości, należałoby dodać rezystory
między katodami wyświetlacza a płytką arduino, aby ograniczyć płynący prąd.
W przeciwnym razie może dojść do uszkodzenia wyjść.
Tutaj zrezygnowałem z nich, aby nie zaciemniać schematu i nie spowalniać symulacji.
*/
//Wykorzystane piny:
//Anody
const int dig1 = 2;
const int dig2 = 3;
const int dig3 = 4;
const int dig4 = 5;
//Katody
const int segA = 6;
const int segB = 7;
const int segC = 8;
const int segD = 9;
const int segE = 10;
const int segF = 11;
const int segG = 12;
const int segCL = 13;
//Przyciski
const int sw1 = A0;
const int sw2 = A1;
//interwał przełączania cyfr
const int brightness = 500;
//pola dla poszczegółnych cyfr
const int numbers[][7] =
{
{0,0,0,0,0,0,1}, //0
{1,0,0,1,1,1,1}, //1
{0,0,1,0,0,1,0}, //2
{0,0,0,0,1,1,0}, //3
{1,0,0,1,1,0,0}, //4
{0,1,0,0,1,0,0}, //5
{0,1,0,0,0,0,0}, //6
{0,0,0,1,1,1,1}, //7
{0,0,0,0,0,0,0}, //8
{0,0,0,0,1,0,0}, //9
{1,1,1,1,1,1,1} //pusty
};
//zmienne zegara
const unsigned long SEKUNDA = 1000000UL;
unsigned long microsLast = 0UL;
byte hh = 0, mi = 0, ss = 0;
//ustawia wyjscia dla konkretnej cyfry
void cyfra(int digit)
{
for(int i=0; i<7; i++)
{
digitalWrite(segA+i, numbers[digit][i]);
}
}
//wyłącza wyjscia dla konkretnej cyfry
void czysc()
{
for(int i=0; i<7; i++)
{
digitalWrite(segA+i, 1);
}
}
void setup() {
//Tryb działania pinów (wejście-wyjście)
//W tym wypadku wszystkie piny kontrolujące wyświetlacz
//są używane jako wyjścia
pinMode(segA, OUTPUT);
pinMode(segB, OUTPUT);
pinMode(segC, OUTPUT);
pinMode(segD, OUTPUT);
pinMode(segE, OUTPUT);
pinMode(segF, OUTPUT);
pinMode(segG, OUTPUT);
pinMode(segCL, OUTPUT);
pinMode(dig1, OUTPUT);
pinMode(dig2, OUTPUT);
pinMode(dig3, OUTPUT);
pinMode(dig4, OUTPUT);
//Przyciski
//aby ograniczyć ilość dyskretnych elementów
//używam wbudowanych rezystorów pull_up
pinMode(sw1, INPUT_PULLUP);
pinMode(sw2, INPUT_PULLUP);
}
void loop() {
//Zegar
//Korzystamy tylko ze zmiennych typu unsigned.
//Ponieważ obliczamy ich różnicę,
//obliczenia będą działać prawidłowo nawet gdy
//wystąpi przepełnenie "micros()".
if ((micros() - microsLast) >= SEKUNDA) {
//Kolejna sekunda
microsLast += SEKUNDA;
ss++;
if (ss >= 60) {
ss -= 60;
mi++;
}
if (mi >= 60) {
mi -= 60;
hh++;
}
if (hh >= 24) {
hh -= 24;
}
}
/////////////////////////////////////////////////////
//Pojedyncze cyfry do wyświetlenia
byte d1 = hh/10;
byte d2 = hh%10;
byte d3 = mi/10;
byte d4 = mi%10;
//Miganie dwukropka
if(ss%2)
{
digitalWrite(segCL, LOW);
}
else
{
digitalWrite(segCL, HIGH);
}
//Przyciski
bool buttonH = digitalRead(A0);
bool buttonM = digitalRead(A1);
//Cyfry na wyświetlaczu
digitalWrite(dig1, HIGH);
cyfra(d1);
delayMicroseconds(brightness);
czysc();
digitalWrite(dig1, LOW);
digitalWrite(dig2, HIGH);
cyfra(d2);
delayMicroseconds(brightness);
czysc();
digitalWrite(dig2, LOW);
digitalWrite(dig3, HIGH);
cyfra(d3);
delayMicroseconds(brightness);
czysc();
digitalWrite(dig3, LOW);
digitalWrite(dig4, HIGH);
cyfra(d4);
delayMicroseconds(brightness);
czysc();
digitalWrite(dig4, LOW);
delayMicroseconds(5000);
//Sprawdzamy później, aby zminimalizować drgania przycisku
//Nastawianie zegara
if(digitalRead(A0)==0 && buttonH==1)
{
hh++;
delayMicroseconds(2000); //drgania
}
if(digitalRead(A1)==0 && buttonM==1)
{
mi++;
delayMicroseconds(2000);
}
}
Minuty
Godziny