Jak se zbavit delay

Všetko čo sa týka mikropočítačov + Sekcia Arduino

Moderátori: psichac, Moderátori

DanielK
Stály člen
Stály člen
Príspevky: 283
Dátum registrácie: 28 Feb 2015, 14:55

Jak se zbavit delay

Príspevok od používateľa DanielK » 11 Dec 2016, 17:13

Ahoj, mám začátečnický dotaz: jak se zbavím _delay_ms()? Potřeboval bych, aby danná část kódu stála, ale zbytek aby dál běžel bez přestávky.

Například v tomto kódu, který jsem z větší části zkopíroval z Knihy AVR. Mám problém, že když se změní ADC hodnota a má dojít ke změně intervalu blikání musí se nejprve dokončit pauza která zrovna probíhá, ale mě by zajímalo, jak se to dá udělat, aby změna intervalu blikání reagovala ihned.

Kód: Vybrať všetko

#include <avr/io.h>  
#include <avr/interrupt.h>  

volatile int analog_value;
volatile unsigned int i;  
void delay_ms(unsigned int time);  
// pretečenie počítadla TCNT0 - nastane každých 100us  
ISR (TIMER0_OVF_vect){    
    // nastavenie počiatočnej hodnoty počítadla  
    TCNT0 = 156;     
    i++;   
}  
//vlastná čakacia funkcia s využitím čítača/časovača 0  
void delay_ms(unsigned int time){  
    TCNT0 = 156;  
    i=0;    
    // cakaj pokial prebehne i krat pretecenie  
    while(i != time*10);  
}  

 ISR(ADC_vect)  // přerušení po ukončení A/D převodu
{
analog_value = ADCH;
}

int main(){  
	DDRD=0b11111111; //Nastavení výstupů a výstupů
	PORTD=0b00000000; //Aktivace pull-up 
    DDRC = 0x00;       
    PORTC = 0b11111110;
    sei();   
    
    TCCR0 = 2;   //předdělička 8 
    // prerušenie pri pretečení TCNT0  
    TIMSK |= (1 << TOIE0);                
    sei(); //povol globálne prerušenia  


ADMUX = 0b01100000;       // reference Ucc
ADCSRA = 0b10001111;    
PORTD = 0x00;

            while(1)
             {             
              ADCSRA |= 0b01000000;    // spuštění ad převodu
              delay_ms(50);
              
                 if (analog_value < 50)
                {
                 PORTD ^= 0b10000000;      //invertuj PD7
                 delay_ms(100);
                }

               else
                {
                 PORTD ^= 0b10000000;
                 delay_ms(1000);
                }
             
             
             }
return 0;                       

                          
} 
Díky za pomoc.
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: Jak se zbavit delay

Príspevok od používateľa peterple » 11 Dec 2016, 17:30

Na to sú dve cesty. Ako to už tak býva v rozprávkach jedna je ľahšia a vedie do pekla. Druhá je náročnejšia a na jej konci čaká krásna princezná.

jedna cesta:
Napíšeš si vlastnú delay, ktorá čaká požadovaný čas a súčasne kontroluje aj udalosti na ktoré treba okamžite reagovať

druhá cesta:
Žiadne delay slučky nikde používať nesmieš. Všetko potrebné časovanie je treba robiť pomocou časovača, prerušení a nejakých stavových premenných.

Môžeš hádať ktorá vedie do pekla.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Používateľov profilový obrázok
Washu
Power user
Power user
Príspevky: 4521
Dátum registrácie: 15 Apr 2010, 00:00
Bydlisko: Multiverse
Vek: -1998
Kontaktovať používateľa:

Re: Jak se zbavit delay

Príspevok od používateľa Washu » 11 Dec 2016, 18:51

peterple: Dobre prirovnanie :D Tak budem pokracovat.
Je tu este jedna cesta, namahava, zlozita a tazka. Ale na jej konci dostanes k princeznej este aj cele kralovstvo.
Vola sa RTOS. Ale ma to zmysel len na dospelejsich procesoroch.
0
It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong
(Richard Feynman)

