Zaslal: st listopad 19 2014, 13:27 Předmět: "Rozsekání" čísla po desítkách
Ahoj, potřeboval bych rozsekat číslo po desítkách (na čtyřcifernou sedmisegmentovku), jak to udělat?
Řešení s dělením mi vždycky nějak selhalo,
Počítání od 0 do 9 podle pulzů mi funguje dobře, rozšíření je problém.
Jinak používám Atmega8, TIMER2 (Nejsou v něm snad žádné záludnosti narozdíl od TIMER0??)
Napadlo mě i klasitké řešení vytvořit si proměnnou pro jednotky, desítky, stovky....ale vzhledem k tomu, že potřebuju jedním signálem přičítat a druhým odečítat (čísla, ne jedničky), tak to nepřichází v úvahu.
Založen: Feb 14, 2005 Příspěvky: 9006 Bydliště: Brno (JN89GF)
Zaslal: st listopad 19 2014, 14:34 Předmět:
Já v assembleru vždycky pracuju se samostatnýma proměnnýma pro stovky, desítky, jednotky... když jde o zobrazování na display. Algoritmus mám, že nejdřív odečítám nejvyšší řád, třeba stovky a počítám, kolikrát odečtu, než je výsledek zápornej, pak ten poslední odečet vrátím a odečítám nižší řád, atd...
Původní číslo ale mám samozřejmě uložený ve zvláštní proměnné, abych s ním kdyžtak mohl dělat běžný operace. Ten rozklad je jen kvůli zobrazování.
Nevim co presne si predstavujes pod pojmem rozsekat na desitky, ale pokud jde o prevod do BCD, deleni by melo fungovat. Pricitej a odecitej si cisla jak chces, ale to co se ma zobrazit preved na BCD. Vydel cislo k zobrazeni 1000 -dostanes tak tisicovky a ty posli na displej, celociselny zbytek vydel 100 (stovky), pak 10 a nakonec ti zbudou jednotky.
Nevim co presne si predstavujes pod pojmem rozsekat na desitky, ale pokud jde o prevod do BCD, deleni by melo fungovat. Pricitej a odecitej si cisla jak chces, ale to co se ma zobrazit preved na BCD. Vydel cislo k zobrazeni 1000 -dostanes tak tisicovky a ty posli na displej, celociselny zbytek vydel 100 (stovky), pak 10 a nakonec ti zbudou jednotky.
Možná í dotaz: Ale vždycky to počítá celočíselně? není v tom nějaká zrada? nebo existuje fce pro zaokrouhlení na jednotky?
case 4:
if ((!(PINB&0b00001000))==0){
cislo=cislo+5;
}
else{
T1=0;
}
break;
case 8:
T1=0;
break;
}
//////////////////////////////////////////////////////////////////////////
// ODECITANI PULZU -(PB2)
//////////////////////////////////////////////////////////////////////////
switch (T2)//kazdejch 19,2s scannuje pulz
{
case 1:
if ((!(PINB&0b00000100))==1){
T2=0;
}
break;
case 2:
if ((!(PINB&0b00000100))==0){ //pokud prisel pulz if ((!(PINB&0b00000100))==0)
cislo--;
}
else { //pokud tady neni pulz, tak neceka do konce, ale jde na zacatek cekani
T2=0;
}
break;
case 3:
T2=0;
break;
}
}
//////////////////////////////////////////////////////////////////////////
// TIMER 2
//////////////////////////////////////////////////////////////////////////
ISR (TIMER2_OVF_vect)
{
TCNT0 = 205; //preruseni po 12,8ms
T3++;
switch (T3)
{
case 1:
PORTC|= (0 << PC2); PORTC|= (1 << PC5);//PC5 -ANODA TISICE
if (cislo>=1000){
cislice=cislo/1000;
cislo=cislo-(cislice*1000);
}
else{
cislice=10; //zobrazi se -
}
break;
case 2:
PORTC|= (0 << PC5);PORTC|= (1 << PC4);//PC4 -ANODA STOVKY
if (cislo>=100){
cislice=cislo/100;
cislo=cislo-(cislice*100);
}
else{
cislice=10; //zobrazi se -
}
break;
case 3:
cislice=cislo/100;
PORTC|= (0 << PC4);PORTC|= (1 << PC3);//PC3 -ANODA DESITKY
if (cislo>=10){
cislice=cislo/10;
cislo=cislo-(cislice*10);
}
else{
cislice=10; //zobrazi se -
}
break;
case 4:
PORTC|= (0 << PC3);PORTC|= (1 << PC2); //PC2 -ANODA JEDNOTKY
cislice=cislo;
T3=0;//vymaze casovaci promennou
break;
}
ukazC(cislice);
}
//////////////////////////////////////////////////////////////////////////
// ZOBRAZOVANI CISEL
//////////////////////////////////////////////////////////////////////////
void ukazC (char cislice)
{
switch (cislice)
{
case 0: PORTD = 0b11000000; break;
case 1: PORTD = 0b11111001; break;
case 2: PORTD = 0b10100100; break;
case 3: PORTD = 0b10110000; break;
case 4: PORTD = 0b10011001; break;
case 5: PORTD = 0b10010010; break;
case 6: PORTD = 0b10000010; break;
case 7: PORTD = 0b11011000; break;
case 8: PORTD = 0b10000000; break;
case 9: PORTD = 0b10010000; break;
default: PORTD = 0b10111111; break; //prostredni vodorovna cara
//0b01111111, //tecka
//0b11111111 //nic
}
}
//////////////////////////////////////////////////////////////////////////
// HLAVNI FUNKCE
//////////////////////////////////////////////////////////////////////////
int main (void)
{
DDRB=0b00110010; //1=vystup, 0=vstup ///F7=>preklad programu
DDRC=0b00111100; //C2-C5 jsou spolecny anody
DDRD=0xff; //sedmisegment-vse vystupy
//PORTB|= (1 << PB1); //zapnuti proudu nafurt
PORTD = 0b11111111;
while(1)
{
TCCR0 |= (1 << CS02) | (1 << CS00); // preddelicka /1024 //TCCR0 = 0b00000101;TIMSK = 0b00000011;
TIMSK|= (1 << TOIE0);// prerušenie pri pretečení TCNT0
Založen: Sep 19, 2007 Příspěvky: 3698 Bydliště: Praha
Zaslal: st listopad 19 2014, 20:46 Předmět:
Vážně ... to vám takhle asi nikdo neřekne. To je pro ATMega 8? Blbě se ladí, nemá debug režim. Zkuste najít chybu krokováním programu v simulátoru a kontrolou dat a výstupů. Pokud máte skutečný HW debugger (Dragon, JTAG ICE apod. a to pro važnější práci fakt doporučuju), tak bych to odladil pro ATMega 88, která má DebugWire a pak odladěné portoval na ATMega 8.
Založen: Oct 30, 2010 Příspěvky: 6645 Bydliště: Praha
Zaslal: st listopad 19 2014, 21:44 Předmět:
Asi tak, dělat něco dnes na MCU bez debugu si nějak radši ani nechci představovat. Když si vzpomenu na doby, kdy jsem kódoval v ASM 51čku a to naštěstí již flashový paralelně programovaný klon od Atmelu a bylo to pořád programátor - patice v zařízení, přičemž vrcholem ladění bylo někam přidat rozsvícení ledky, no nechybí mi to Oblíbil jsem si Cypress PSOC, řada 4 je narozdíl od 5 i za velmi přijatelné peníze a s osmibity zcela nesrovnatelná.
Založen: Sep 13, 2005 Příspěvky: 867 Bydliště: Praha
Zaslal: st listopad 19 2014, 22:22 Předmět:
Ten program je bohuzel asi hodne spatny... Jednak se mi zda, ze tam vidim nekolik "race condition"... Operace, ktere maji byt atomicke atomicke nejsou, cislo se rozpocitava na digity rozlozene v case, do toho to rozebirane "cislo" muze menit to druhe preruseni... tohle spatne odhaluje i pri krokovani....
Tohle predpokladam, ze je preklep a ma byt TCNT2:
TCNT0 = 205; //preruseni po 12,8ms
Takhle tou operaci OR opravdu puvodne nahozenou anodu neodbudis...
PORTC|= (0 << PC3);PORTC|= (1 << PC2); //PC2 -ANODA JEDNOTKY
PORTC|= (0 << PC3); oprav na PORTC&= ~(1 << PC3);
a vsechno dalsi taky...
Takhle reseny program je zrejme velke sousto....
Ono i ty intervaly by to chtelo resit zpusobem, kdy se o to clovek nemusi starat a nastavovat TCNTx na neco v ISR, protoze se tim zanasi systematicka odchylka.... _________________ de omnibus dubitandum est
Ten kod ma, obavam se, zasadni koncepcni vady... no uvidis...
A vkladej sem ten zdrojak jako "code", at to neni tak necitelna hruza...
DÍKY MOC ZA TEN TCNT2 !!
To jsem úplně přehlídl, fakt mi to pomohlo!!
Už mi to funguje,
Pokud se ti chce, tak mi prosím (třeba i v bodech) napiš, co se ti na tom koncepčně nezdá...
Jsem začátečník a rád se přiučím
Založen: Sep 13, 2005 Příspěvky: 867 Bydliště: Praha
Zaslal: čt listopad 20 2014, 0:32 Předmět:
Uz jsem to psal nahor, zas ale ten zdrojak nechi prolejzat do detailu, takze pokud to mas ostreno, napis jak...
Napr. ten multiplex mas rizeny prerusenim a soucasne s kazdym digitem pocitas, co zobrazit a upravujes pri tom hodnotu promenne "cislo", behem te doby ale "cislo" obsahuje nejaky mezivysledek pro zobrazovani, ovsem TIM0, se zda, ze ti ho muze kdykoliv zmenit - ten mezivysledek.... Proste, kdyz nejakou promennou zpracovavas (a tady "cislo" zpracovavas vlastne po celou dobu multiplexu, vyjma jeho navratu na prvni digit), musis mit zajisteno, ze ti do ni nikdo jiny nesahne (TIM 0 ISR) a opacne nesmis (TIM2 ISR) ji menit nekomu, kdo s ni pracuje (TIM0 ISR)... pomohou tomu pomocne promenne a atomicke predavani hodnot (tj. rekneme "neprerusitelne").
Moc nevim, jak to muze fungovat (ale mohl jsem v tom neco prehlednout), protoze ten zobrazovaci multiplex ti vzdycky znici obsah "cislo"...
Taky nechapu, proc jsou v mainu uvnitr while(1) ty incicializace timeru a to povoleni preruseni.... _________________ de omnibus dubitandum est
Nemůžete odesílat nové téma do tohoto fóra. Nemůžete odpovídat na témata v tomto fóru. Nemůžete upravovat své příspěvky v tomto fóru. Nemůžete mazat své příspěvky v tomto fóru. Nemůžete hlasovat v tomto fóru. Nemůžete připojovat soubory k příspěvkům Můžete stahovat a prohlížet přiložené soubory
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.