Vítejte na Elektro Bastlírn?
Nuke - Elektro Bastlirna
  Vytvořit účet Hlavní · Fórum · DDump · Profil · Zprávy · Hledat na fóru · Příspěvky na provoz EB

Vlákno na téma KORONAVIRUS - nutná registrace


Nuke - Elektro Bastlirna: Diskuzní fórum

 FAQFAQ   HledatHledat   Uživatelské skupinyUživatelské skupiny   ProfilProfil   Soukromé zprávySoukromé zprávy   PřihlášeníPřihlášení 

"Rozsekání" čísla po desítkách

 
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Programování PIC, ATMEL, EEPROM a dalších obvodů
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
pirat077



Založen: May 02, 2014
Příspěvky: 324

PříspěvekZaslal: st listopad 19 2014, 13:27    Předmět: "Rozsekání" čísla po desítkách Citovat

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.

Díky
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
forbidden



Založen: Feb 14, 2005
Příspěvky: 8977
Bydliště: Brno (JN89GF)

PříspěvekZaslal: st listopad 19 2014, 14:34    Předmět: Citovat

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í.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
termit256



Založen: Dec 06, 2007
Příspěvky: 10335

PříspěvekZaslal: st listopad 19 2014, 15:32    Předmět: Citovat

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.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pirat077



Založen: May 02, 2014
Příspěvky: 324

PříspěvekZaslal: st listopad 19 2014, 16:08    Předmět: Citovat

termit256 napsal(a):
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á obrazek_cenzuraí dotaz: Ale vždycky to počítá celočíselně? není v tom nějaká zrada? nebo existuje fce pro zaokrouhlení na jednotky?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
AB1



Založen: Nov 23, 2009
Příspěvky: 312

PříspěvekZaslal: st listopad 19 2014, 16:54    Předmět: Citovat

kód:
unsigned int number = 1234;

jed = number % 10            // 4
des = (number / 10) % 10     // 3
sto = (number / 100) % 10    // 2
tis = (number / 1000) % 10   // 1


citace:
Ale vždycky to počítá celočíselně? není v tom nějaká zrada? nebo existuje fce pro zaokrouhlení na jednotky?

Dělení celočíselných typů probíhá celočíselně.

int a,b,c;
a=7;
b=2;
c=a/b; // c = 3

Asi by bylo dobré přečíst nějakou knihu o C.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pirat077



Založen: May 02, 2014
Příspěvky: 324

PříspěvekZaslal: st listopad 19 2014, 17:24    Předmět: Citovat

Díky, nefunguje mi tenhle program: (snad mě neukamenujete za tak dlouhej kus)

Displej bliká, něco se tam děje....
Budu fakt moc vděčnej za radu Wink

#define F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <math.h>

volatile unsigned int cislice;
volatile unsigned int cislo;
volatile unsigned char T1;
volatile unsigned char T2;
volatile unsigned char T3;

//////////////////////////////////////////////////////////////////////////
// TIMER 0
//////////////////////////////////////////////////////////////////////////
ISR (TIMER0_OVF_vect)
{
TCNT0 = 180; // preruseni po 19,2ms
T1++;
T2++;
//////////////////////////////////////////////////////////////////////////
// FCE PRICITANI PULZU - (PB3)
//////////////////////////////////////////////////////////////////////////
switch (T1)//kazdejch 19,2s scannuje pulz
{
case 1:
if ((!(PINB&0b00001000))==1){ //pokud neprisel pulz
T1=0;
}
break;

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

//TIMER2
TCCR2 |= (1 << CS22) | (1 << CS21)| (1 << CS20); // preddelicka /1024 //TCCR0 = 0b00000101;TIMSK = 0b00000011;
TIMSK|= (1 << TOIE2);// prerušenie pri pretečení TCNT2

sei(); //povol globálne prerušenia

PORTB=0b00110000;
_delay_ms(40);
PORTB ^= (1 << PB5);
_delay_ms(100);
}
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mtajovsky



Založen: Sep 19, 2007
Příspěvky: 3697
Bydliště: Praha

PříspěvekZaslal: st listopad 19 2014, 19:46    Předmět: Citovat

Nejspíš tam budete mít nějakou chybu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
pirat077



Založen: May 02, 2014
Příspěvky: 324

PříspěvekZaslal: st listopad 19 2014, 19:50    Předmět: Citovat

mtajovsky napsal(a):
Nejspíš tam budete mít nějakou chybu.

Ale kde? Very Happy
Já už nevím Sad
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mtajovsky



Založen: Sep 19, 2007
Příspěvky: 3697
Bydliště: Praha

PříspěvekZaslal: st listopad 19 2014, 20:46    Předmět: Citovat

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.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Zaky



Založen: Oct 30, 2010
Příspěvky: 6602
Bydliště: Praha

PříspěvekZaslal: st listopad 19 2014, 21:44    Předmět: Citovat

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 Smile 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á.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
WLAB



Založen: Sep 13, 2005
Příspěvky: 867
Bydliště: Praha

PříspěvekZaslal: st listopad 19 2014, 22:22    Předmět: Citovat

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
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pirat077



Založen: May 02, 2014
Příspěvky: 324

PříspěvekZaslal: st listopad 19 2014, 22:53    Předmět: Citovat

Díky, ty negace portu už jsem opravil,
...a ten komentář v ms je špatněj, zkoušel jsem jinej interval... Ale postřeh dobrej

hlavní chyba je v tom, že se ta hlavní suma pořád jen dělila časovačem2, za chvilku ukážu lepší řešení Wink
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
WLAB



Založen: Sep 13, 2005
Příspěvky: 867
Bydliště: Praha

PříspěvekZaslal: st listopad 19 2014, 23:24    Předmět: Citovat

jsi si jistej, ze v ISR u TIM2 misto
kód:

TCNT0 = 205;

nema byt
kód:

TCNT2 = 205;


Takhle na pohled mi to prijde divny....

Ten kod ma, obavam se, zasadni koncepcni vady... no uvidis...

A vkladej sem ten zdrojak jako "code", at to neni tak necitelna hruza...

_________________
de omnibus dubitandum est
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pirat077



Založen: May 02, 2014
Příspěvky: 324

PříspěvekZaslal: st listopad 19 2014, 23:57    Předmět: Citovat

WLAB napsal(a):
jsi si jistej, ze v ISR u TIM2 misto
kód:

TCNT0 = 205;

nema byt
kód:

TCNT2 = 205;


Takhle na pohled mi to prijde divny....

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 Wink

Díky!
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
WLAB



Založen: Sep 13, 2005
Příspěvky: 867
Bydliště: Praha

PříspěvekZaslal: čt listopad 20 2014, 0:32    Předmět: Citovat

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
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Programování PIC, ATMEL, EEPROM a dalších obvodů Časy uváděny v GMT + 1 hodina
Strana 1 z 1

 
Přejdi na:  
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

Powered by phpBB © 2001, 2005 phpBB Group
Forums ©
Nuke - Elektro Bastlirna

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.


PHP-Nuke Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Čas potřebný ke zpracování stránky 0.16 sekund