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í 

Pomoc s kodem v C pro ATtiny13A

 
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
JirkaZ



Založen: Feb 26, 2021
Příspěvky: 2735

PříspěvekZaslal: pá květen 28 2021, 13:15    Předmět: Pomoc s kodem v C pro ATtiny13A Citovat

Zdravím,

byl by někdo z přítomných schopen a zejména ochoten mi pomoct s kódem v C pro ATtiny13A?

O co jde: potřebuji udělat úplně jednoduchý modul zajišťující pomalý analogový track and hold (podrobněji na schématu v příloze).

Jako skvělou inspiraci jsem našel https://adnbr.co.uk/articles/adc-and-pwm-basics . Je tam asi skoro všechno*, nicméně jako programátorský laik nejsem schopen ty ukázky "učesat a slepit" do jednoho zdrojového souboru, který bych předhodil překladači (nejspíš avr-gcc).

Jako alternativu (pro mě asi lepší) zvažuji Arduino IDE, kde jsem si už doinstaloval podporu pro ATtiny13, ale zůstávám "zaseknutý" na oné neschopnosti kód z příkladů "učesat a slepit".

(*) V ukázkových příkladech chybí mnou požadovaná klíčová funkce /HOLD a není tam ani použitý watchdog

Výstupem pro mě by tedy měl být jeden textový soubor (co nejvíce podobný těm příkladům a s ponechanými komentáři), který bych si už dále sám upravoval a současně se na tom učil.

Pokud by to nebylo triviální, můžeme se dohodnout na vhodné odměně.

Díky

--
Jirka



track_and_hold.png
 Komentář:
 Velikost:  33.07 kB
 Zobrazeno:  179 krát

track_and_hold.png


Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
ZdenekHQ
Administrátor


Založen: Jul 21, 2006
Příspěvky: 25741
Bydliště: skoro Brno

PříspěvekZaslal: pá květen 28 2021, 13:43    Předmět: Citovat

Mám dojem, že jdeš s kanónem na vrabce.

Ten obvod se správně jmenuje "sample and hold". Pokud je sepnuto, napětí na výstupu odpovídá napětí na vstupu. Pokud je rozepnuto, drží hodnotu. Procesor netřeba. Technicky to lze zapojit tak, že se na "hold" přepíná až při změně řídícího signálu, jinak ten kondík vůbec není v cestě signálu.

Nakonec případná analogová filtrace bývá taky daleko efektivnější.

Převod na PWM na výstupu je taky daleko jednodušší, nejsi limitovaný taktem procesoru.

_________________
Pro moje oslovení klidně použijte jméno Zdeněk
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?
]


Naposledy upravil ZdenekHQ dne pá květen 28 2021, 13:54, celkově upraveno 1 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
JirkaZ



Založen: Feb 26, 2021
Příspěvky: 2735

PříspěvekZaslal: pá květen 28 2021, 13:53    Předmět: Citovat

ZdenekHQ napsal(a):
Mám dojem, že jdeš s kanónem na vrabce.

Ten obvod se správně jmenuje "sample and hold". Pokud je sepnuto, napětí na výstupu odpovídá napětí na vstupu. Pokud je rozepnuto, drží hodnotu. Procesor netřeba.

Nakonec případná analogová filtrace bývá taky daleko efektivnější.

Převod na PWM na výstupu je taky daleko jednodušší.


Bohužel nikoliv.

Analogový sample and hold je sice teoreticky možný, ale reálně není s rozumnou součástkovou základnou schopen udržet hold hodnotu déle než řekněme jednotky, max. desítky minut. Já to potřebuju teoreticky "na furt", lépe řečeno do doby vypnutí obvodu.

Jsem založením analogový hw elektronik s praxí mnoho desítek let a nepochybuj o tom, že kdyby to bylo možné, už dávno jsem tu dvojici OZ, spínač, kondenzátor a pár odporů použil...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
ZdenekHQ
Administrátor