romiadam
Ultimate člen
Ultimate člen
Príspevky: 4426
Dátum registrácie: 09 Apr 2008, 00:00
Bydlisko: Wicklow, Irsko
Vek: 47

Re: Jak se zbavit delay

Príspevok od používateľa romiadam » 11 Dec 2016, 18:56

vsetko zavisi od toho co sa v danom programe deje. kedze si to nepopisal, nemozeme ti presne odpisat.
potrebujes ten delay mat na mikrosekundu presny? alebo to moze lietat hore dole aj o napr. 300ms?
Popis presne program (blokovo), a dostanes realne jednoduche riesenia. Bude sa ten program neskor dopisovat (doprogramovavat)? Alebo to bude uz fixny nemenny?
0
Prepáčte mi za diakritiku a preklepy - väčšinou píšem z mobilu a ENG klavesnice.
(výroky nemenovaného člena fóra:) ...základy elektrotechniky ovládam dokonale, tak napr. taký tyristor neviem ako presne funguje

Používateľov profilový obrázok
boraicho
Ultimate člen
Ultimate člen
Príspevky: 12417
Dátum registrácie: 03 Feb 2007, 00:00
Bydlisko: Prešov
Vek: 35
Kontaktovať používateľa:

Re: Jak se zbavit delay

Príspevok od používateľa boraicho » 11 Dec 2016, 19:23

viem že som neskuseny ale ak možem tak takto to robim, prakticky ja to tiež robim cez delaye ale prakticky stači ak to robi dajme tomu 100x za sekundu, čiže pre človeka je to prakticky odozva okamžitá.

pridam nejaku premennu.

usnigned int pocet=0;
unsigned int log=1;

while(1)
{


while(log==1)
{
ADCSRA |= 0b01000000; // spuštění ad převodu
if (analog_value <= 50) log=1;
else log=0;
delay_ms(10);
pocet++;
if(pocet==100)
{ PORTD ^= 0b10000000; //invertuj PD7
pocet=0;
}
}

while(log==0)
{
ADCSRA |= 0b01000000; // spuštění ad převodu
if (analog_value > 50) log=0;
else log=1;
delay_ms(10);
pocet++;
if(pocet==1000)
{ PORTD ^= 0b10000000; //invertuj PD7
pocet=0;
}
}
0
"Aj nevinne vyzerajúca súčiastka, môže byť príčinou nefunkčnosti zariadenia a tou kondenzator 100% je"
3D REBEL II + PLA + PETG
CNC 1810 na DPS

Zaky
Stály člen
Stály člen
Príspevky: 219
Dátum registrácie: 08 Nov 2014, 16:41

Re: Jak se zbavit delay

Príspevok od používateľa Zaky » 11 Dec 2016, 21:18

Takže jdeš vlastně přesně tou cestou do pekla, jak je popsáno výše :-) Při tom s použitím hw časovače a přerušení je to celé jen docela málo jiné. Spustíš hw časovač, pokud lze do kontinuálního běhu, třeba na těch 10ms, ten ti tedy každých 10 ms vyvolá přerušení, v přerušení si nahodíš příznak a v programové smyčce ho pak testuješ, když je příznak nahozený, inkrementuješ si ten svůj sw čítač a příznak shodíš. Takhle můžeš realizovat mnoho sw časovačů a program je pomalejší jen o část testování nahození příznaku od hw časovače. Asi nejsložitejší je na tom zvládnutí konfigurace hw časovače a konfigurace přerušení.
0

Pega
Stály člen
Stály člen
Príspevky: 192
Dátum registrácie: 28 Mar 2012, 08:52

Re: Jak se zbavit delay

Príspevok od používateľa Pega » 11 Dec 2016, 22:20

Trochu jsem tvůj kód změnil a okomentoval

Kód: Vybrať všetko

//Atmega8 , 8 MHz

#include <avr/io.h>  
#include <avr/interrupt.h>  

volatile uint8_t analog_value;  // VOLATILE je tu protože proměnná je použitá v main() i v přerušení 

////void delay_ms(unsigned int time); // tato deklarace je nutná pouze když kód funkce
                                      // je až za koncem main() 
  

