Ahoj, prosím Vás mohl by mi někdo pomoct? Dostala jsem za úkol napsat program ale o programování v podstatě vůbec nic nevím. Pomůžete?
Zadání:
Na bránu B připojte přípravek LED, na bránu D připojte přípravek s tlačítky. Stiskem tlačítka S0 až S2 měňte stav LED. Tlačítko S0 nuluje všechny LED. Tlačítko S1 zvýší číslo zobrazené pomocí LED o 1. Tlačítko S2 sníží číslo zobrazené pomocí LED o 1. programově ošetřete zákmity.
Fórum › C / C++
Tlačítka
No já si nejsem jistý, jestli toto spadá pod tuto kategorii fóra.. Spíš bych to viděl na VHDL a hradlová pole (podle zadání).. Ale může to být i něco jiného.. V prve řadě bych se podíval, z jakého předmětu to je.. Toto na C#/C++ opravdu nevypadá..
To bude na nějakým AVR?
hu
V C/C++ to asi bude, ale musíš nám napsat, na čem to poběží. Vypadá to na nějaký jednočip, asi AVR.
hu
ATTiny2313 - to je co jsem chtěl vědět. Typ procesoru je dán, jeho dokumentaci není problém najít. Stačí napsat ATTiny 2313 datasheet do google. Na tuto úlohu je potřeba pracovat s porty. To je popsáno v kapitole která by se mohla jmenovat "Using ports as GPIOs" nebo nějak podobně. Porty, na kterých jsou tlačítka, nastavíš jako vstupy s "internal pull up" a porty s ledkama jako výstupy. Pak potřebuješ nějakou proměnnou ve které budeš uchovávat číslo "namačkané" tlačítky. S0 tuto proměnnou nuluje, S1 k ní přičte 1, S2 od ní odečte 1. Nejtěžší je softwarově odstranit zákmity tlačítka. To je možné udělat tak, že "připojíš" ke kontaktu tlačítka "softwarový kondenzátor" - na to použiješ proměnnou. Stačí pravidelně testovat stav tlačítka. Když je kontakt sepnutý, "nabíjíš kondenzátor" - přičteš 1, když je kontakt rozepnutý, "vybíjíš kondenzátor" - odečteš 1. Když je hodnota v proměnné menší než nějaká hodnota (např. 1/3 rozsahu), je kontakt rozepnutý, když je větší než nějaká hodnota (např 2/3 rozsahu), je sepnutý. Obě meze pak vytvoří hysterezi.
hu
Ještě pozn.: má to být C++, takže se dá na to jít objektově. Napíšeš si třídu pro tlačítko s parametrickým konstruktorem (parametr bude pin na kterém je tlačítko připojeno) s veřejnou metodou třeba CtiStav(), která vrátí stav tlačítka a metodou Vzorkuj(), která otestuje příslušný port. Třída bude řešit zákmity tlačítka. Pak pro každé tlačítko vytvoříš samostatnou instanci třídy.
hu
Nevíte prosím, co je tam za chybu?
#include <avr/io.h> //
#define F_CPU 20000000UL //definice frekvence 20MHz
#include <util/delay.h> //knihovna přerušení
#define bit_is_set (PIND,PD0) (ADRESS |= (1 << BIT))
#define bit_is_clear (PIND,PD0) (ADRESS &= ~(1 << BIT))
unsigned char cislo;
int main(void)
{
DDRB=0xff; //brána B je výstupní
PORTB=0xff; //počáteční stav na bráně
DDRD=0x00; //brána D je vstupní
PORTD=0xff; //na bráně D je aktivován Pull-up
cislo=15; //počáteční stav čísla
while(1)
{
if (bit_is_clear(PIND,PD0))
{
_delay_ms(20);
if (bit_is_set(PIND,PD0)) break; //ošetření vůči zákmitům
cislo=15; //nulujeme proměnnou cislo
_delay_ms(200);
}
if (bit_is_clear(PIND,PD1))
{
_delay_ms(20);
if (bit_is_set(PIND,PD1)) break; //ošetření vůči zákmitům
if(cislo<255)cislo++;//jestliže je cislo menší jak 255 pak je inkrementujeme
_delay_ms(200);
}
if (bit_is_clear(PIND,PD2))
{
_delay_ms(20);
if (bit_is_set(PIND,PD2)) break; //ošetření vůči zákmitům
if(cislo>15 )cislo--;//jestliže je cislo větší jak 0 pak je dekrementujeme
_delay_ms(200);
}
PORTB=cislo; //hodnotu proměnné cislo přiřadíme PORTU B
}
}
podle me je vetsina problemu kolem tech maker:
#define bit_is_set (PIND,PD0) (ADRESS |= (1 << BIT))
#define bit_is_clear (PIND,PD0) (ADRESS &= ~(1 << BIT))
proste jsou uplne zpraseny... mezera za nazvem makra a zavorkama vesmes znamena, ze se bit_is_set nahradi za to co je vse za nim, misto aby se to bralo jako "pseudo funkce"... a taky by tam melo byt spis:
bit_is_set(ADDRESS,BIT) ((ADRESS) |= _BV(BIT))
kromě maker je zmaštěná detekce tlačítek. Musíš odstranit zákmity tlačítka a na vyčištěném signálu detekovat jeho změnu pokud má reagovat jen jednou na stisk tlačítka. Program bych si udělal "od zadu" od nejjednodušších akcí. Začneme inkrementací, dekrementací a nulováním na portu:
void nuluj()
{
PORTB = 0;
}
void plus()
{
PORTB++;
}
void minus()
{
PORTB--
}
hu
Detekce změny stavu tlačítka je sekvenční logika - výsledek vyhodnocení záleží na současném stavu a na stavu, který předcházel. Jestliže si stisknuté tlačítko označím hodnotou true a nestisknuté false pak mám celkem 4 stavy:
1. předešlý a současný stav jsou false - tlačítko v klidu nestisknuté
2. předešlý stav false, současný stav true - tlačítko někdo stisknul, změna stavu
3. předešlý stav true, současný stavtru - tlačítko v klidu stisknuté
4. předešlý stav true, současný stav false - tlačítko někdo uvolnil, změna stavu
Program tedy provede požadovanou akci při zjištění stavu 2. tlačítka. To budu zjišťovat tak, že budu v pravidelně (v hlavní smyčce programu) porovnávat současný a předešlý stav. Vše kolem tlačítek je možné napsat jako třídu, její metoda by mohla vypadat takto (jen nástřel):
int tlacitko::stisk()
{
if (!predesly_stav && soucasny_stav)
{
return 1; //probehlo stisknuti
}
return 0;
}
predesly_stav a soucasny_stav jsou atributy třídy tlacitko, eviduji jeho stav. Při stisknutí tlačítka metoda vrátí 1, při ustáleném stavu nebo uvolnění vrátí 0.
hu
Zákmity tlačítek odstraním např. tak jak bylo popsáno výše. Opět jako metodu třídy - ukázka samotného filtrování, bez načítání stavu příslušného portu:
void tlacitko::filtr()
{
if (vstup) //vstup je primo nacten z portu (staci vhodne maskovat PIN)
{
if (kond < MAX) //MAX je pocet vzorku, jeho hodnotu definuj napr v hlavickovem souboru
{
kond++;
}
}
else
{
if (kond > 0)
{
kond--;
}
}
if (kond == MAX)
{
soucasny_stav = 1;
}
else
{
soucasny_stav = 0;
}
return;
}
hu
Skoro hotový kód v C++.
/*
TlacitkoClass.h
*/
#include <avr/io.h>
#define MAX 100 //pocet vzorku vstupu pri fltraci tlacitek
class tlacitko {
public:
int8_t soucasny_stav, predesly_stav, kond, maska;
tlacitko(int8_t pin);
void filtr();
int stisk();
};
/*
* TlacitkoClass.cpp
*
*/
#include "TlacitkoClass.h"
//********************************************************
tlacitko::tlacitko(int8_t pin)
{
maska = 1 << pin; //vytvori bitovou masku
kond = 0;
predesly_stav = 0;
soucasny_stav = 0;
//DDRD je defaultne 0x00, vsechny bity jako vstup
}
//********************************************************
int tlacitko::stisk()
{
if (!predesly_stav && soucasny_stav)
{
return 1; //probehlo stisknuti
}
return 0;
}
//********************************************************
void tlacitko::filtr()
{
if ((~PIND) & maska) //vstup je primo nacten z portu, pri stisknutem tlac. Low na prislusnem pinu
{
if (kond < MAX)
{
kond++;
}
}
else
{
if (kond > 0)
{
kond--;
}
}
if (kond == MAX)
{
soucasny_stav = 1;
}
else
{
soucasny_stav = 0;
}
return;
}
/*
* AVRGCC2.cpp
*
*/
#include "TlacitkoClass.h."
tlacitko plus(PIND1);
tlacitko minus(PIND2);
tlacitko nuluj(PIND0);
int main(void)
{
DDRB = 0xFF;
while(1)
{
plus.filtr();
minus.filtr();
nuluj.filtr();
if (plus.stisk())
{
PORTB++;
}
if (minus.stisk())
{
PORTB--;
}
if (nuluj.stisk())
{
PORTB = 0;
}
//nejaky cekani ktere urci vzorkovaci frekvenci
}
}
hu
Chybička se vloudila. Zkus ji najít (to není výzva pro KIIV ).
hu
Mi bereš poslední iluze, že v životě už programování neuvidí ani z dálky
hu
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Tlacitka — založil dragon124
Obrázek na tlačítka — založil Honzík
CSS tlačítka — založil cheeester
Menu tlačítka — založil hindour
Actionscript a tlačítka — založil dragon124
Moderátoři diskuze