Založen: Jul 21, 2006
Příspěvky: 25741
Bydliště: skoro Brno

PříspěvekZaslal: pá květen 28 2021, 13:54    Předmět: Citovat

Ta informace "na furt" je někde v zadání?
_________________
Pro moje oslovení klidně použijte jméno Zdeněk
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?
]
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
JirkaZ



Založen: Feb 26, 2021
Příspěvky: 2735

PříspěvekZaslal: pá květen 28 2021, 13:58    Předmět: Citovat

ZdenekHQ napsal(a):
Ta informace "na furt" je někde v zadání?


Ne, v zadání není, je nepřímo obsažena už v principu řešení a pro něj není podstatná.

Opravdu nepotřebuju nic jiného, než na co jsem se ptal. Čili ani nespecifikuju momentálně nepodstatné věci, vše důležité je ve schématu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
ZdenekHQ
Administrátor


Založen: Jul 21, 2006
Příspěvky: 25741
Bydliště: skoro Brno

PříspěvekZaslal: pá květen 28 2021, 14:00    Předmět: Citovat

Děláš klasickou chybu, že navrhneš pouze vlastní řešení a nenapíšeš PROČ. Pak se nediv podobným reakcím. Tak hodně štěstí.
_________________
Pro moje oslovení klidně použijte jméno Zdeněk
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?
]
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
lesana87



Založen: Sep 20, 2014
Příspěvky: 3327

PříspěvekZaslal: pá květen 28 2021, 20:38    Předmět: Citovat

Tak jsem ti to slepila dohromady, ale nemám to teď na čem vyzkoušet. Very Happy

kód:


// 9.6 MHz, built in resonator
#define F_CPU 9600000
#define PWM_OUT 1 //PWM output on PB1
#define HOLD 4 // HOLD signal on PB4

#include <avr/io.h>

void adc_setup (void)
{
    // Set the ADC input to PB2/ADC1
    ADMUX |= (1 << MUX0);
    ADMUX |= (1 << ADLAR);

    // Set the prescaler to clock/128 & enable ADC
    ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
}

int adc_read (void)
{
    // Start the conversion
    ADCSRA |= (1 << ADSC);

    // Wait for it to finish
    while (ADCSRA & (1 << ADSC));

    return ADCH;
}

void pwm_setup(void)
{
    // Set Timer 0 prescaler to clock/8.
    // At 9.6 MHz this is 1.2 MHz.
    TCCR0B |= (1 << CS01) | (1 << CS00);
    // Set to 'Fast PWM' mode
    TCCR0A |= (1 << WGM01) | (1 << WGM00);
    // Clear OC0B output on compare match, upwards counting.
    TCCR0A |= (1 << COM0B1);
}

void pwm_write (int val)
{
    OCR0B = val;
}

// ... adc_setup, adc_read, pwm_setup, pwm_write ...