// vypočítáme čas přerušení
// time[us] = 256 * prescaler / F_CPU[MHz] // 256 je max. hodnota čítače + 1 
// time = 256 * 8 / 8 = 256
// přetečení TCNT0 nastane každých 256us  

ISR (TIMER0_OVF_vect)
{    
static uint16_t counter_100ms = 0;   
static uint16_t counter_1s    = 0;   

   counter_100ms++;           // při každém přerušení inkrementuj čítače 
   counter_1s++;
   
   if(analog_value < 50) 
   {  
      if(counter_100ms > 390) // proběhlo 390 přerušení = 100 ms (99,84 ms)
      {
         PORTD ^= (1<<PD7);   // invertuj PD7
         counter_100ms = 0;
      }
   }
   else                       // if analog_value >= 50
   {
      if(counter_1s > 3906) 
      {
         PORTD ^= (1<<PD7);   // invertuj PD7
         counter_1s = 0;
      } 
   }
}     

//vlastná čakacia funkcia s využitím čítača/časovača 0  
////void delay_ms(unsigned int time){  
////    TCNT0 = 156;  
////    i=0;    
    // cakaj pokial prebehne i krat pretecenie  
////    while(i != time*10);  
////}
// tuto funkci nepotřebujeme, vše se odehraje v přerušení TIMER0  


////ISR(ADC_vect)  // přerušení po ukončení A/D převodu
////{
////   analog_value = ADCH;
////}
// použít přerušení ADC je tady zbytečné


int main()
{  
   DDRD  = 0b11111111;     // Celý portD výstupy
   ////PORTD = 0b00000000; // Aktivace pull-up 
   // pull-up se nastavuje hodnotou 1, ale má význam jenom u vstupů 

   DDRC = 0x00;            // Celý portC vstupní
   PORTC = 0b11111110;     // pull-up na všech pinech kromě PC0
   ////sei();     // ??         

   ////TCCR0 = 2;   //předdělička 8 
   // používej jména bitů
   TCCR0 = (1<<CS01);
   
   ////TIMSK |= (1 << TOIE0);  // povol prerušenie pri pretečení TCNT0             
   // při prvním zápisu do registru použij "=" , ne "|="
   TIMSK = (1 << TOIE0);
   ////sei(); //povol globálne prerušenia  
   // sei se většinou dává těsně před while() 

   ////ADMUX = 0b01100000;       
   ADMUX  = (1<<REFS0)|(1<<ADLAR); // reference Vcc, zarovnání vlevo (8-bit v ADCH)
   
   ////ADCSRA = 0b10001111;
   ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // zapni ADC a nastav předdělič   
   
   PORTD = 0x00;
   sei();

   while(1)
   {             
     ////ADCSRA |= 0b01000000;  
     ADCSRA |= (1<<ADSC);        // spuštění ad převodu
     ////delay_ms(50);
     while(ADCSRA & ADSC);       // čekej až převod skončí (bit ADSC se vrátí do nuly)

     analog_value = ADCH;
   }
}
//return 0; // toto se už dávno nepoužívá                      
0

Používateľov profilový obrázok
boraicho
Ultimate člen
Ultimate člen
Príspevky: 12417
Dátum registrácie: 03 Feb 2007, 00:00
Bydlisko: Prešov
Vek: 35
Kontaktovať používateľa:

Re: Jak se zbavit delay

Príspevok od používateľa boraicho » 11 Dec 2016, 22:29

Ano , na svoju obranu :) za seba tiež odporučam prerušenia a v tomto pripade by som tiež použil prerušenia, ale kedže autor otazky zrejme nevie použivať prerušenia, tak by som to riešil cestou do pekla :D a pridanim dalšieho kodu sa to vlastne dostane už len do pekla
0
"Aj nevinne vyzerajúca súčiastka, môže byť príčinou nefunkčnosti zariadenia a tou kondenzator 100% je"
3D REBEL II + PLA + PETG
CNC 1810 na DPS

Zaky
Stály člen
Stály člen
Príspevky: 219
Dátum registrácie: 08 Nov 2014, 16:41

Re: Jak se zbavit delay

