Ahoj všem, mám drobný problém. Realizui program pro průtokoměr se zobrazením průtoku na LCD, čerpadlo posílá pulzy na INT0 kde je snímám procesorem, a po době 1s bych je chtěl vypsat na LCD, na to bych chtěl použít časovač mikroprocesoru. Aktuálně mi funguje čítání impulzů a jejich zobrazení na LCD, jakmile sem ale přidal časovač, tak to přestalo jet a chová se to divně, display bliká a údaje se nezobrazují. Posílám můj program, je tam i spousta věcí pro testy a další balast, jak sem nevěděl co s tím.
A taky bych pridal nejakou podminku at se ten display prepise, jenom kdyz se zmeni hodnota. Nebo kdyz prijde to 1s preruseni. A nezapomen na to, ze kdyz pouzivas promennou v preruseni je nutno pred ni pridat volatile, jinak to prekladac vyhodi.
Takze
volatile int pocet_pulzu; // pomocne promene
volatiole uint16_t i=0, j=0, pocet_pulzu_pomocna; // promena typu 16 bit integer
char pom[6], pom1[6];
Díky za reakci, až to budu v tejdnu předělávat, doplním to. Tenhle program byl zatím jenom test jestli to vůbec rozjedu, potom to teprve budu upravovat ať to za něco stojí To s tou proměnou v přerušení jsem ale nevěděl, děkuju za radu.
Tak posledni 4 prispevky jsou pro mne spanelska vesnice, prakticky nerozumim ani slovo
Atomicka uroven strojoveho kodu?
Kopie atomicke urovne strojoveho kodu?
Když nápíšeš operaci v C například inkrementaci proměné int32 tak na 8bit mcu jako je AVR se provede jako několik asm instrukcí, to znamená že ta operace není atomická. Takže pokud používáš takovou proměnou někde v kódu a její inkrementaci provádíš například v přerušení, musíš ji zamykat. Pokud ti apriory jde o to aby zamčení nezpůsobilo zablokování inkrementace (nechceš ztratit informaci) tak výsledek operace kopíruješ do proměné a ta se teprve zamyká a používá v kódu mimo přerušení.
NO taky z toho nejsem moudrej, ale komplet jsem to rozchodil, jestli budte chtít někdo, až to nějak doládím, tak sem kód dám
Ještě bych poprosil o příklad zamykání, jak to vypadá . V asm bych to věděl, ale v GCC nevim, jestli se to dělá stejně nebo jak.
Zavedeš si pomocnou proměnou, v ní je 0 nebo 1 (odemceno/zamceno) V přerušení kde s uzamykatelnou proměnou pracuješ, tuhle pomocnou proměnou testuješ a zachováš se podle toho. V ASM je to stejný jako v C.
Ještě jeden dotaz, jak se nejlépe zobrazí nějaké číslo s desetinami na LCD, je mi jasné že rozdělit na jednotky, desítky a stovky, už jsem to i vytvořil a funguje to, hledám ale nějaký elegantnější způsob, moje řešení je nějaký kostrbatý, moc se mi nelíbí.
d= pocet_pulzu_pomocna/5.5;
[/code]Nemůžeš takto míchat celé a desetinné čísla. (Výslede bude pocet_pulzu_pomocna/5).
Stačí rozšířit zlomek:
[code]
d= pocet_pulzu_pomocna * 10 / 55;
[/code]
a hned je to lepší.
Výpočet s pevnou desetinnou čárkou (bez typu float):
Pokud chceš počítat na jedno desetinné místo, použij 10x větší hodnotu.
Výsledek bude 10x větší a ve funkci sprintf() ho upravíme.
Aby proměnná po vynásobení nepřetekla, použijeme větší typ (uint32_t).
[code]char display_string[8];
uint32_t pocet_pulsu;
uint32_t prutok_d(void)
{
return (pocet_pulsu * 100 / 55); // místo "pocet_pulsu * 10 / 55"
}
int main(void)
{
while(1)
{
sprintf(display_string, "%lu.%lu", prutok_d() / 10, prutok_d() % 10);
Podobně pro počítání na 2 des. místa vynásobíme stem atd.
Nepoužívej pro proměnnou malé L, protože se plete s jedničkou.
Vůbec proměnné jako a, b, k dělají kód nepřehledný.
Vyplatí se trocha duševní námahy pro zvolení popisných jmen.