int main (void)
{
    int adc_in;

    // LED is an output.
    DDRB |= (1 << PWM_OUT);
    DDRB &= ~(1<<HOLD); // Makes HOLD pin of PORTB as Input

    adc_setup();
    pwm_setup();
    while (1) {
        // Get the ADC value
        adc_in = adc_read();
        if (PINB & (1<<HOLD)) {
             // Now write it to the PWM counter
            pwm_write(adc_in);
        }
    }
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
JirkaZ



Založen: Feb 26, 2021
Příspěvky: 2735

PříspěvekZaslal: pá květen 28 2021, 20:52    Předmět: Citovat

lesana87 napsal(a):
Tak jsem ti to slepila dohromady, ale nemám to teď na čem vyzkoušet. Very Happy


Díky moc, ATtiny13 budu mít k dispozici až příští týden, dám vědět.

Mimochodem jsem si nevšiml, že na původním odkazu https://adnbr.co.uk/articles/adc-and-pwm-basics je až dole další odkaz na https://gist.github.com/adnbr/9289235 a tam je ten mnou požadovaný "učesaný a slepený" kód z příkladů vcelku... Samozřejmě tam není funkce /HOLD.

Watchdog v Tebou slepeném kódu zatím zřejmě není, šel by dopsat?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mahoney



Založen: Oct 26, 2019
Příspěvky: 381

PříspěvekZaslal: so květen 29 2021, 9:42    Předmět: Citovat

Šel.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
bdn



Založen: Jan 16, 2020
Příspěvky: 467

PříspěvekZaslal: so květen 29 2021, 17:55    Předmět: Citovat

Přidání watchdogu pro kód výše.
první číslo znamená, číslo řádku, kam nakopírovat...
kód:
/* 7 */ #include <avr/wdt.h>
/* 57 */ wdt_enable(WDTO_500MS);
/* 59 */  wdt_reset();

Mimochodem kód výše je 8bit. ADC hodnota a 8bit. PWM. Modernější např. attiny1614 má 16bit. timer, takže PWM zde může být 16bit. rozlišení...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
JirkaZ



Založen: Feb 26, 2021
Příspěvky: 2735

PříspěvekZaslal: ne květen 30 2021, 19:57    Předmět: Citovat

bdn napsal(a):
Přidání watchdogu pro kód výše.
první číslo znamená, číslo řádku, kam nakopírovat...
kód:
/* 7 */ #include <avr/wdt.h>
/* 57 */ wdt_enable(WDTO_500MS);
/* 59 */  wdt_reset();



Díky moc, zkusím v týdnu, až budu fyzicky mít tu ATtiny13A. Napíšu sem výsledek.

bdn napsal(a):

Mimochodem kód výše je 8bit. ADC hodnota a 8bit. PWM. Modernější např. attiny1614 má 16bit. timer, takže PWM zde může být 16bit. rozlišení...


Ano, já vím, že ATtiny13 má osmibitový PWM a že v tom kódu se využívá jen horních 8 bitů z 10bit ADC (autor to popisuje na zdrojové stránce).

Jenže: existuje ATtiny (popř. prostě nějaký Atmel) v osmivývodovém pouzdře a s 10bit ADC i PWM? Při zběžném hledání jsem neuspěl, našel jsem pouze PICy a tam bych potřeboval, aby mi někdo vhodný program napsal úplně komplet... Osmivývodové pouzdro potřebuju kvůli místu na DPS.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mahoney



Založen: Oct 26, 2019
Příspěvky: 381

PříspěvekZaslal: po květen 31 2021, 13:45    Předmět: Citovat

Ten kód bude víceméně stejný, jen pojistky, inicializace a jména registrů se budou lišit. Vhodné MCU jsou PIC12F683, PIC12F1501, PIC12F1822 (či 12F1840). Víc teď nemůžu pomoci, snad se toho někdo chytne.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
FHonza



Založen: Nov 20, 2012
Příspěvky: 1453
Bydliště: Praha

PříspěvekZaslal: út červen 01 2021, 21:22    Předmět: Citovat

JirkaZ napsal(a):

Jenže: existuje ATtiny (popř. prostě nějaký Atmel) v osmivývodovém pouzdře a s 10bit ADC i PWM?

ATtiny212, ATtiny412
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
JirkaZ



Založen: Feb 26, 2021
Příspěvky: 2735

PříspěvekZaslal: st červen 02 2021, 7:54    Předmět: Citovat

FHonza napsal(a):
JirkaZ napsal(a):

Jenže: existuje ATtiny (popř. prostě nějaký Atmel) v osmivývodovém pouzdře a s 10bit ADC i PWM?

ATtiny212, ATtiny412


Aha, díky... ATtiny212 je dokonce o fous levnější než ATtiny13 a sem tam se dá i sehnat. No, uvidíme...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
JirkaZ



Založen: Feb 26, 2021
Příspěvky: 2735

PříspěvekZaslal: út červen 08 2021, 21:02    Předmět: Citovat

Tak po dalších neumělých úpravách z mé strany vzniklo něco jako funkční kód, osobně úspěšně ověřený s ATtiny13A.

Maximalizoval jsem frekvenci PWM (původní kód poskytoval cca 550 Hz, nyní cca 35,71 kHz), dvojnásobně zrychlil A/D převodník, použil pro něj vnitřní referenci 1,1 V . Jo a 8 bitů PWM stačí (lépe řečeno musí stačit)...

Pro mě je zajímavé, že tento kód lze vložit do Arduino IDE (samozřejmě při nastavení správné "desky", zde MCU na ATtiny13), kompilace normálně proběhne bez chyb a stejně tak se exportuje i výsledný *.hex. Čili není třeba se zabývat s avr-gcc v konzoli a s hledáním správných parametrů překladu.

Pak už jen vhodný programátor a je hotovo Wink

Tímto děkuji všem zúčastněným...

kód:

// Track and hold (sample and hold) circuit with ATtiny13A
// voltage input on pin 7 (PB2/ADC1), PWM output on pin 6 (PB1),
// control input (H=track, L=hold) on pin 3 (PB4)
// fclk 9.6 MHz, built in resonator
// original source: https://adnbr.co.uk/articles/adc-and-pwm-basics
// original source: https://gist.github.com/adnbr/9289235
// modification: http://www.ebastlirna.cz/modules.php?name=Forums&file=viewtopic&p=1175950

#define F_CPU 9600000
#define PWM_OUT 1 //PWM output on PB1
#define HOLD 4 // HOLD signal on PB4

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

void adc_setup (void)
{
    // Set the ADC input to PB2/ADC1
    ADMUX |= (1 << MUX0);
    ADMUX |= (1 << ADLAR);
    ADMUX |= (1 << REFS0); // set ADC ref. to internal ref. 1.1V

    // Set the prescaler to clock/128 & enable ADC (fclk for ADC cca 75 kHz)
    //ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
    // Set the prescaler to clock/64 & enable ADC (fclk for ADC cca 150 kHz)
    ADCSRA |= (1 << ADPS1) | (0 << ADPS0) | (1 << ADEN);
}

int adc_read (void)
{
    // Start the conversion
    ADCSRA |= (1 << ADSC);

    // Wait for it to finish
    while (ADCSRA & (1 << ADSC));

    return ADCH;
}

void pwm_setup(void)
{
    // Set Timer 0 prescaler to fclk/n
    //TCCR0B |= (1 << CS01) | (1 << CS00);//n=64, fpwm cca 550 Hz
    //TCCR0B |= (1 << CS01) | (0 << CS00);//n=8, fpwm cca 4.464 kHz
    TCCR0B |= (0 << CS01) | (1 << CS00);//n=1=no prescaling, fpwm cca 35.71 kHz
    // Set to 'Fast PWM' mode
    TCCR0A |= (1 << WGM01) | (1 << WGM00);
    // Clear OC0B output on compare match, upwards counting.
    TCCR0A |= (1 << COM0B1);
}

void pwm_write (int val)
{
    OCR0B = val;
}

// ... adc_setup, adc_read, pwm_setup, pwm_write, watchdog ...

int main (void)
{
    int adc_in;

    // LED is an output.
    DDRB |= (1 << PWM_OUT);
    DDRB &= ~(1<<HOLD); // Makes HOLD pin of PORTB as Input

    adc_setup();
    pwm_setup();
    wdt_enable(WDTO_500MS);
    while (1) {
        // Get the ADC value
        wdt_reset();
        adc_in = adc_read();
        if (PINB & (1<<HOLD)) {
             // Now write it to the PWM counter
            pwm_write(adc_in);
        }
    }
}
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.17 sekund