Príspevok od používateľa Zaky » 12 Dec 2016, 00:21

S tím, že člověk pár ms delay nemá šanci poznat máš samozřejmě pravdu a pokud MCU nemusí stíhat nic jiného a ani není plánováno, že by v budoucny měl, tak se kód samozřejmě tak napsat dá a je to prostě jednodušší. Já třeba delay celkem běžně mastím do různých initů, kde je třeba nějaký test displeje, nebo zobrazení nějakých init hlášek a ještě to jinak nic nedělá, do programové smyčky ale pak už většinou ne, protože nepříklad jak je potřeba stíhat vyčítat sériák, byť i jen kvůli ladění, tak už 10 ms delay použít jednoduše není možné. Tazateli bylo řečeno, jak na to a pokud má zájem a něco času, tak nakonfigurování jistě časem zvládne.
0

DanielK
Stály člen
Stály člen
Príspevky: 283
Dátum registrácie: 28 Feb 2015, 14:55

Re: Jak se zbavit delay

Príspevok od používateľa DanielK » 12 Dec 2016, 17:44

peterple: Díky za reakci, ale moc moudrý z toho nejsem, protože nevím která klíčová slova vygůglovat, abych se o tom dozvěděl více.

Washu: Díky za tip. Koukl jsem na kód s RTOS, moc jsem z toho nepobral, zkusím ještě nějaké ukázkové programy najít.
Proč to má smysl jen na lepších procesorech? Momentálně tu mám ATMegu8, to asi moc dospělejší procesor není :)

romiadam: Chtěl bych se to naučit používat univerzálně. Rád bych aby to bylo přesný (v rámci možností).
Toto neni konečný program, chci pochopit jenom princip, abych to uměl časem reálně používat.

boraicho: Díky za ukázkový program, tohle by určitě v tomto případě stačilo, ale až někdy v budoucu budu potřebovat, chtěl bych aby reakce byla co nejrychlejší.

Zaky: Díky.

Pega: Velký díky, tohle mi strašně moc pomohlo. Ale moc nerozumím tomu, proč to bliká rychlostí 100ms, i přesto že na PC0 mám plné napětí.
0

Používateľov profilový obrázok
Washu
Power user
Power user
Príspevky: 4521
Dátum registrácie: 15 Apr 2010, 00:00
Bydlisko: Multiverse
Vek: -1998
Kontaktovať používateľa:

Re: Jak se zbavit delay

Príspevok od používateľa Washu » 12 Dec 2016, 18:11

Vacsie procesory maju podporu HW pre beh OS. AVR je prilis jednoduche, ma velmi malo RAM, obmedzenu instrukcnu sadu. Da sa nanom prevadzkovat jednoduche RTOS ale nieje to uplne ono. RTOS je velmi mocny nastroj na riesenie komplexnejsich problemov. Ale zas na jednoduche ulohy typu "blikanie ledkou" je to strasny owerkill.
0
It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong
(Richard Feynman)

Používateľov profilový obrázok
boraicho
Ultimate člen
Ultimate člen
Príspevky: 12417
Dátum registrácie: 03 Feb 2007, 00:00
Bydlisko: Prešov
Vek: 35
Kontaktovať používateľa:

Re: Jak se zbavit delay

Príspevok od používateľa boraicho » 12 Dec 2016, 18:22

co je PC0?

washu možeš aspon tu skratku RTOS prepísať do slov? aspon trošku k tomu niečo? vďaka
0
"Aj nevinne vyzerajúca súčiastka, môže byť príčinou nefunkčnosti zariadenia a tou kondenzator 100% je"
3D REBEL II + PLA + PETG
CNC 1810 na DPS

Používateľov profilový obrázok
Washu
Power user
Power user
Príspevky: 4521
Dátum registrácie: 15 Apr 2010, 00:00
Bydlisko: Multiverse
Vek: -1998
Kontaktovať používateľa:

Re: Jak se zbavit delay

Príspevok od používateľa Washu » 12 Dec 2016, 18:27

boraicho: Kedy sa naucis pouzivat google?
https://en.wikipedia.org/wiki/Real-time ... ing_system
0
It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong
(Richard Feynman)

DanielK
Stály člen
Stály člen
Príspevky: 283
Dátum registrácie: 28 Feb 2015, 14:55

Re: Jak se zbavit delay

Príspevok od používateľa DanielK » 12 Dec 2016, 19:13

Port C0, pin 23.
0

Marekodzapadu
Stály člen
Stály člen
Príspevky: 175
Dátum registrácie: 25 Apr 2010, 00:00
Vek: 12

Re: Jak se zbavit delay

Príspevok od používateľa Marekodzapadu » 12 Dec 2016, 19:26

Ako sa spomina vyssie. najidealnejsia je volba RTOS, je ich mraky staci si vybrat
Ale, davat RTOS na 8bit AVR je ako lodne delo na mravce, touto cestou by som nesiel.

1) Nastudovat trocha teorie o casovacoch a malicko teorie o "multitaskingu" a skusit co napisali chlapci vyssie
(nieze niekto napise ze na 1jadre nejde multitasking alebo bude o tom polemizovat!!)

2) Pohrat sa so srandou ProtoThreads , pre mna velmi sympaticke a uzitocne, chce to zopar dni kym sa to vstreba...

3) Pozriet sa na AvrWiz, dalsia paradna vecicka (:
0

Používateľov profilový obrázok
boraicho
Ultimate člen
Ultimate člen
Príspevky: 12417
Dátum registrácie: 03 Feb 2007, 00:00
Bydlisko: Prešov
Vek: 35
Kontaktovať používateľa:

Re: Jak se zbavit delay

Príspevok od používateľa boraicho » 12 Dec 2016, 19:29

to je jasne že je to nejaky pin ale čo ten pin robi? čo maš na nom? prečo na nom meraš napetie?
0
"Aj nevinne vyzerajúca súčiastka, môže byť príčinou nefunkčnosti zariadenia a tou kondenzator 100% je"
3D REBEL II + PLA + PETG
CNC 1810 na DPS

DanielK
Stály člen
Stály člen
Príspevky: 283
Dátum registrácie: 28 Feb 2015, 14:55

Re: Jak se zbavit delay

Príspevok od používateľa DanielK » 12 Dec 2016, 21:24

Marekodzapadu> Díky za odkazy. AvrWiz mi nějak nechce emulátor přelouskat :?

boraicho: Zatím k němu mám pro úplnou jednoduchost připojený potenciometr jako dělič napětí.
0

Používateľov profilový obrázok
Washu
Power user
Power user
Príspevky: 4521
Dátum registrácie: 15 Apr 2010, 00:00
Bydlisko: Multiverse
Vek: -1998
Kontaktovať používateľa:

Re: Jak se zbavit delay

Príspevok od používateľa Washu » 12 Dec 2016, 22:55

DanielK: vykasli sa na AVR a skus stm32f0 pre zaciatok. Ked skusis HW debug tak sa na AVR nevratis ;)
0
It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong
(Richard Feynman)

Zaky
Stály člen
Stály člen
Príspevky: 219
Dátum registrácie: 08 Nov 2014, 16:41

Re: Jak se zbavit delay

Príspevok od používateľa Zaky » 12 Dec 2016, 23:44

Má pravdu ten pán nade mnou, v dnešní době něco páchat na procesoru bez HW debugu prostě nemá smysl. Doby debugovací ledky jsou naštěstí minulostí.
0

alidedko
Ultimate člen
Ultimate člen
Príspevky: 3963
Dátum registrácie: 04 Feb 2013, 22:04
Bydlisko: U alibabky v Poprade
Vek: 32

Re: Jak se zbavit delay

Príspevok od používateľa alidedko » 13 Dec 2016, 08:03

Pravda pravda, skusil som len tak, na ochutnavku, zabrdnut do STM procakov. Je to uplne ina kava, nez AVR. Len keby toho casu bolo viac ...

(Ak by si velmi chcel, STM32F103 kit mi lezi na stole, posuniem dalej za dobru cenu)
0
Motto: Nikto nie je tak velky, aby sa nevosiel do truhly.

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok