7-segmentový displej na futbal: Rozdiel medzi revíziami
Zo stránky SensorWiki
Riadok 35: | Riadok 35: | ||
<tabs> | <tabs> | ||
<tab name="SemProj"><source lang="c++" style="background: LightYellow;"> | <tab name="SemProj"><source lang="c++" style="background: LightYellow;"> | ||
// Required libraries | // Required libraries | ||
#include <avr/io.h> | #include <avr/io.h> | ||
#include <util/delay.h> | #include <util/delay.h> | ||
#include <avr/interrupt.h> | #include <avr/interrupt.h> | ||
#define CLK PD5 // CLK -> pin 5 | |||
#define DIO PD4 // DIO -> pin 4 | |||
Riadok 49: | Riadok 47: | ||
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) | #define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) | ||
#define LEFT_START_STOP_PIN PD2 // | #define LEFT_START_STOP_PIN PD2 // Button for the left team | ||
#define RIGHT_START_STOP_PIN PD3 // | #define RIGHT_START_STOP_PIN PD3 // Button for the right team | ||
#define RESTART_PIN PD6 // | #define RESTART_PIN PD6 // Button for the right team | ||
volatile uint8_t count_left = 0; // Counter for the left displays | volatile uint8_t count_left = 0; // Counter for the left displays | ||
Riadok 287: | Riadok 115: | ||
sei(); // Enable interrupts | sei(); // Enable interrupts | ||
while (1) { | while (1) { |
Verzia z 12:53, 6. máj 2024
Záverečný projekt predmetu MIPS / LS2024 - Daniel Žula
Zadanie
Pripojenie 7 - segmentového LED displeja k vývojovej doske, vytvorenie potrebných knižníc a funkcií. Cieľom je, aby sme dokázali zobraziť skóre futbalového zápasu, ktoré dokážeme meniť podľa potreby pomocou tlačidiel.
Literatúra:
Analýza a opis riešenia
Princíp fungovania bol jednoduchý, ak stlačíme tlačidlo príslušné k prvému tímu, meníme skóre prvého tímu a ak stlačíme tlačidlo príslušné k druhému tímu, meníme skóre druhého tímu. Takisto máme tlačidlo RESET, ktoré celé skóre resetuje. Na správne fungovanie sme si vytvorili knižnicu, v ktorej sme zadefinovali čísla od 0-9 pomocou zapnutých a vypnutých segmentov na 7 segmentovke.
Algoritmus a program
Tento program sme vytvorili na ovládanie 7 segmentového displeja pomocou tlačidiel a následného zobrazovania futbalového skóre pomocou tlačidiel. Najprv sme si vytvorili knižnicu do ktorej sme uložili čísla od 0-9 na zobrazenie čísiel pomocou svietiacich a zhasnutých segmentov. Následne sme si vytvorili funkcie na zapnutie a vypnutie komunikácie.
Potom sme si vytvorili funkcie na inicializáciu, nastavenie segmentov a ich následné zobrazenie. Nakoniec sme pre INT0 a INT1 spravili funkcie, jedna pre ľavú stranu a druhá pre pravú stranu, v ktorých po stlačení tlačidla nastalo zvýšenie hodnoty o 1, kde ak sme dosiahli číslo 99 a zvýšili sme ho, číslo sa nám resetovalo naspäť na 0, keďže na číselné hodnoty sme mali iba 2 7 - segmentové displeje. Keď sme mali všetky tieto funkcie zadefinované, v hlavnej časti programu sme CLK aj DIO nastavili opäť ako input, povolili sme INT0 a INT1 takisto sei().
Následne vo while funkcii sme už len dané čísla, ktoré boli uložené v counter_left a counter_right zobrazovali pomocou našej funkcie pre zobrazenie čísla na 7 segmentovke, kde sme pozíciu čísel nastavili na pravú 7 segmentovku z dvojice (čiže celkovo 2. a 4. 7 segmentovka) a po zvýšení čísla na 10 a viac sa začali využívať obe 7 segmentové displeje pre daný tím. Po stlačení tlačidla RESET sa hodnoty v counter_left a counter_right vynulovali a opäť sa využívali iba pravé 7 segmentovky z dvojice. Takto to funguje donekonečna.
// Required libraries
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define CLK PD5 // CLK -> pin 5
#define DIO PD4 // DIO -> pin 4
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define LEFT_START_STOP_PIN PD2 // Button for the left team
#define RIGHT_START_STOP_PIN PD3 // Button for the right team
#define RESTART_PIN PD6 // Button for the right team
volatile uint8_t count_left = 0; // Counter for the left displays
volatile uint8_t count_right = 0; // Counter for the right displays
// External interrupt 0 (button for the left team)
ISR (INT0_vect)
{
_delay_ms(10);
if(bit_is_clear(PIND, LEFT_START_STOP_PIN)){
// Increase left count and reset if it reaches 100
count_left++;
if (count_left >= 100) count_left = 0;
}
_delay_ms(150);
}
// External interrupt 1 (button for the right team)
ISR (INT1_vect)
{
_delay_ms(10);
if(bit_is_clear(PIND, RIGHT_START_STOP_PIN)){
// Increase right count and reset if it reaches 100
count_right++;
if (count_right >= 100) count_right = 0;
}
_delay_ms(150);
}
int main(void){
clear_bit(DDRD, CLK); // Set CLK as input
set_bit(PORTD, CLK); // CLK as input pull-up on
clear_bit(DDRD, DIO); // Set DIO as input
set_bit(PORTD, DIO); // DIO as input pull-up o
clear_bit(DDRD, LEFT_START_STOP_PIN); // Set LEFT_START_STOP_PIN as input
set_bit(PORTD, LEFT_START_STOP_PIN); // LEFT_START_STOP_PIN as input pull-up on
clear_bit(DDRD, RIGHT_START_STOP_PIN); // Set RIGHT_START_STOP_PIN as input
set_bit(PORTD, RIGHT_START_STOP_PIN); // RIGHT_START_STOP_PIN as input pull-up on
clear_bit(DDRD, RESTART_PIN); // set RESET_PIN as input
set_bit(PORTD, RESTART_PIN); // RESET_PIN as input pull-up on
uint8_t data[] = { 0, 0, 0, 0 };
set_segments(data, 4, 0);
EIMSK = 0b00000011; // Enable INT0, INT1
EICRA = 0b00001010; // Detect falling edge on both pins
sei(); // Enable interrupts
while (1) {
if (bit_is_clear(PIND, RESTART_PIN)) {
// Perform reset operation
count_left = 0; // Reset the left count
count_right = 0; // Reset the right count
}
// Display left count on left two displays and right count on right two displays
display_number_segment(count_right, 0, 2, 2);
display_number_segment(count_left, 0, 2, 0);
}
return 0;
}
}
Zdrojový kód: zdrojaky.zip
Overenie
Na zobrazovanie aktuálneho skóre používame dve tlačidlá, jedným, ktorý je vľavo meníme skóre tímu vľavo, a druhým, ktorý je v strede meníme skóre tímu ktorý je napravo, posledným tlačidlom ktoré je vpravo skóre resetujeme.
Video: