Shiftelés, bit-bang és a C

Fórumok

Iskolás feladat. Egy csipes processzor (most épp STM8), "plain C" (most épp sdcc).
Handlert írogatok egy 2x74HC164 shift regiszterrel kihajtott 8 digites hétszegmenses kijelzőhöz. Van egy adat és egy clock pinje (no meg persze táp).

Assembly -ben 16 bites regisztert shiftelgetek a carry flag irányába és egy utasítással a carry flaget kirakom az adat pin -re. "shift left" utasítás ami a carry -t is használja szinte minden egy csipes tud, nem gond.

Hogy kell ezt csinálni, ha C -ben kell megírni?

Egy ötlet: nem a carry de a 15. bitet figyelve ha az egy, akkor egyet írok a portra, ha ez 0 akkor nullát, a shift utasítás meg alap a C -ben.

Hozzászólások

Érdekességképpen:

https://c.godbolt.org/z/6q67cv   <-- stm8
https://c.godbolt.org/z/qdTGxY   <-- ARM Cortex M3, például STM32F1xx
https://c.godbolt.org/z/chTM9d   <-- PC
https://c.godbolt.org/z/bnqW9Y   <-- kíváncsiságból RISC-V

Viszont bitreverzre nem a fenti megoldás az optimális, helyette bitcsoportonként érdemes.
Lásd itt az utolsó példa assembly-jét: https://rust.godbolt.org/z/sKrb9x

Hű ez nagyon tetszik! Köszönöm!
Nem ismertem ezt a site -ot, mikor tűnnek el az "ujj gyakorlatok"?

A szakirodalomban halottam, hogy az ARM processzorok C -ben nagyon hatékonyak de nem godoltam hogy ennyire. Úgy hogy az stm8 extended utasítás készlettel bír, egészen egzotikus címzési módokkal.

* Én egy indián vagyok. Minden indián hazudik.

És még kettő fordítás:
   https://c.godbolt.org/z/1voGTY <-- AVR8, ATtiny, ATmega
   https://c.godbolt.org/z/s6nxE4 <-- MIPS, például a Microchip PIC32 mikrovezérlője vagy a sok OpenWRT-s SOHO router procija.

Ha bármikor kell a tempó, a 8 bites és a 32 bites mikrovezérlő között közel sem az órajel arány lesz a gyorsulás, hanem a több byte-os értékek egyben való kezelhetőségével nyersz.
Mondom annak tükrében, hogy annó 8 bites PIC-re fejlesztettem IP stacket. A 32 bites értékek összehasonlítása soklépcsős volt, ma a 32 bites mikrovezérlőknél egyetlen cmp.

És egy kis 32 bites összehasonlítás:
    https://c.godbolt.org/z/bqEjce  <-- ARM, pl. STM32
    https://c.godbolt.org/z/86noaT <-- MIPS, pl. PIC32 vagy OpenWRT-s SOHO routerek
    https://c.godbolt.org/z/Wz4xo8 <-- 8 bites AVR
    https://c.godbolt.org/z/b9jaco   <-- STM8 ... jé van 16 bites loadw és cmpw ... rövidebb az assembly. Vajon 1 órajelesek? Hát csodák nincsenek, 2 órajeles (66. old).

Köszönöm!

Végig követtem a fejlődést, az i8080 és MCS51 -től. Inkább csak az egycsipesektől távolodtam el. A 80 és 90 es években nagyon eszköztelenek voltunk (egy időben betéve tudtam az '51 opcodjait hexában).
Láttam 16 bites, majd a 32 bites processzorok felemelkedését és most itt vannak a 64 bitesek.

OFF: Amit nem értek, az hogy a legújabb 4 magos, Raspberry Pi 4G RAM -al nem annyira gyors mint azt vártam volna (m,ég van a 256M -ból is, persze azon nemigen futtattam grafikus felületet).

* Én egy indián vagyok. Minden indián hazudik.

Szintén zenész. Bár én igazán az 1995 után kóstoltam bele a mikrovezérlős világba PIC majd a fejlettebb AVR8 oldaláról. Előtte 1987-től a 6502-es proci assembly trükkjei volt az iskola.
Ez a könyv mai szemmel is elgondolkoztató, milyen játékosan magyarázta el például a kettes komplemenst a sima dinnyemérés 1, 2, 4, 8 ... kg-os súlyai után. Küldöm pár oldal fotóját:
    http://hg2ecz.ham.hu/forumkep_hup/20201108_090839.jpg
    http://hg2ecz.ham.hu/forumkep_hup/20201108_091549.jpg
    http://hg2ecz.ham.hu/forumkep_hup/20201108_091530.jpg
    http://hg2ecz.ham.hu/forumkep_hup/20201108_090903.jpg
Akkoriban az összes elérhető könyvet beszereztem ez utóbbi procihoz. Frankó, érthetően magyarázó magyar nyelvű könyvek jelentek meg nagy ritkán a megyei könyvesbolt polcán.

Raspberry Pi4: a 4 magos ARM Cortex A72 nagyon gyors valójában. Kettő dolog: hőmegfutás ellen visszaszabályoz, teljesítményigény esetén érdemes a csupasz toknál jobban hűteni. A másik az energiaellátás. Az Rpi3-nál mértem még ki, hogy gyengébb táp esetén ha beszakadt a feszültség egy pillanatra, akkor 600 MHz energiatakarékos órajelre váltott, fele számítási tempót adva.

Máskülönben a szoftverek hanyagsága okozza leginkább a lassú érzést. Próbáld ki a mai x86 szoftvereket például Pentium4-en. Használhatatlanul nehézkesen futnak a mai szoftverek Pentium4-en. Pedig ha mélyebbre ásunk, még a Pentium-MMX idejében is tudtuk használni a számítógépet filmnézésre, stb.
A NEON-t ha megtanulod használni, az float32x4_t-vel leírva amit akarsz, 4-szerezi a számítási tempót, hiszen 4 sávon fogja egyszerre produkálni a 4 szorzatot.

Lásd: https://c.godbolt.org/z/17hzzW

ARM Cortex A szériánál egyébként általában nem a CPU a leggyengébb láncszem, hanem a RAM illesztés. Frankó gyorsra megírod az aritmetikát és érzed, hogy éhezik a processzor, nem bírja a RAM táplálni.
Egyébként a közép- és felsőkategóriás mikrovezérlők is felnőttek a jelfeldolgozási feladathoz. Nézd meg az egyik zászlóshajót, az STM32H7 családot. Egy 480 MHz-en járó ARM Cortex M7 és egy 240 MHz-en járó ARM Cortex M4. Az ARM Cortex M7 mag hardverből aritmetikázza a double-t is a float mellett. Egyedül a NEON nincs bennük, de előbb-utóbb lesz mikrovezérlős ágon HELIUM.

Ugyan nem értem, hogy jött ide a bitreverzió, de ha már az, akkor minek a ciklus?

unsigned short int reverse16(unsigned short int x)
{
	x = (((x & 0xaaaa) >> 1) | ((x & 0x5555) << 1));
	x = (((x & 0xcccc) >> 2) | ((x & 0x3333) << 2));
	x = (((x & 0xf0f0) >> 4) | ((x & 0x0f0f) << 4));
	x = (((x & 0xff00) >> 8) | ((x & 0x00ff) << 8));
	return x; // Hogy szep legyen. :P
}

Innen, csak 16-bitre.

Jaja, pontosan így csináltam meg az FFT tesztemnél is C-ben és a reverse_bits() metódus előtt Rust-ban is (1.37). Arra akartam egyúttal rávilágítani, hány helyen lehet indokolatlan lassulást okozni a szoftverekben.
Egyébként a Lua volt a legfurmányosabb az 5.3-as verziót megelőzően. Ott ugyanis kizárólag double volt a numerikus típus, de szerencsére van egy "bit" nevű standard modulja, ahol a háttérben áttöltötték uint64_t-re az értéket, elvégezték a logikai műveletet majd visszatöltötték double-ba. Az alábbi módon nézett ki (32 bitre):

  brev = bit.bor(bit.rshift(bit.band(brev, 0xaaaaaaaa), 1), bit.lshift(bit.band(brev, 0x55555555), 1))
  brev = bit.bor(bit.rshift(bit.band(brev, 0xcccccccc), 2), bit.lshift(bit.band(brev, 0x33333333), 2))
  brev = bit.bor(bit.rshift(bit.band(brev, 0xf0f0f0f0), 4), bit.lshift(bit.band(brev, 0x0f0f0f0f), 4))
  brev = bit.bor(bit.rshift(bit.band(brev, 0xff00ff00), 8), bit.lshift(bit.band(brev, 0x00ff00ff), 8))
  brev = bit.bor(bit.rshift(brev, 16), bit.lshift(brev, 16))

 

A double a modern procikon, ahol van hardveres double aritmetika, ott szkriptnyelvre jó választás. A "mantissa" vagyis tört érték double esetén 52 bitnyi törtet tartalmaz. Ergó veszteség nélkül 52 bites számot oda-vissza használhatod.
Ha bárkinek demózni akarsz, az alábbit mutasd be float-ra (23 bit tört):

#include <stdio.h>

int main() {
    for (int i=0; i<10; i++) {
        int   ni = (1<<24) - 5 + i;
        float nf = ni;
        printf("%d <--> %f\n", ni, nf);
    }
}

és double-ra (52 bit tört):

#include <stdio.h>

int main() {
    for (int i=0; i<10; i++) {
        long long  ni = (1LL<<53) - 5 + i;
        double nf = ni;
        printf("%Lu <--> %f\n", ni, nf);
    }
}

Látszik, hogy mindkét példánál az első 5 lépés okés, a határ utáni 5 lépés gázos.
Egyébként tévedtem előbb, a bit operátorok 32 bites értékig működtek LUA-ra, nem engedték az 52 bitet: http://lua-users.org/wiki/BitwiseOperators

Valamikor implementáltam C-ben egy saját virtuális CPU-t saját utasításkészlettel. Én is ezt követtem, csak double tipusa volt és minden egyszerűbb lett az implementációban. A LUA is minimalista, ezért szeretik hozzáfordítani NGINX, nmap és sok programhoz beágyazott szkriptingre. A LuaJit környezet ráadásul gyors is (C-vel elérhető tempó harmada-negyede) az általa ismert architektúrákra.

> A double a modern procikon, ahol van hardveres double aritmetika, ott szkriptnyelvre jó választás. A "mantissa" vagyis tört érték double esetén 52 bitnyi törtet tartalmaz. Ergó veszteség nélkül 52 bites számot oda-vissza használhatod.
> Ha bárkinek demózni akarsz, az alábbit mutasd be float-ra (23 bit tört):

Ha a számok, amikkel dolgozom, garantáltan nem fognak lebegőpontos értéket felvenni, akkor a lebegőpontos ábrázolás felesleges overhead-et csinál, nagy általánosságban is, de pont például az általad hozott bitwise műveleteknél pláne. Úgy meg főleg, ha csak 32-bitig működik, mert akkor minden 64-bites bitwise műveletet több lépésben kell végrehajtani.

> Valamikor implementáltam C-ben egy saját virtuális CPU-t saját utasításkészlettel. Én is ezt követtem, csak double tipusa volt és minden egyszerűbb lett az implementációban.

Virtuális CPU-t én is csináltam már egy párat, de eszembe se jutott volna float-only módon megcsinálni bármelyiket.
A másikra: ne érts félre, nem bántottam a Lua-t, nem ismerem, csak ez így furcsa volt.

Ha temagad hajtod ki a portokat a megfelelo i/o biteken keresztul akkor barmilyen sima C algoritmus teljesen jo, maximum nem lesz gyors. Master eszkozoket bitbangelni jolval egyszerubb mint slave-eket :) 

Ha meg szamit a sebesseg akkor az egyik legeffektivebb megoldas az egy static inline ... () fuggveny implementalasa ami az adott architektura assembly-jeben csinalja meg ezeket a bitbang-eket. 

Bocsánat, csak most dugtam ki a fejem, már működget a kód de nem "tökéletes" - vegyes C és assembly.

A valóság az, hogy ugyan idétlen idők óta dolgozom C -ben, de az egycsipesek programozása ezen a nyelven még mindig sok tanulni valót mutat.
Borzasztóan zavar a bit kezelés. Folyton oda lyukadok ki, hogy bevágom a szükséges értékeket az sfr regiszterekbe mondjuk bináris számként (persze és/vagy). Ami nagyon gány, különösen ha valamit bele kell túrni, esetleg másik processzora alkalmazni. (Anno még a Simonyi féle annotációt is használtam).

Ráadásul, kiderült, hogy elavult sdcc -t használok - majd frissítenem kell. De már annyiszor eltérültem, hogy valamire jutni akarok előtte.

OFF: Nem gondoltam, hogy ennyien foglalkoznak egycsipesekkel.

* Én egy indián vagyok. Minden indián hazudik.

Pedig csak 1-szer kell megértened 10 perc alatt.

| --> bit szintű VAGY (bármelyik 1-es, a kimenet 1) ne keverd a  logikai  if ( true || false ) féle 1 bites vagy-gyal.
& --> bit szintű ÉS (ha mindegyik 1-es, akkor lesz a kimenet 1) .. ezt se keverd a logikai if ( true && false ) féle 1 bites és-sel.
^ --> bit szintű kizáró vagy (XOR). Kizárólag akkor 1, ha csak egyik 1-es, a másik 0-ás. A VAGY ugyebár 11 esetén is 1 volt.
~ --> bit szintű negálás Ezt se keverd a ! jellel. Utóbbi is csak 1 bites. Lásd még: false = 0; true = !false;
(x<<N) --> N lépéssel balra shiftel. Zárójelezd a kódokban, mert például az utána következő operátor precedenciája csúnyán bekavarhat. A C fordító warningot dob (-Wall esetén).
(x>>N) --> N lépéssel jobbra shiftel. Zárójelezd a kódokban.

Hasznos példa:
   4. bit és 0. bit set-elésére:  ertek |= (1<<4) | (1<<0); // utóbbit is kiírom a kódban a rend kedvéért, a fordító úgyis kiejti a <<0-t.
   4. bit és 0. bit resetelésére: ertek &= ~((1<<4) | (1<<0)); // amely biteket akarod resetelni, annak az egésznek az inverzével (~) ÉS-elünk.

   4. bit és 0. bit invertálására:   ertek ^=    (1<<4) | (1<<0); // XOR
   4. bit és 0. bit kivételével inv: ertek ^= ~((1<<4) | (1<<0)); // inverzével XOR

Még annyit érdemes megjegyezned, hogy melyik 4 bites érték (0b0000 ... 0b1111) mennyit ér és 16-os számrendszerben ez az érték mivel jelölendő (0..9 oké, majd A..F).
Ugyanis ahogy fentebb is láthattad, a bitek halmozása helyett áttérünk inkább 4 bitenként egyetlen digitre (0..F) a tömörebb leírhatóság miatt. De mögötte a logikai műveletek fejben való sakkozásánál mindig a bitképre gondolj.

Tedd el ezeket a sorokat és remélem nem lesz gondod a továbbiakban ezzel sem.

Köszönöm a rám fordított idődet. De ezeket jól ismerem.
A Kernighan Ritchie mindig a kezem ügyében van: Twenty-fourth Printing (Second Edition) 1994

Egyszerűen nem jár rá az agyam erre a kódolásra (ennél csak a gcc szimbolikus assemblere durvább).

Ha már az alapok, miért nem használunk bit field -et? Elvileg egy union, amivel akár byte -ot is felszeletelhetnénk.
(utoljára a win32 apiban a soros kommunikációnál láttam ilyet)

OFF: Ha már az FFT -nél tartunk, akkor beleártottad magad a digitális jelfeldolgozásba. Tudsz ajánlani valami használható olvasni valót a digitális szűrőkről?

* Én egy indián vagyok. Minden indián hazudik.

A bit field nagyon jó gondolat!

Az STM8 memory mapped io-val rendelkezik. Csak egy jó header kell, és készen vagy.

Nézegetem a fenti C fordítmány ajánlásokat és egyre jobban értem, miért nem programozok C-ben mikrokontrollert. :-D

Az STM8-nak van egy BCCM utasítása, amivel a CARRY értékét írja a portra.

Az alábbi pszeudokód egész biztosan megírható soronként 1 db ASM utasítással.

data16 - a kiírandó 16 bit

ciklus - ciklusszámláló

clock - a 74164 clock bemenete

data - a 74164 data bemenete

Ha valahol nem jó az időzítés a 74164 specifikációjához, akkor elegendő NOP utasítást kell beilleszteni.

	load(data16)

	ciklus=16
loop:

	clock=0

	lshiftC(data16)

	data=carry

	clock=1

	dec_jump_if_nz(ciklus) -> loop

	clock=0

Mit kell tudnia ilyenkor a C-nek?

  • a clock és data bitfieldben van
  • a clock=1 a megfelelő bit set utasításra fordul (BSET, BRES)
  • az lshiftC = data16<<1, de megőrzi a CARRY értékét (RLCW)
  • a data=carry pszeudokód az előző utasítás eredményét másolja a bit field-be (BCCM)
  • a dec_jump_if_nz pszeudokód -> if (--ciklus) goto loop vagy while(--ciklus) egy utasításra fordul*

*Ennél a processzornál nincs ilyen utasítás (?), ezét egy DEC és egy JRNE utasítás kell.

A C ennél a 9 utasításnál sokkal hosszabra fordulhat. Hardver programozásnál érdemes először pontosan megfogalmazni mi is a feladat, és csak utána okoskodni a C-vel. Az eredményt esetleg ellenőrizni/mérni kell az időzítések miatt.

Annak idején a 8085 (~8080) mellé 74LS259-ből készítettem 8 bites bit set/reset és impulzus(!) protot. Meg lehet oldani vele, hogy az adat íródjon ki, vagy külön címen legyen a set és a reset. Ezzel rögtön két új fajta utasítása keletkezett az általános processzornak.

16 bit ki shiftelésére ezt a kódot írtam:

volatile uint8_t    shft_idx;
volatile uint8_t    shft_dig;
volatile uint8_t    shft_seg[8];


void            shift_16(uint16_t w)
{
  w;
__asm
  ldw     x, (3,sp)
  push    #16
00001$:
  rlcw    x
  bccm    _PD_ODR, #PIN_DIN
  bset    _PD_ODR, #PIN_CLK
  bres    _PD_ODR, #PIN_CLK
  dec     (1, sp)
  jrne    00001$
  pop     a
  bres    _PD_ODR, #PIN_DIN
  ld      a, _shft_dig
  sll     a
  jrnc    00002$
  ld      a, 1
00002$:
  ld      _shft_dig, a

__endasm;
} //end shift_16(uint16_t w)

Még küzdök vele, de tulajdonképp működik. Nem vagyok vele elégedett. A fő probléma (nevetséges módon) a 16 bit shiftelendő összerakása, azt c -ben írtam és szörnyű. Anno mikor az UART kezeléshez írtam routinokat (cirkuláris buffer) a buffer pointereket egy a program memória szegmensben elhelyezett pointerekkel oldottam meg úgy, hogy kitudtam használni az stm8 elvetemült címzési módját - amolyan indirect indexelt címzés ld ([rx_ptr],X),A ahol az rx_ptr mutat a rx buffer elejére és az X tartalmazza az aktuálisan üres helyet. Viszont ez külön assembly fájlban volt, saját equate -kel. (Azért előnye is van, pl. nem nyomja bele a zavarba ejtő clr a, div x,a utasításokat)

* Én egy indián vagyok. Minden indián hazudik.

Véleményem szerint az assembly-t annyira célszerű minimalizálni a C kódjaidban, amennyire csak tudod.
Néha elkerülhetetlen, én a SIMD utasításokkal vagyok így. Továbbá gyors IRQ-nál néha van egy-egy frappáns assembly trükk.

Assembly hátrányai:
  - nem hordozható az algoritmusod, bár ennél az esetnél C-ben is kisebb korrekcióra szorul teljesen más architektúrára cipelésen.
  - könnyebben hibázhatsz assemblyben
  - nehezebb később általad is karbantartani a kódot, ha másnak adod akkor neki pláne.

Viszont van hogy kell nop mikrokésleltetéshez, ott legrosszabb esetben írsz egy ilyen makrót:
   https://c.godbolt.org/z/5GaG7c
Nézd meg, mi történi ha a más architektúrára (AVR helyett ARM, MIPS, x86, RISC-V) fordítod az iménti oldalon.
 

Ronda kód, ami a C konveció kavarodása.

A lokális változók helye a stack, mind az ötszázé! Itt meg csak 1 van.

Azt, hogy az A és X mentve van-e hívás előtt, nem tudjuk. De azért használjuk, akkor maradjon így!

Adatmozgatás A-n keresztől nincs, tehát szabadon használható.

Így aztán a bit számlálót töltheted az A-ba (push #16) és rögtön 17 ciklussal rövidebb a program, mert a pop a is elmarad.

A 74164 élvezérelt, úgy szebb vezérelni, ahogy korábban írtam a ciklusban:

  • clock=0
  • shift
  • data out
  • clock=1
  • loop

Így "hordozható" lesz a kód, mert gyorsabb processzoron és/vagy lassabb 164-es esetén sem kell NOP-okat beszúrni.

A data vonalat felesleges "nullázni" a ciklus végén.

Gyilkoljuk ki egy kicsit a C-t! Hiszen engem már cseszegettek azért, mert a terabájtos ;) programot illik rakni a flash-be.

shift_outW macro
	lda	x, w
	call	shift_out16
	endm

shift_out16
	rept	#16
	rlcw	x
	bres	_PD_ODR, #PIN_CLK
	bccm	_PD_ODR, #PIN_DIN
	bset	_PD_ODR, #PIN_CLK
	endm
	return

Ez maximális sebességgel kishifteli a szót.

Hívása: shift_outW    w

Ha nem sok helyről hívod, akkor a betöltést lerakhatod az alsó makróba, kihagyod a return-t, és még egyszerűbb a kód.

shift_outW macro
	lda	x, w
	rept	#16
	rlcw	x
	bres	_PD_ODR, #PIN_CLK
	bccm	_PD_ODR, #PIN_DIN
	bset	_PD_ODR, #PIN_CLK
	endm
	endm

Jólvanna! Nem ez volt a kérdés.

Szerintem a processzor készítői azért találták ki az utasításokat, hogy jól lehessen őket használni. Aztán jön a C fordító...

Jogos, mivel úgy látszik nem mentél lejjebb, ott látszik csak, hogy az egész eljárás interrupt -ban fut (timer 4 1ms tick), így a regiszterek mentése felesleges.

Az egyetlen lokális változó a ciklus számláló lenne ami 16, ott az akku.

Hát ebben a C épp a legkevesebb és a társalgás eredménye képpen lehet átírom C -be (de ezt még ki kell próbálni).
(Amikor munka szinten foglalkoztam ilyenekkel akkor nem is volt C compilerem)

OFF: Az egész project arrókl szól, hogy akarok csinálni egy precízebb volt/amper mérő műszert az ina226 -ra építve, amit simán rajta hagyhatok 10A -es áramon is (a multiméterek zöme max 20sec). Viszont kell neki egy jól látható kijelző (a szemem sem a régi), még a jó öreg 7 szegmenses LED tűnik a legjobbnak. Mivel nem akarok most NYÁK -al bíbelődni, olyan kijelzőt kerestem ami legalább 2x4 digit és két sor (nem egymás mellett). Ja és nem fogy ki belőle az elem, és ha kell lehet naplózni az adatokat.

* Én egy indián vagyok. Minden indián hazudik.

Nem az interruptra gondoltam. Van ilyen (pl. IBM xlc), hogy pragma isolated_call. Ellenkező esetben mindent ment, hátha a változókat módosítja a függvény. Ennek hiányában csak feltételeztem.

A projekt ina vs multiméter?  Persze nem akarom a játékodat elvenni, de ilyet talán 100A-ig az ebay árul. Az egész inkább a sönt kérdése, illetve annak hűtése. Az én "egyszer majd" projektem egy rs485-re kötött izolált fogyasztásmérő. ;)

Beletenyereltem olyan esetbe, amikor 12V-os akkumulátoros rendszer és 48V-os akkumulátoros rendszer táplálja az adott berendezéshalmazt. Sőt még van a berendezésből izoláltan kijövő 5V-os vezérlővezeték is. A mérési eredményeket viszont együttesen kell kezelni.
Ellenben egyáltalán nem számíthatsz arra, hogy a sok telephely közül tuti minden telephelyen a közös föld az akkumulátorok negatív pontja és a berendezés izolált vezérlővezetékének negatív lába is egy ilyen negatív közösre lenne kötve.

Üdv a laborszagon kívüli való világban!

No igen, amikor mindenfélét összeraknak, "integrálnak".
Az első ötlet egy ESP32 (vagy ESP8266) mint mérő eszköz és wifi kapcsolattal (ez tűnik jelenleg a legolcsóbbnak). Ha kell ez lehet AP is. Minden ilyen elfuserált helyre egy egy darab. Még jó hogy occó.

* Én egy indián vagyok. Minden indián hazudik.

Az sdcc pragma deklarációkig még nem jutottam el, van egyáltalán ilyenje?

Az eBay 100V/10A indultam neki én is mondván mit küzdjek, filléres árú.

 

OFF: Innen ez elektronika.
Van itt valaki akinek ez működött?
Teljesen fals dolgokat mér, sz@rt nem ér (vagy 6 db vettem különböző kereskedőktől, 23 és 4 digites verzióban).
Az áramot egy 0,007 Ohm shunt ellenálláson eső feszültséget egy lm358 -al erősítik fel. Már itt gáz, hiszen az LM358 adatlapja szerint 3V ami határeset, és a kimenet nem rail-to-rail hanem tápfesz -1,5V vagyis a mi esetünkben alig 1,5 lesz a swing. Az ADC referenciája 3,3V amit az mcu tápja ad meg. Az LM358 bemenetre vonatkoztatott offsetje akár 5mV. Az offset kompenzálás trükkjét megtaláltam a WEB -en, de nem segített, teljesen fals adatokat kapok (párhuzamba kötöttem egy régi USSR A/V/Ohm mérőt 6A -ig akár órákon át mér, nem 10-20 sec) akár 1A is téved és még csak nem is lineáris a hiba. Na itt lett tele a tököm.
"Megtaláltam" az ina226 -ot, (drágább mint az mcu) de eBay kibírható. 15bit+előjel a 75mV shunt ellenállások bármelyike tökéletes hozzá.
Egyébként megtaláltam a "prototípusát" ezeknek a vackoknak (meg egy blogot ahol hasonlóan nem értik miért vásárolnak ilyet az emberek). A prototípus, szintén LM358 használ, de 12V -ról és ott van hol tárolná az offsetet.
Ráadásul, mivel az mcu hajtja ki a LED -ket jól megrángatja a (3,3V) tápot, így a mérést még a mérés is rontja - tiszta káosz.

* Én egy indián vagyok. Minden indián hazudik.

Jaja, egy hetszegmens-kijelzo szerintem semmilyen szempontbol sem timing-kritikus. Raadasul azert sem mert a klasszik tobbszamjegyes hetszegmens driverek folyamatosan aktivan porognek (ha van 4 digited es 7 szegmensed akkor 4+7 labbal active high + active low formaban porgeti, es ezt illik azert nehany 100hz-n csinalni legalabb). Itt meg eleg csak es kizarolag akkor frissitened a shift regisztereket ha valtozik a szamertek. 

Szoval batran kiprobalnam barmelyik C-s bitbang megoldast, az tokeletesen fasza lesz erre a celra. Kesobb meg lehet probalkozni inline assembly-vel is, de nem lesz tole szoszerint sem latvanyosan jobb a kijelzok frissites. Azaz hogy 1.7μs vagy 2.8μs alatt frissul le mondjuk masodpercenkent 1x a kijelzett szamertek az szemmel mar nem fog latszani :) 

Pontosan. Ami számít, hogy ha PWM-mel van meghajtva (legtöbbször érdemes a fényerő és a fogyasztás csökkentése miatt), akkor annak a frekvenciája kellően nagy legyen, és állandó a kitöltési tényezője. Így nem villog, és nem hunyorog a kijelző. Ha sötétben is használják a kijelzőt, akkor idegesítő lehet, ha "szem elhúzásra" szétesik a kép - még néhány LED-es hátsó lámpa is ilyen, ezek engem borzasztóan idegesítenek. Ahhoz, hogy ez ne legyen jócskán növelni kell a frekvenciát, az 50-100Hz nagyon nem elég. Legjobb, ha hardveres a PWM emiatt. De ne is legyen túl nagy, mert akkor növekszik a fogyasztása és csökken az élettartama a kapcsolóelemnek.

Egyszer programoztam olyan kijelzőt, ami egy shiftreggel hajtott két bankot valahogy (felváltva, így meg lehetett spórolni pár shift reget), így minden PWM ciklusra be kellett frissíteni a teljes adatot. Ráadásul a PWM olyan lábon volt, amihez nem volt HW timer kimenet. Na, azt elég nehéz volt úgy megcsinálni, hogy kellően nagy és állandó kitöltésű lehessen a PWM frekvencia, de végül sikerült szépre megcsinálni. Vagy egy hetet elszórakoztam vele, ráadásul a megrendelőt nem is érdekelte ez az issue, csak saját szórakozásra akartam szépre megcsinálni.

Annak egyébként lehet értelme, hogy ha sok a digit, hogy bankonként különböző fázisú a PWM-mel vezérlünk, mert így a pillanatnyi fogyasztás kisebb tartományban ugrál, de ilyet is inkább úgy érdemes tervezni, hogy az adat egy hosszú láncolt shift-regben van, és az output enable PWM jelekből van 2-3 darab, és ezek eltolt fázisban aktívak.

Villódzás helyett:
    https://www.onsemi.com/pub/Collateral/MC74HC595A-D.PDF
    http://ww1.microchip.com/downloads/en/DeviceDoc/20001952C.pdf
    http://ww1.microchip.com/downloads/en/DeviceDoc/20005855A.pdf
Ezekből egymás utás több is felfűzhető. Igaz, ekkor minden egyes szegmenshez kell 1 db SMD vagy furatszerelt ellenállás.

Ha lett volna ilyen opció, akkor vagy a MAX7219 vagy a TM1637(3(9 vagy akár HT16K33 - fiókban van mind, de kész panelen, két sorban csak ez :(

Csak halkan, azért érdemes lenne ránézned mennyibe is kerülnek ezek az opciók. Pl. a MAX7219 a Farnell -nél >2.500,- Ft. Egy STM8S103F3 pedig <500,- Ft.

* Én egy indián vagyok. Minden indián hazudik.

Mint valahol írtam, most még nem akarok NYÁK -ot tervezni, gyártani. Így csak ezt találtam ahol a shift regiszterben nincs output latch. Maga a LED kijelző nem annyira időkritikus, de azért mégis.
mcu 16MHz órajel mellett a 16 bit ki shiftelése 100us és 1ms -ként jön a következő digit, így 62,5Hz -en frissül a 8 digit és homályban "parázslanak" a szegmensek ha nincsenek bekapcsolva. Nincs sok játék lehetőségem.

* Én egy indián vagyok. Minden indián hazudik.

Ezért kell assemblerben programozni, hogy az embernek lila gőze legyen, hogy mi történik. ;)

... vagy legalabb erdemes megnezni a disassembly-t hogy pontosan mi is keszult a ce kodbol :) En mindig meglepodom azon hogy -O3 mellett ugy romma tudja optimalizalni mar a gcc hogy viszonylag sok asm tapasztalat mellett is csak pislogok hogy ezt igy hogy ;)

Amikor időre (pontos időzítéssel) készítesz egy hardvert kezelő program részletet, ott szó sem lehet az optimalizálásról, különösen a sorrend változtatásról. Bonyolultabb esetben lehet dönteni az egyes műveletek átlapolásáról, de csak az adatlap(ok) alapján, amit ugye nem olvasott a fordító. ;)

Elrettentő példa, amikor egy nagytudású kolléga interfészt programozott. A 2-10us reakcióidőn belül ki tudja miért lebegőpontos műveleteket is végzett. A gép egy 4,77MHz-es XT volt, koprocesszor nélkül. ;) Nem is működött.

Amikor időre (pontos időzítéssel) készítesz egy hardvert kezelő program részletet, ott szó sem lehet az optimalizálásról, különösen a sorrend változtatásról. Bonyolultabb esetben lehet dönteni az egyes műveletek átlapolásáról, de csak az adatlap(ok) alapján, amit ugye nem olvasott a fordító. ;)

En mondjuk ennyire nem latom borusan ezt a kerdest ;) Legalabbis a tapasztalat is es az elvart mukodes is hogy pl periferia-illesztesnel a volatile-kent dekralt valtozok eleresenek sorrendjet tartani kell a forditonak - felteve persze ha a nyelvi elemekbe ez nem utkozik. Pl ha egy funct(a,b) hivas eseten az a is meg b is volatile read, akkor nem ismert a sorrend, de ha azt mondod hogy whatever_t x,y; x=a; y=b; funct(x,y); akkor az a-t elobb kell kiolvasnia az mmio-regiszterbol mint a b-t. Es a fordito azert megoldja hogy ezutobbi annyira hatekony legyen mint az ezelobbi - csak a jo sorrend garantalt. 

De persze, vannak szelsoseges peldak, peldaul ami nagyon tetszik az a low speed usb bitbang implementacio 12MHz-s AVR-en, ahol 8 orajeled van ugye letudni egy bitet, minden nyalanksaggal (pl stuffing). Na, ott azt valoban nem erdemes C-ben irni es egyebkent is eleg jol ismerni kell az architekturat ;) Lasd pl: https://github.com/harbaum/I2C-Tiny-USB/blob/master/firmware/usbtiny/in…, mint szep pelda. 

Az USB low speed bitbang szép példa, annó én is végigelemeztem a JK állapotoktól az SE0-ig. Egyébként pontosan ezért is került bele a szabványba a low speed, hogy a kezdeti időkben a hardvertámogatás nélküli mikrovezérlőkkel is kialakuljon a periféria erre az interfészre. És a legügyesebb húzás az volt, hogy a HOST kontroller után kötelező volt integrálni egy root hub-ot, mielőtt az USB tervei helyett gyors RS485-ként lett volna használva az interfész. De ez már történelem.

Egy mai assembly bitbang a Beaglebone PRU-ja. Ez 200 MHz-es 32 bites I/O processzor, amelyik a Linuxot futtató rendszer RAM-ját is direktben eléri. Na itt bitbangelhetsz  SPI kimenetet vagy akár több I2C-t vagy I3C-t is. Mind szoftverből és alacsony szinten.

Újabb elrettentő példa, ami ott is van valahol a githubon: AM2320 driver rpi

Írja a szoftvert az ember, serial_write(), stb. Aztán vesz egy másik rpi-t és nem megy vele.

Ugyanezt úgy írtam meg PIC-re, - amelynek nagyon jó i2c implementációja van, tehát semmi bitbang, - hogy elolvastam az adatlapot. A protokollban plusz két szabványon kivüli időzítést külön timerrel kellett megoldani. Ez a megoldás működik az órajeltől függetlenül. Nem csak feltételezem, hanem a gyakorlatban is szükség folt rá, mert valami nem ment debug módban a maximális sebességgel az adott processzoron.

Na igen, a tiny-usb sem bízta a C fordítóra a dolgot, pedig meg lehetne írni. De minek körülményesen elmagyarázni a C tájszólásával a feladatot, amikor oda lehet írni azt az utasítást.

Biztosan emlegettem valahol, ha a firmware-be "szoftvert" akarok írni, akkor megírom és tesztelem awk-ba. Aztán a kódot beemelem kommentként és kitöltöm asm utasításokkal. Ha jól dolgoztam, alig lesz hosszabb.

Mindenképpen meglepett, hogy a (nm épp a legfrissebb) sdcc milyen jó kis kódot generál.
Persze, ez csak akkor látszik ha megpróbálod assembly -ben megírni. Én fordítva ültem fel a lóra, először assembly aztán nézegettem a C fordítást. Nagyon sokat fejlődtek a C compilerek, érdemes rájuk támaszkodni. Viszont ellenőriuzni sosem árt, különösen egy interrupt -on belül.

OFF: Régen csináltam olyan "trükköt", hogy az interrupt routinon belül be pushj -oltam a hosszabb routin címét, és az iret először azt hívta meg (persze akkor gondoskodni kell a regiszterek mentéséről ami plusz idő). Cserébe érvényre jutottak az alacsonyabb prioritású interrupt -ok is. Feltéve hogy mind kellő gondossággal van kivitelezve, ez a minimális hibát okozott.
Miért is jöttem ezzel elő? Még nem piszkáltam az interrupt prioritásokat. Az ina226 i2c -ről megy és az STM hibajegyzékeibe elég sok hiba van az i2c interrupt kezelésével (már az is fura hogy az i2c mindössze egy interruptot kap amit aztán ott kell eldönteni miért is kaptad). Egyelőre az i2c kezelés polling -al működik (>30 év alatt először kezelek i2c -t, ez valahogy kimaradt) így valami egyszerű működő verziót kerestem és implementáltam. A következő lépés talán ennek az újra gondolása lesz, most már elérem azt a tudás szintet amivel meg tudom írni és ellenőrizni.

* Én egy indián vagyok. Minden indián hazudik.

Cserébe érvényre jutottak az alacsonyabb prioritású interrupt -ok is

Biztos hogy nem volt a prioritasok es/vagy beagyazhatosag beallitasanak valami gyaribb beepitett modja? :) Mondjuk jo kerdes, tenyleg, hogy milyen alkalmazasnal lehet ilyesmi szintu szofisztikaciora szukseg. 

Borzasztóan zavar a bit kezelés.

Ne zavarjon. Ha a C fordito okos es az architektura tamogatja az adott bitmuvelet hatekony elvegzeset, akkor ki fogja nekunk optimalizalni meg a bonyolultnak latszo kodot is. Tipikus pelda a bitforgatas (ROL, ROR): https://c.godbolt.org/z/easav8. Azaz:

#include <stdint.h>

uint64_t whatever(uint64_t x)
{
 if ( x & (1UL<<63) ) 
        return((x<<1)|1);
 else   
        return(x<<1);
}

Es ebbol megcsinalja a hatekony x86-os kodot:

whatever:                               # @whatever
        mov     rax, rdi
        rol     rax
        ret

Így néz ki a kicsit javított bit bang, az isr routinba ágyazva - 1ms nyomja ki a 16 bitet a 2db 74HC164 shift regiszterbe.

volatile uint16_t   tick_word;

volatile uint8_t    shft_idx;
volatile uint8_t    shft_dig;
volatile uint8_t    shft_seg[8];

const uint8_t       *ptr_seg = shft_seg;

//-----------------------------------------------------------------------------
inline void     shift_16(void);
void            hc164_setup(void);

//-----------------------------------------------------------------------------
inline void     shift_16(void)
{
__asm

  clrw    x
  ld      a, _shft_idx
  ld      xl, a
  ld      a, ([_ptr_seg],x)
  ld      xh, a
  ld      a, _shft_dig
  ld      xl, a
  ;--- ldw     x, (3,sp)
  ld      a, #16
00001$:
  rlcw    x
  bccm    _PD_ODR, #PIN_DIN
  bset    _PD_ODR, #PIN_CLK
  bres    _PD_ODR, #PIN_CLK
  dec     a
  jrne    00001$
  bres    _PD_ODR, #PIN_DIN
  sll     _shft_dig
  jrnc    00002$
  bset    _shft_dig, #0
00002$:
  ld      a, _shft_idx
  inc     a
  and     a, #0x07
  ld      _shft_idx, a

__endasm;
} //end shift_16(void)

//-----------------------------------------------------------------------------
void            tim4_tick_isr(void)  __interrupt(TIM4_ISR)
{
  // sdcc generate "clr a, div x,a" as a workaround !?
  tick_word++;
  TIM4_SR &= 0b11111110;      // UIF bit

  shift_16();
  // sdcc generate iret
}

A lista szerint működik az inline.
Viszont a segéd "ptr_seg" segéd pointeremet valami INITIALIZED területre teszi. Vajon ez a RAM vagy a ROM (program memória?

* Én egy indián vagyok. Minden indián hazudik.

C-ben a shift_16(): https://c.godbolt.org/z/b7z73a
Az SDCC fordító egyszer döntött bres mellett, egyébként általános megoldást használt or és and művelettel.
Ez a bset és bres hardverutasítást megkerülve picivel lassabb megldás, ellenben átláthatóbb a forráskód.
Kérdés, hogy kell-e nagyobb tempó? Ha igen, akkor kell segíteni még asm betéttel a C kódon: https://c.godbolt.org/z/zqzoGv

Az igazán durva az7 volt, mikor C -ből raktam össze mit is kell ki shiftelni

  uint16_t  w;

  w  = shft_dig;
  w |= (shft_seg[shft_idx] << 8);

Ebből lett

        ld      a, _shft_dig+0
        ldw     x, #_shft_seg+0
        ld      a, xl
        add     a, _shft_idx+0
        rlwa    x
        adc     a, #0x00
        ld      xh, a
        ld      a, (x)
        call

Ezt mind öszesen 1 utasítással tudtam lejjebb tenni (lásd feljebb) amihez kellet egy két bájt hely a CODE területen.
Nem biztos hogy megérte.

Az általad javasolt makrókhoz hasonlókat is használok (másutt)

#define BCPL_PA_ODR_BIT1()    __asm__("BCPL 0x5000,#1")
#define BRES_PA_ODR_BIT1()    __asm__("BRES 0x5000,#1")
#define BSET_PA_ODR_BIT1()    __asm__("BSET 0x5000,#1")
#define BCPL_PA_ODR_BIT2()    __asm__("BCPL 0x5000,#2")
#define BSET_PA_ODR_BIT2()    __asm__("BSET 0x5000,#2")
#define BRES_PA_ODR_BIT2()    __asm__("BRES 0x5000,#2")

Abban biztos vagyok, hogy ennél gyorsabbat nehéz lenne írni. Viszont nem hordozható, szerintem még a családon belül sem feltétlenül.

* Én egy indián vagyok. Minden indián hazudik.

kicsit off: de mit takar a csipes processzor kifejezes ebben a contextusban?

A bitbang azt jelenti, hogy egy hardver funkciót szoftverből valósítasz meg.

A topicban leírt feledatot pl. spi-vel is megoldhatnád, de itt a szoftver megoldás nevezhető bitbang-nek. Ugyanez, ha i2c kommunikációt szoftverelsz az arra alkalmas hardver nélkül. Az néha olyan is. ;)

Apropó, egyetlen IC: minap jött szembe egy aranyos téma, amikor vettem egy PocketBeagle-t és az áramkörére kerestem.

Itt a fotón egy Rpi4-re raktam összehasonlításképpen: http://hg2ecz.ham.hu/forumkep/pocketbeagle.jpg
Itt van eleje, hátulja. Alig van az IC tok körül alkatrész: https://www.14core.com/wp-content/uploads/2017/09/PocketBeagle-Pinout-D…

És akkor lássuk magát az IC tokot, mit rejt magában: https://linuxgizmos.com/files/octavo_osd335xsm_detail.jpg

Jól néz ki és az ára sem rossz (Farnell). De momentán nem tudom mire is tudnám használni.

A Raspberry Pi -vel építettem 48V -os POE kamerát (csak 5M pixel) - sajnos a BME280 -al valami baj van mert már hónapok óta csak 100% lát.

WiFi gondolom van benne akkor egy erősebb ESP32? - azért ahhoz drága.

* Én egy indián vagyok. Minden indián hazudik.

Csak külön írtad, ez csapta ki a biztosítékot. Ez is egy szleng. ;)

A gyártók is évszámtól függően másképp nevezik. Nekem mindegyik processzor. :)

Akkor nem kell ennyit hablatyolni:

Az Intel 80186 egy 1982-ben megjelent mikroprocesszor és mikrokontroller. Felépítése az Intel 8086 processzoron alapul, ...

Most akkor ló vagy tetű?

Nem teljesen ertem, hogy miert kell 1ms-enkent LED-es kijelzot frissiteni. Fogod, mersz 1kHz-el (ha erre van szukseg a felhasznalashoz), esetleg ezeket is atlagolhatod/szurheted, ha mondjuk zajos dolgot mersz ADC-vel. Aztan amikor az ertek valtozik, akkor frissited a kijelzodet. Meg ekkor is erdemes lehet egy korlatot adni ra (ha t idon belul jon friss adat, azt ne jelezze ki), kulonben nehezkes leolvasni (volt valami repulos tortenet, amikor a digitalis kijelzo tul gyorsan porgott, es nem tudtak leolvasni rola).

Erre a celra az olvashatosag es a hordozhatosag fontosabb szerintem. Majd a C fordito megoldja, hogy vallalhato sebesseggel fusson, ha nem, az sem baj. Ahol pedig szamit a sebesseg (mert olyan az adatmennyiseg, pl. SD kartyat irsz/olvasol), oda ugyis olyan mikrokontrollert teszel, amiben van hardware-es SPI. Azert az nem egy urtechnika, talan a legegyszerubb protokoll, eleg hasznalhato is, es ennek megfeleloen szeretik beepiteni az eszkozokbe. Igazabol bajban lennek, ha olyan mikrokontrollert kene mondanom fejbol, amiben nincsen (attiny vonalon talan a 6 labuak lehetnek ilyenek, de mar a 13A-ban is van). (AVR8-at, meg kis ARM-ot hasznaltam eddig, utobbival inkabb csak jatszottam.. ill. Arduinon az egeszet eltakarja a shiftOut)

A strange game. The only winning move is not to play. How about a nice game of chess?

Elszomorítasz, ennyire érthetetlen amit írok? 2x4 digites 7 szegmenses kijelzőt kell vezérelni 74HC164 shift regiszterek segítségével, amiben nincs output latch, vagyis amíg shiftelsz az is látszik. Ugyanakkor olyan sebességgel kell írni, hogy folyamatosan láthatóak legyenek (min. 20ms az ököl szabály szerint).
A követekező, hogy miért nem használok valamilyen korrektebb IC -t (74HC595, MAX7219 stb.) - mert ez van a NYÁK -on, nem találtam olyat ami a 2 db 4 digites kijelző egymás alatt van csak ami egy sorban.

Az STM8S103 -ban is van SPI, de nem akarnám ilyen "alantas" feladatokra lehasználni. Most az ina226 a cél, de lehet akövetkező valami még komolyabb, ahol tényleg az SPI az egyedüli megoldás.

Feljebb láthatod, ez a bit bang 100us alatt lefut. Egyelőre kielégítőnek ítélem.

* Én egy indián vagyok. Minden indián hazudik.

Oke, az output latch-re nem figyeltem. Eddig 595-ost hasznaltam hasonlo esetben, ott nem volt ilyen problema. Azt akar kezzel is shiftelhetned, ha prellmentes a nyomogombod.

Az SPI-nal szokott lenni egy - tipikusan negativ - chip select, amig az a lab inaktiv, figyelmen kivul hagyja amit kap. Szoval ha van 3 SPI-os eszkozod, kulon labakra kotott CS-sel nyugodtan tudod hasznalni, nem tudod alantas dologra "lehasznalni" (1-1 lab kell eszkozonkent alapbol, de persze megoldhato maskepp). Mondjuk a 164-es ebbol a szempontbol is buta, de legkozelebb ha ilyen kell, majd legfeljebb 595-ot tervezel az eszkozbe, es ennyi.

A strange game. The only winning move is not to play. How about a nice game of chess?

Ráadásul nincs kivezetve chip select -ként használható láb (pedig lenne). Megnéztem, a 595 -ös nem láb kompatibilis a 164 -el, de a kereskedők sokszor így "specifikálják". (A Farnell szerint az 595 fele annyiba kerül mint a 164 -es, gondolom elavult nem is igen gyártják)

* Én egy indián vagyok. Minden indián hazudik.

A 2x4*8=64 bit és 4 szó. Egy bit=(2+1+1+1)*64+2*4=328Cy, ami 16MHz esetén 20,5 us.

Van egy műszerem, amelynek 4Hz a frissítése. Mit mondjak, elég idegesítő. Ezért itt legyen 2Hz=500ms.

A 8 digit adatai legyenek a w0..w3 változókba.

Ha új adatot írsz a w#-be, akkor beállítasz egy frissíteni_köll flag-et.  ;)

Csinálsz egy 500ms periódus időzítőt az 1ms interruptba.

Ha lejárt, akkor megnézed a frissíteni_köll értékét, és elzavarod a shiftelést, ha köll.

Ha látod a 0,0041%-os kitöltésű frissítést, akkor megnyerted a Titanic őrmatróza állást. :-D

Ha ez kész, akkor rátérhetünk a 4-4 digit külön frissítésére és a fényerőszabályzásra, ha köll. ;)

A shiftelést ennek az utolsó fejezete alapján készítheted el. Vigyázz, mert az lda helyett ldw (és a w0..w3) kell.

A rept direktívát helyettesítheted kopipészt utasítással. ;)

KORREKCIÓ! Nem 100us csak 10us !!!

(Nagyon várom az új munkaszemüvegem)

A kijelzett érték frissítése, nem a digitek/szegmensek multiplexeléséről szól. A multiplexelés sebessége azért érdekes, mert a mostani egy 1digit/ms shiftelés 10us és homályban látni hogy az összes digit és szegmens kicsit "parázslik". Lehet, ha 1dgit/2ms van kinn (a shift regiszteren) akkor ez javul, az elvi határ, hogy a 8 digitnek 20ms alatt kell felfrissíülnie.

Az ina226 delta-szigma, így olyan eszement sebességet nem tud, de "belül" tud pl. átlagolni. Én olyan másodpercenként legfeljebb háromszor frissíteném a kijelzett értéket (első lépésben elég az 500ms)

OFF: Megint egy kis elektronika. Nekem azok a műszerek tetszenek amik a számok alatt egy vizsszintes csíkon megjelenítik a "pillanatnyi" nem átlagolt értéket. Ha a nem egyenáramot mérsz, mondjuk gerjed a mért készülék vagy a táp akkor ez a csík jelzi, hogy valami nem stimmel. Másként lehet észre sem veszed (ilyen szempontból a régi Depree rendszerű műszerek jobbak voltak). Egyébként egy olyan projekt is "motoszkál" a fejembe, hogy váltóáramú verziót is lehetne ilyenből készíteni, persze a váltóáram az egyszerűbb mikrokontrollerekkel pár száz Hz lehet legfeljebb (de mérhetne true rms -t vagy cos Fi -t). Érdekes lenne egy olyan verzió is ami "biztosíték" -ként is működhetne, beállítható árammal és feszültséggel.

* Én egy indián vagyok. Minden indián hazudik.

egy 1digit/ms shiftelés 10us és homályban látni hogy az összes digit és szegmens kicsit "parázslik"

Na, most konkrét leszek: Honnan szedted ezt a baromságot?!

Hát azért parázslik, mert az 1 ms szünet alatt fals érték van rajta.

Tényleg, ha meglesz a szemüveged, olvasd el mit írtam feljebb!

gerjed a mért készülék vagy a táp

És zaj is lehet rajta. Éppen ezért soha nem mérjük belövés közben kéziműszerrel.

Erre való a szkóp.

a váltóáram az egyszerűbb mikrokontrollerekkel pár száz Hz lehet

A PIC16-PIC18 ADC elméletileg 50.000 sample/s, a valóságban csak 30.000. Ezzel szürés nélkül 3-5kHz frekvenciát lehet mérni.

Az STM8 enné egy nagyságrenddel gyorsabb. Más kérdés, hogy van-e idő a feldolgozásra.

mérhetne true rms -t vagy cos Fi -t

Erre léteznek céláramkörök: teljesítménymérő. A linkelt típus elavult, de érdemes az adatlapját megnézni, hasonlót keresni.

"Az STM8 enné egy nagyságrenddel gyorsabb. Más kérdés, hogy van-e idő a feldolgozásra."

Na a kétledes villogó és hasonló faék egyszerű feladaton túl ezért tértem át 32 bitesre több projektnél.
   - van RAM ... akár 256 kB-ig, flash akár 2 MB-ig. Lényeg hogy kiértékeléshez tudsz tárolni mintákat.
   - amikor a lassabbja is kb. 80 millió 32 bites utasítást hajt végre másodpercenként, nem érzed szűkösnek a kapacitását.
   - ARM Cortex M3 olcsó, de csak integeres, az algoritmusokban célszerű a float-ot kerülni. Ahova kell gyors float, oda az ARM Cortex M4-ben van floating point. Az ARM Cortex M7-ben double is van hardverből. De PIC32-vel is volt fizetős melóm, ez utóbbi MIPS32 architektúra, szintén kellemes a 8 bites korlátai után.

Ez egy kicsit más világ.

Én kicsi műszereket készítek, amelyek USB csatlakozáson keresztül küldik az adatot a Windows alapú szoftvernek.

- Kell az 5V, mert ilyen nyomás és árammérőt használunk - nincs is más, ami megfelelő lenne

- Kell a RAM, ezért már eldőlt, hogy csak a PIC18F24K50 jöhet szóba. (2k) Ez tulajdonképpen egy modern 2550.

- Szívesen programoznék 16 bitest is, de az USB verzió 3,3V-os és drágább a 8 bitesnél.

- Asseblerben még nem sikerült megtöltenem a 16k flasht, de megszorulnék, van a 24k-s 25K50 is.

- A szenzorok felbontása, pontossága és (a használt) határfrekvenciája miatt elegendő a tudása.

- A 64000B/s adatátviteli sebesség is mindig elég volt.

Az int16 kezeléséhez van pár makróm, van usb driver, i2c metódus az új eszközök gyors illesztéséhez, AES256, 32 tapos FIR filter stb. A szoftveres helyett néha én végzem a feldolgozást is. Mert gyorsabb vagyok, mint a Core i7 C#-ban, vagy hamarabb elkészülök vele, mintsem megértené mit kell csinálni. :-D

Igen, az 5V-os rendszer az egy fontos érv. A 8 bites mikrovezérlők után már a 3,3V-os logika következik de az iménti okok miatt gyakran 5V I/O toleranciával.
Egyébként árban már drágább a normálisabb 8 bites a nála sokkal többet tudó belépő szintű 32 bitesnél:

   https://www.tme.eu/hu/details/pic18f24k50-i_so/8-bit-pic-csalad/microch… --> 12 millió 8 bites integeres utasítás/másodperc
   https://www.tme.eu/hu/details/stm32f042f4p6/st-mikrovezerlok/stmicroele… --> 48 millió 32 bites intergeres utasítás/másodperc
   https://www.tme.eu/hu/details/32mm0128gpm048-ipt/32-bit-pic32-csalad/mi… --> 25 millió 32 bites intergeres utasítás/másodperc
   https://www.tme.eu/hu/details/samd11c14a-ssut/32-bit-arm-csalad/microch… --> 48 millió 32 bites intergeres utasítás/másodperc
   https://www.tme.eu/hu/details/samd21g17a-au/32-bit-arm-csalad/microchip… --> 48 millió 32 bites intergeres utasítás/másodperc
 
Így amennyit nyersz assembly-ben való utolsó utasítás optimalizálással, ennél többet nyersz architektúraváltással és tisztán C-ben. És még a mikrovezérlő darabára is olcsóbb.
Ezért a legegyszerűbb, körülbelül 2 LED-es villogó szintű feladatnál nagyobb feladatoknál én már nem részesítem előnyben a 8 bites történelmi darabokat.

Én mondhatni dacból (és konformizmusból) folytatom az STM8 tanulását, használatát.
Nem akarok itt megrekedni. A következő az STM32F030R8 lesz ami helyből 48MHz és 8K RAM Cortex M0 gyári DISCO lappal.
(De az F030 -ban van SSOP20 verzió is)

Sejtem, ez megint hit kérdése de miért a PIC?
Drágább a csip és a fejlesztő környezet is fizetős (bár nem panaszkodnak rá annyit mint a Cube MX és Cube IDE kombóra).

Van egy kis játék "Logic Analyzerem" ami elvileg tud 40 MSPS (tán egy csatornán?) annak a lelke is egy PIC.

 

* Én egy indián vagyok. Minden indián hazudik.

PIC (Microchip fejlesztés) a lelke, vagy MIPS? Ugyais a PIC32-nél a 32 bites architektúra kifejlesztését szerencsére nem vállalta a Microchip, inkább beszerzett MIPS32 IP-ket és azt gyártja PIC32m[xz] fantázianévem.
Egyébként azok is szeretnivalóak, gyorsak és van RAM bőven, amikor valamit statisztikázni kell. A GCC-vel viszont gonoszkodnak, a -O2-t csak megvásárlás után engedélyezik. A -O2 pedig nálam alap.

Ezeknél (MIPS. ARM Cortex M3) megy ilyen hogy 64bit += 32bit * 32bit, ami 24 bites számokkal tök jól használható. Szóval ezt sem kell rengeteg utasításból összeraknia. Sőt ha a feladathoz kell, az PIC32MZ szériában már van hardver floating point unitot tartalmazó is, ahogy ARM Cortex M4 és M7 családok esetén is.

Vagyis akkor a 32 bites PIC sorozatnak semmi köze az eredeti 8 bites PIC -hez. Így inkább a MIPS -et kellene hasonlítgatni mondjuk az ARM -al (ami most a legelterjedtebbnek tűnik).

Talán úgy lehet megfogni, hogy mit építenek köré, ill. mennyi flash és sram.

* Én egy indián vagyok. Minden indián hazudik.

> Talán úgy lehet megfogni, hogy mit építenek köré

Ez a kulcskérdés! Másik topikban volt szó arról, hogy mennyi mindent meg lehet valósítani hardverrel, és nem kell "lekódolni", ha jól választ az ember a feladathoz kontrollert. Egy feladatról kiderül, hogy sokkal kevesebb CPU igénye van, mint bitbanggel - vagy akár nincs is CPU igénye, csak fel kell programozni a hardvert.

Például az AVR új 8 bites sorozatában vannak ilyen egyszerű programozható hardverek a megszokott perifériák mellé. Érdekes, hogy bevállalták egy új 8 bites processzor fejlesztését CURRENT_YEAR (oké, jópár éve kezdték, de már jócskán a 32 bites ARM-ek korában). Miért van (lesz) ennek piaca? Azért, mert a mikrovezérlős projektek legnagyobb része egyáltalán nem processzor-korlátos. Én többnyire csak hobbista vagyok, de eddig nagyon kevés olyan projektbe futottam bele (beleértve az elképzelt soha meg nem valósult projekteket is), amihez szükséges volna nagyobb számítási kapacitás. Gondolom aki SDR-rel (Software Defined Radio) foglalkozik, annak máshogy jön ez ki, meg még van pár terület ahol kell a számítási kapacitás, de nem ez a gyakori.

Ahogy bucko is írta, az áramkör árának a nagyobb része nem az MCU lesz, hanem a kiegészítő áramkörök, emiatt is, ha egy processzor közvetlen használható (5V ugye), akkor az nagyobb érték lehet összességében, és a minimális árkülönbség nem is számít. Ráadásul a kisebb 8 bitesek nagyon olcsók is.

Vagy aki az Arduino lib keretei között marad és kb 100 órajelbe kerül neki egyetlen lábat high-ból low-ba állítani, annak is hamar kevés lehet az órajel. De valójában a perifériák helyes kezelésével és normális programozással általában 10-100-1000x gyorsabbat lehet az Arduinonál írni ugyanarra a processzorra, és kiderül, hogy nem is az MCU a lassú.

Csak tájékozódás, felcsaptam a Farnell -t és látszik, hogy az STM8S és az STM32F sorozatok ára nagyjából azonos (a kis tssop20 tokozásúak ck. 500 HUF/db). Viszont az STM32F sorozat programozása jóval macerásabb mint a régi kis 8 biteseké.

Az ARM processzorok körbe építettsége vetekszik a PC alaplapokkal (nem sebességben csak összetevőkben pl. DMA).

Ami az Arduino -t illeti arra nyújtana megoldást, hogy nem túl képzett emberek barkácsoljanak, legyen sikerélményük. Nekünk az a sikerélmény amikor a kód minősége megfelelő nekik az hogy működik (nekünk ez az alap). Én is belenéztem az AVR -be (nem mentem sokáig) egyrészt a kész minimál panelek drágábbak mint az STM alapúak (a chipek nem mutatnak ekkora különbséget sőt, ATMega8 SSOP 286 HUF/db), másrészt a risc nálam nem pozitívum. (Az ATMEL akkor jött nekem elő, amikor elsőként gyártott flash -el integrált '51 -ket).

* Én egy indián vagyok. Minden indián hazudik.

Pont a szószátyár assembly miatt - talán emlékszel volt olyan makró gyűjtemény ami valamelyik risc proci (lehet hogy pic) utasítás készletét "egészítette ki" '51 -re. Kisregényt kell írni a legegyszerűbb(nek tűnő) műveletekhez is.

Mind C -ben mind assembly -ben arra szoktam törekedni hogy egy oldalon legyen kerek az eljárás, persze ez nem mindig lehetséges és a cél nem szentesíti az eszközt.

* Én egy indián vagyok. Minden indián hazudik.

Ez egy részleges hardver emulátor - nagyon rossz példa. Mert ugye a "legegyszerűbbnek tűnő művelet", amit az egyik hardver valósít meg, teljesen másképp működik a másik hardveren. Idézem magam:

Biztosan emlegettem valahol, ha a firmware-be "szoftvert" akarok írni, akkor megírom és tesztelem awk-ba. Aztán a kódot beemelem kommentként és kitöltöm asm utasításokkal. Ha jól dolgoztam, alig lesz hosszabb.

Az awk az assemblerhez képest egy "roppant magasszintű nyelv". Akkor hogy lehetséges ez? A risc utasítások nagyon hatékonyak, de a nagyobb processzorokhoz képest (a nagyon kicsik) kevés címzési módjuk van. Viszont kis memórián sokkal rövidebb és gyorsabb program lesz az eredmény.

A sokregiszteres, memóriába mutató SP, stb. processzorokon jól fut a C. Ha ezt egy kis PIC-re implementálod, akkor kínosan bonyolult lesz a program és zabálja a memóriát. Ez a szoftveresen emulált stack egy olyan processzoron, ahol nincs SP, BP, FP, és STACK (!) tehát nem a "magasszintű nyelvek" futtatására találták ki. A PIC18-nak van egy extended módja, amikor indexelt címzést és néhány egyéb turpisságot is megengedhetsz, de a kisméretű vezérlőprogramokhoz ez inkább káros. Ilyenkor pont azok a fícsörök tűnnek el, amitől ez a processzor jó. Ez az ára a C-nek.

A risc itt azt jelenti, hogy a kevés regiszter (1db: W munkaregiszter, azaz akkumulátor - és kész) mellett szinte minden utasításban címezhetsz memóriát is. Ennek súlyos ára van: Hogy beférjen az utasításba a megcímzendő objektum címe, ahhoz a címnek rövidnek kell lennie. Tehát nem tudod az egész memóriát megcímezni, csak azt a szegmenst, amire a BSR (bank select register) mutat. Ezzel pedig egy csapásra sok regisztered támadt. A W mindent, a többi majdnem mindent tud. ( A 8080 egy ilyet tudott: M, amit a [HL] címzett.)

A fordító nem mindig tudja megállapítani melyik bankot használod, és sok esetben utasíttássá alakul az, hogy kiválaszd a megfelelő bankot. Kifejlesztettem egy olyat, amikor csak egy bankot használok (meg egy másiknak egy részét, mert PIC18-on van egy 0x60 méretű ún. acces tartomány), de a fordító nem szerette. Szerencsére itt a fórumon összefutottam Molnár Karcsival - a gputils utolsó kezelőjével, aki némi nyomás hatására migcsinálta az ASSUME direktívát. Ezt használva a fordító nem hányja a hibákat és nem illeszt be felesleges utasításokat.

Már csak a REPT/IRP/IRPC direktíva kellene...

A következő az STM32F030R8 lesz ami helyből 48MHz és 8K RAM Cortex M0 gyári DISCO lappal.

Sot, meg az STM32F042x-bol is van SSOP20-as verzio is! Egyebkent jaja, ezt a sorozatot (STM32F...) ajanlom, halas joszagok. Van par apro dolog ami idegesito benne de meg lehet szokni (I2C kozepesen agyremes, nehany regiszter 32 bitesnek van deklaralva de 8 biteskent is cimezheto es akkor kezd el igazan jol viselkedni, a flash page-k kicsit nagyok, stbstb...).

A Nucleo-sorozatu development board-ban az a jo hogy az ST-Link programozon felul van benne egy virtualis soros port is, ami kozvetlenul ossze van kotve az MCU-val, igy mar rogton alapszintu interaktiv kommunikaciot (debug konzol, pl) is tudsz csinalni fejlesztes kozben, mindenfele kulso egyeb bizgentyu nelkul is. 

Hát idegesítő dolog, az az STM8 -ban is van (pl. már az uart -nál beleszaladtam, hogy nem mindegy melyik regiszterrel kezded az inicializációt, sokat szívtam vele). Az i2c itt sem "sima liba", ez a nem mindegy hogy hány bájtot akarok levenni roppant zavaros. Egyébként az összes alapvető dokumentációjuk kicsit zagyva, könnyen félreértelmezhető.

Arról a virtuális soros portról tudsz valami leírást? - "Useer manual" -ban szó nincs róla.

Ha már itt tartunk milyen IDE -t használsz az STM -hez?

* Én egy indián vagyok. Minden indián hazudik.

ez a nem mindegy hogy hány bájtot akarok levenni roppant zavaros

Na, igen, az stm32f is akkor orokolte ezt a csodat ;) De igen, az egy altalanos tapasztalat hogy mig az UART, SPI, CAN interface-eket meglepoen egyesegesen es hasonloan kezeli le minden gyarto minden periferiaja es a kapcsolodo regiszterkeszlete, addig az I2C az mindenhol mas es mindenhol agyfaszos. Pedig azert _annyira_ nem kene ordongossegnek lenne. Meg a slave oldalon sem, foleg ha hardveresen a clock stretching is ott van mint lehetoseg. 

Arról a virtuális soros portról tudsz valami leírást? - "Useer manual" -ban szó nincs róla.

Nezd meg (pl) a UM1724-et. Irja is hogy van es a kapcs rajzbol (de gondolom a doksibol is) kiderul hogy a PA2 ill PA3-ba koti be. Ami pl az STM32F072-esen az USART2, alternate function: 1. Teljesen szuperul megy.

Ha már itt tartunk milyen IDE -t használsz az STM -hez?

Semmilyet, teljesen bare metal modon megy a programozas. Azaz sima debian alatti gcc-arm-none-eabi, binutils-arm-none-eabi, libnewlib-arm-none-eabi, libstdc++-arm-none-eabi-newlib csomagok, az STM altal adott hivatalos periferia-headerek (stm32f0xx.h), CMSIS headerek (core_cm0.h), es az adott mikrokontrollerhez illesztett linker script. Ezutobbi az egyetlen "specifikus" dolog, de ha sima programot akarsz beletolteni akkor csak ket szamot kell beleirnod (flash ill. RAM meret), a gyari peldak is olyanok hogy ezt a ket sort megadod, majd a tobbi *.ld-t include-olja. Ettol fuggetlenul hasznos ha ismerjuk ezutobbit is mert itt mar kezzel kell felosztanod a flash-t ha pl bootloader-t is akarsz magadnak, vagy ha a flash bizonyos teruleteit konfiguracios memorianak is hasznalod. 

Engem az STM32 BOOT ROM-ja fogott még meg. Boot0 lábat felhúzod, RESET és UART-ról felflash-eled (stm32flash). Ha kész, akkor Boot0 vissza, RESET és fut a kódod.
Így könnyen rárakható Raspberry-re vagy egyéb SBC-re az üres mikrovezérlő is, hiszen UART + 2 db GPIO és a Raspberry-be SSH-zva távolról átflash-elhető a rajta csücsülő mikrovezérlő.
Egyébként a Raspberryvel SPI-n keresztül legalább 31 Mbps tempóval képes adatot cserélni. Innentől amolyan Beaglebone PRU érzés. :)

A szövegszerkesztő lehet a kedvenced, nem kell valami ismeretlen, faramuci izével bíbelődni, illetve a fordítás a jó öreg make.
Tetszik Azért látom a CMSIS -t érdemes használni (az stm8 -ra már nem tudom hanyadik header -be futottam bele, nem halálos, de zavarba ejtő tud lenni, így a kis projektjeimhez mindig hozzá csapom a használt header fájlt).

Debug?
Tudom, jó sokáig meg van az ember nélküle, valamiféle műszerezettséggel, de az adott hiszen nem csak egy prci lóg a levegőben. A CubeMX és CubeIDE -röl sok jót nem hallok, azon túl hogy ingyenes.

* Én egy indián vagyok. Minden indián hazudik.

Debug: furi és sokat gondolkozom ezen, hogy miért, de nekem nem jött be C-nél a low level debugger, helyette a kérdéses részeknél debugoláskor telirakom print-ekkel és küldöm a képernyőre / UART-ra a részeredményeket. Ha pedig rendben, akkor //#define DEBUG_XY ... és a #ifdef DEBUG_XY -oknál nem fordulnak már bele a debug részek a kódjaimba.

Debuggert használsz?

OpenOCD-n keresztul programzom, plusz az jo interaktiv(abb) debuggolasra is. Programozonak meg ST-Link leginkabb, az a legegyszerubb. De hasznaltam mar bitbanges SWD drivert is (raspberry pi-n), ill epp most epul egy FT4232-es alapu beepitett programozo is (azaz a board-on az MCU mellett van egy FT4232-es is, es annak az egyik MPSSE/SPI-csatornaja van rakotve az SWDIO/SWCLK-ra. Ezeket (mmint ST-Link, bitbang ill FT[24]232 MPSSE) mind tamogatja nativan az OpenOCD, vannak hozza egyszeru konfiguracios szkriptek. 

Debuggolasra meg mindig van egy darab led minden board-unkon legalabb :)

Milyen felállás?

Itt mire gondolsz? :) Programozo? Ld. fentebb. 

Pont leírtad a felállást. ST-Link, OpenOCD. Viszont, ami hibádzik, hogy milyen szövegszerkesztőt/IDE -t használsz, hol jelenik meg a debug információ? Elvileg ezek több break pointot is tudnak meg ki tudja még mit. Ha jól be is konfigurálom nem tudom mit kellene látnom.

OFF: Anno, részben azért hagytam fel az mcu programozással, mert nagyon eszköztelenek voltunk (csorgattuk a nyálunk a sok milliós árú in-ciruit emulátorokra). A PC -n bármikor megállíthatod a programot és akár trace -hetsz is. Az mcu -val ilyet nem nagyon tudsz megtenni. Régen a "legfejlettebb" technológia az eprom volt - folyamatosan ment a törlő. Ha lehetett építettünk rom emulátort, vagy szintén jó drágán pigy-back kivitelű mcu -kat (pl. Dallas) használtunk.
Most azért más a világ, egy új verzió beégetése <10sec és már látod mi van. Szeretnék a PC környezethez közelebb álló rendszert mcu -ra. Pl. lejjebb írom, hogy, megy a blinkelés de 8 bites számlálóval kicsit gyorsabb mint szeretném, csináltam 16 bites veriziót, de nem jó, nem úgy működik ahogy kéne és nem tudok rájönni miért.

* Én egy indián vagyok. Minden indián hazudik.

Pont leírtad a felállást. ST-Link, OpenOCD. Viszont, ami hibádzik, hogy milyen szövegszerkesztőt/IDE -t használsz, hol jelenik meg a debug információ? 

Sima mcedit :) (lasd: "munkaeszkoz" definicioja). Ugyanakkor az OpenOCD tud olyat hogy gdb-hez kulso frontendkent csatlakozik, igy gdb-n keresztul mar el tudsz helyezni breakpoint-okat is, amiket a forraskod sor-szamozasa alapjan is tudsz cimezni. Itten van ket vegigjatszas:

Es ha van egy egyszeru development board-od ami tartalmaz is akar egy beepitett ST-Link programozot (pl: STMFx-discovery vagy Nucleo-sorozat), akkor hajra! Anno ezeket megnezegettem, es tenyleg mint eszkozok teljesen jol hasznalhatoak.Ugyanakkor mostanabban amikor OpenOCD-vel debuggoltam akkor mar inkabb azt is "bare metal" modon csinaltam es az OpenOCD egyes sajat parancsait (mdw, mdh, mdb, ...) hasznaltam. Vagyis, ez inkabb a periferiak debugollasara es/vagy kezi uzemeltetesere jo ;) 

> Szeretnék a PC környezethez közelebb álló rendszert mcu -ra.

Na, ezért van értelme platformfüggetlen programot írni, és megcsinálni hozzá a PC szimulátort is. Én jóideje így csinálom a legkisebb példaprogramokat is. Persze pont a HW illesztést nem tudod ezzel tesztelni, de minden mást igen, és akkor azért eléggé magabiztos lehetsz, hogy a HW-en is éppen úgy fog működni.

Úgy szoktam csinálni, hogy ha a programomnak vannak real time komponensei, ezeket interruptokból valósítom meg. A többit pedig egy main loop-ban, amit szépen leválasztok egy HAL-lal. A kulcskérdés mindig az, hogy melyik ponton vágja el az ember az absztrakciót: ha túl részletes ponton, akkor bonyolult lesz a szimulátor. Ha meg túl absztrakt ponton, akkor túl sok mindent nem tudsz PC-n kimérni.

Ez az amit Buckó kritizált, hogy szerinte felesleges, de szerintem nyúlfarknyinál nagyobb programok esetén megéri.

(Kivétel, amikor nem működött a módszer: például egyszer egy kasztolás hibát elég sokáig kerestem, de ha betartottam volna a MISRA szabályait, akkor nem lett volna ilyen. És ezt statikus ellenőrzővel ki lehet kényszeríteni.)

Ez például egy mikrovezérlőre írott hasonló projekt: egy eszterga szánjaira szerelt mérőlécek értékeit jelzi ki - HTML oldalba ágyazva a mikrovezérlő programot: https://rizsi.com/programs/eszterga/emscripten/lathe.html

A kijelzés minden részletét - a konkrét kishiftelésen kívül - egy böngészőben is tudom tesztelni. Régebben standalone programokat csináltam (Java-ban), ez az első webes megjelenítésű mikrovezérlőre szánt programom, de egyből beleszerettem a technológiába: emscripten-nel fordítom a program HW független részét, a HAL pedig egy JS-hez kapcsolódó illesztő. Ezen a HAL-on keresztül adom át a JS-nek a program belső állapotait, és eszerint vannak frissítve a szimulált hétszegmenses kijelzők. Hasonlóan a gombok is így vannak megoldva, illetve a szánok inputjai is a HTML csúszkáról.

A kvadratúra számlálót ASM-ben írtam meg, és zavart, hogy nem tudom PC-n tesztelni. Poénból csináltam egy Assembler szimulátort ehhez a projekthez, amiben tudtam regressziós teszteket csinálni. Itt vannak: https://rizsi.com/programs/eszterga/quad_decoder_attiny25_custom/

sim_gen.cpp : az program binárisa visszafejtve és abból egy C program generálva. (A visszafejtő+generátor Java-ban van, és azt nem tettem elérhetővé.)

AVR_simulator.cpp : ebben van a processzor szimulálása.

AVR_debugger.cpp : ebben vannak a tesztesetek a futtatókörnyezettel együtt. Tehát formailag nem ilyen Unit tesztek, de lényegében úgy fut mintha az lenne.

quad_decoder.asm : ez maga az ASM program, erről írtam blogposztot is régebben, ezt teszteli a cucc.

Ha már így megemlítettél... ;)

Tudok ám én is C-ben programozni! Sőt, 2 évet C++/Windows környezetben is dolgoztam. A C múlt meghatározó eleme a 19 év POWER*/AIX/xlc. Ott voltak egyszerű programok, de nagymennyiségű adatot feldolgozó és javító dolgok nagyobb mennyiségben. Volt debugger is, de kifejezetten hasonló módszert használtam, mint hg2ecz: print. Ez éppen olyan gazdaságos megoldás, mint a profi logiai analizátor + 60-70 csipesz felrakása utáni nemértemnemértem helyett maximum egy logic pent vagy 100uA szovjet mutatós műszert használni debuggerként. Vagy egy kicsit gondolkodni és máris megvan a hiba. ;) Mindez annak ellenére, hogy 8085-höz olyan programkövetőnk volt, hogy a 4 órajelből álló utasítás bármelyik fázisát "ki tudtuk merevíteni".

Ennek az eljárásmódnak két ütős magyarázata van.

A profi szoftveres megtervezi a programot, a vázat és elkészül a main(). Majd megírja a függvényeket is hozzá. A hardveres megtervezi és összerakja a hardvert és kipróbálja az egyes elemeket. (Nem mindig volt minden egyetlen mcu-ban!) Gyakorlatilag először készülnek el a "függvények" és csak utána integrálódnak az egységbe. Tehát a hardveres mindig "alulról építkezik".

Idestova 35 éve "valamit működtető" programokat írok. Példaként lézernyomtató (bár annak a programját nem én terveztem), cdrom, kötőgép ;) ... vagy 150 klienses backup rendszer. A technológia minden esetben végesállapotú gép. Az ilyet nagyon egyszerű programozni, mert csak meg kell tervezni az események hatására végrehajtandó akciókat és állapotváltozásokat. A program egyes elemei (az akciók) rövidek, könnyen érthetőek és vizsgálhatóak. Az egész programrendszer önzáró és atombiztos. A debugger szart sem ér, mert lehetetlen olyan rendszert követni, ami egyszerre 150 folyamat-sorozatot futtat, vagy 13 interruptot + néhány változó időzítést kezel. (Egy példa a cdrom vezérlő program. A főprogram ellenőrizte, hogy megnyomták-e  a tálcanyitó gombot, jött-e újabb parancs és loop. A többi interrupt.)

Az utóbbi 13 interruptos példa egy olyan műszer, ahol egy négyhengeres motoron mérünk néhány jellemzőt. Közben nem árt a grafikonokra rápöttyözni, hogy hol volt a gyújtás, ezért megy négy vezeték a gyújtótrafókra is. A zavar is jön ezért célszerű a fordulatokra szinkronizálni és süketíteni azokat a csatornákatt, amit éppen nem vizsgálunk. Közben a mérést végző meg húzogatja a gázt. :( A program ezt úgy ellensúlyozza, hogy változó méretű időablakban engedélyezi csak a gyújtás vizsgálatét a következő hengeren. A gyújtássorrendet és a vezetékek sorrendjét nem tudjuk. Hogyan lehet egy ilyet debuggolni? És nem is debuggolni, hanem a helyes működést beállitani.

A PIC programozó csatlakozóján (ICSP) van az adat és órajel. Ezeket a portokat beméréskor egy T csatlakozó keresztül kötöm az analizátorra. Legyen a példa egy timer beállításának vizsgálata! Beállítom az 1ms periódusidőt és ellenőrizni szeretném, hogy nem írtam-e el valamit.

TimerInterrupt
...
#ifdef	TIMER_DEBUG
		mkPulse	1, TRIGGER
#endif	TIMER_DEBUG
...

És máris ott virít az analizátoron az 1ms periódusidejű jel. Más eseményekre több impulzust rakok ki. A futásidő mérésére a kódrészlet elején beállítom, a végén törlöm a portot. Ezzel a technikával sokkal több "töréspontot" tudok előállítani, mint amire ezek a kis processzorok képesek.

"Biztosan emlegettem valahol, ha a firmware-be "szoftvert" akarok írni, akkor megírom és tesztelem awk-ba." - Motort meg nem cipelünk a 3. emeletre. ;) A számítás ellenőrzésére betöltöm a nyers mérést a hardverbe, majd a korrekcióval kiolvasom. Ennek bitre meg kell egyeznie az awk vagy excel által számított értékekkel.

Lényegében ezenél a szerkezeteknél a hardver és a külső események valósítják meg a működést. A HAL a szerkezet önmaga, ezért felesleges lenne annak az emulációját megírni. A maradék bárhány százalék "szoftver" bármi mással tesztelhető.

Annak, hogy más hardveren kellene ugyanannak futni, abszolút semmi esélye. Két probléma mégis adódhat. Ha nem gyártják tovább a processzort esetleg át kell írni a kódot, de ez ritka és ebben az esetben létezik felülről kompatibilis új termék. A másik, ha kijavítanak valamilyen gyári hibát. :-D

Ja, és egy 9-10k méretű (risc) program nem nyúlfarknyi, pedig nem is programozok szószátyár módon.

Jó hogy eszembe juttatad a szimulátort, rossz hogy "free" nincs (gyors keresgélésre kaptam két github projektet, egyik sincs befejezve 2016/'17).

Valójában ez is sokat lendíthetne rajtam. A gondjaimat az okozza,  hogy nem mindig tudom helyesen értelmezni a dokumentációt és az SDCC assemblere nem követi az ST által javasolt jelölés módokat. Az STM8 annyiféle címzési móddal rendelkezik, hogy még van amit nem értek, és nem tudok megfelelően leírni, mert más a szintaxis (folyton böngésznem kell a leírásban szereplő kódokat és összevetni az elkészült listával).

* Én egy indián vagyok. Minden indián hazudik.

Itt kezdődik az assembler előnye. :-D

Ez nekem egy fél évembe került, amig a PIC mellett kiderítettem: a Microchip C, annak az assembler kimenete, az assembler fordítója, egyéb C fordítók és a dokumentáció más világ. Hiába a 20+ év C és 30 év assembler tapasztalat, nem tudok hatékonyan dolgozni. És még nem is említettem a mindenféle free PIC projekteket!

És jött a csoda, a gputils fordítója használható, persze csak 8 bitig.

A gyártáshoz 50-300 csipet kell egyszerre sütni. A cég >100k árú sütője frissítés után sem kezelte atermékekban használt processzort, a hozzávaló >70k árú adapter meg obsolete. A sorozatprogramozás meg kínosan lassan megy a gyártó szoftverével. És ekkor a sourceforge adta a megoldást! Egy londoni csapat felajánlotta a munkáját a Microchipnek, de nem kellett nekik. Ezért zárt forráskóddal árulták a terméküket. Vettünk egyet, majd jó két hónap levelezés és diszkrét anyázás közepette megcsinálták annyira, hogy azóta ezzel programozok.

Most akkor közzé teszem a saját hülyeségemet, nem tudok rájönni miért nem működik a kód. Annyi a feladat, hogy egy 16 bites számlálót ketyegtet majd ha nulla elvégez egy kis logikát és kész, első látásra olyan mintha 65535 -öt számolna mire eléri a nullát, holott mindig 255 -öt töltök be. Nem látom miért nem működik :(

000166 CEu00u0F         [ 2]  320 	ldw	x, _tick_bli
000169 5A               [ 2]  321 	decw	x
00016A 26 0B            [ 1]  322 	jrne	00004$
00016C C6u00u0E         [ 1]  323 	ld	a, _shft_bli
00016F C8u00u0D         [ 1]  324 	xor	a, _shft_msk
000172 C7u00u0D         [ 1]  325 	ld	_shft_msk, a
000175 BE FF            [ 2]  326 	ldw	x, 255
000177                        327 	00004$:
000177 CFu00u0F         [ 2]  328 	ldw	_tick_bli, x

Ugyanez 8 bites számlálóval úgy működik ahogy kell. Itt direkt a 255 -öt használom, ez ugye a maximum 8 biten.

0001C8 72 5Au00u0F      [ 1]  371 	dec	_tick_bli
0001CC 26 0E            [ 1]  372 	jrne	00004$
0001CE 55 00 FFu00u0F   [ 1]  373 	mov	_tick_bli, 255
0001D3 C6u00u0E         [ 1]  374 	ld	a, _shft_bli
0001D6 C8u00u0D         [ 1]  375 	xor	a, _shft_msk
0001D9 C7u00u0D         [ 1]  376 	ld	_shft_msk, a
0001DC                        377 	00004$:

* Én egy indián vagyok. Minden indián hazudik.

Na ezzel az izével sincs szerencsém, "Compilation failed"

#include <stdint.h>

#define    TICK_BLINK

uint16_t   tick_bli = TICK_BLINK;
uint8_t    shft_msk;
uint8_t    shft_bli;

--tick_bli;
if ( tick_bli == 0 )
{
    shft_bli ^= shft_msk;
    tick_bli = TICK_BLINK;
}

Szóval, C -ben 6 sor.

* Én egy indián vagyok. Minden indián hazudik.

Ott a pont! Ha valaha találkozunk tied egy korsó sör vagy egy doboz Guines.
Ráadásul, itt kivételesen a compiler követi az STM szintaxist, helyesen a sor így néz ki:

0001D8 AE 00 FF         [ 2]  379 	ldw	x, #255

(Szerencsére most nyírtam le a hajam, nem tudom kitépni)

Jó cucc ez a cimpiler explorer, de valójában a lista (ahol ott a hexa op-code) segített megtalálni a hibát.
De hogy kicsit enyhítsek magamon, a compiler nem követeli meg a "$" az shortmem/longmem címzésnél.

Viszont ez felvet nekem egy kis problémát, mihez képest long a long pointer, mire inicializálja a stack pointert a compiler. Na van itt néhány alapvető kérdés ami felett eddig simán elsiklottam.

* Én egy indián vagyok. Minden indián hazudik.

Legalább a LD utasítás 4 oldalas taglalása esetén kételkedhetnél magadban: Miért is nem szeretem a risc-et? ;)

Jó játék az explorer, de én szeretek olyan fordítót haszálni, ami önmaga elegendő minden kérdés eldöntéséhez.

Kérdésedre a válasz:

4.2  Data space
The data space is 16-Mbyte and linear. As the stack must be located in section 0 and as
data access
outside section 0/1 can be managed only with LDF instructions, frequently used
data should be located in section 0 to get the optimum code efficiency.
All data pointers are located in section 0 only.
Indexed addressing (with 16-bit index registers and long offset) allows data access over
section 0 and 1.
All the peripherals are memory mapped in the data space.

Lefordítom. A stack kezelés az első 64k-s "section" entitásban történik. Ettől lesz rövid és gyors a kód.

Ha kicsi processzoron kicsi programot írsz C-s "agyállással", akkor rögtön 3-5x lassabb lesz, a felhasznált memória meg 2x értéknél kezdődik.

Ha átadod a paramétereket a stack-en, meg a volatile is kötelező, mert úgy szép...dejszen ott van a memóriában, és a 3 regiszterben nem tudja a processzor keselni, tehát úgy is újra kell tölteni. Vagyis át sem kell adni és automatikusan volatile lesz.

Világos, a 3 regiszteres helyett lefordul a C program a 64 regiszteres processzoron is, ha szépen van megírva. A 3 regiszterest meg pont nem arra optimalizálták, amire a másikat.

Ezek a dolgok arra visznek, hogy a fordítót szolgáld ki jelentős többletmunkával, mintsem a feladatot oldanád meg az adott a processzoron. Pedig a hordozás helyett fontosabb lenne megtanulni a feladat-erőforrás-teljesítmény becslést, és ehhez a mefelelő processzor választást.

A PIC esetében ehhez még hozzájön a "core independent" perifériák fajtája és darabszáma. Az újabb fejlesztések már kihasználhatatlan mennyiségű perifériát zsúfolnak már egy 8 lábú tokba is. A perifériákat kívül-belül is összekötözheted, egy helyre többet is köthetsz. A CLC (configurable logic cell) segíségével külső aszinkron eseményeket kezelhetsz, saját logikai áramköröket rakhatsz össze. Sok esetben a szoftver helyett kialakítasz egy hardvert és működik.

Kösz a megfejtést! Ha jól látom ezt a "Programming manual" -ből szedted elő.
Azért továbbra is zavarba ejtő, amikor 12 bites cím buszt mutatnak egy olyan processzor kapcsán ami mindössze 1k RAM.
"Section 0" az alsó 64k megint bulshit, hol a 64k (ha mondjuk oda tudnék map -elni egy külső ISP RAM -ot azt mondanám OK, de így ez valami ismeretlen "jövő kép" aminek semmi köze a gyakorlati dolgokhoz). Az alap koncepció, nagyon emlékezetet a régi '51 architektúrára, ahol volt 256 bájt RAM és pussz.

Módosíthatom a kérdést, mit kell tennem azért, hogy a legpörgősebb adataimat ("volatile" pointerek és egyéb bit manipulált regiszterek) az alsó 256 bájtba kerülhjenek?

Az UART IT handleremet "tisztán" assemblerben írtam. Van ".area DATA" és ".area CODE" viszont az ".org" utasítást nem tudtam belecsűrni :( (Még jó hohgy a handshake vonalakkal nem kellett foglalkoznom)

A "a fordítót szolgáld ki jelentős többletmunkával" pontosan arról szól, hogy biztosítsa a kód hordozhatóságát, ami mint azt tisztáztuk, firmware esetében fából vaskarika. Hacsak, menet közben nem találják ki, hogy kell még valami funkció amihez nagyobb integráltságú mcu kell. Elvileg, ha maradsz a compiler által követelt konvencióknál, akkor egy mozdulattal megteheted.

Nagy szomorúság a RAM hiánya. Lehetne valami egyszerű mutli task kezelést csinálni, de 1K és benne a stack, illetve az interruptok miatt életveszély. Talán ahogy az '51 -el csináltam, ahol register bank -at négy task -ra osztottam, és nem a stacknbe tároltam le az mcu állapotokat.

A 8 lábú chipekbe belesűrített perifériák az Atmel -nél is jól láthatóak, pl. ATtiny85. Úgy látom, nem a chip de a kivezetések száma a drága.

* Én egy indián vagyok. Minden indián hazudik.

> Nagy szomorúság a RAM hiánya. Lehetne valami egyszerű mutli task kezelést csinálni, de 1K és benne a stack, illetve az interruptok miatt életveszély.

Már miért volna életveszély? Ki kell számolni, ha elfér, akkor meg lehet csinálni. Igaz, hogy csak poénból, de ATMega-ra csináltam többszálúságot, ott ha jól emlékszem nagyságrendileg 40 bájt volt szálanként az overhead (regiszterek mentése ugye), ha a stackednek csak néhány mélysége van, akkor még 1k-ba is belefér ebből akár 10 is. Elszántság kérdése. Persze valójában értelmetlen, hangsúlyozom én is poénból csináltam.

Az sdcc stack -et használ routin híváskor, priorált interrupt kezelés van, tehát több interupt is mehet egy időben (hacsak le nem tiltod), a több szál futtatásakor minden reentrant kell hogy legyen, ami általában megint stack. Szóval egy kis módosítás és máris fejbe csaptad a változóidat/buffereidet. Veszélyes.

* Én egy indián vagyok. Minden indián hazudik.

Abban a fajta multitaskban amit én csináltam, ott az van, hogy minden stacken ezek vannak:

* Saját maga, tehát annak a szálnak a main loopja, és minden amit ő hív

+ Ezek közül _valamelyik_:

* Saját regisztereinek mentése: kb 36 bájt + még az az interrupt, ami a context switch-cset csinálja

* Interruptok (level1+level2)

Ki lehet számolni/meg lehet mérni, hogy mi mennyit eszik. Ha elfér, akkor nincs veszélye. Ha nem mindig fér el, akkor valóban veszélyes, de úgy is fogalmazhatunk, hogy nem működik.

Egyébként threadeket csinálni csak akkor kell, ha olyan algoritmusod van, amit nem tudsz úgy megírni, hogy félbeszakítható legyen, és ezekből _többet kell párhuzamosan_ futtatni. (Valójában minden algoritmus átírható félbeszakíthatóra, csak van amit nehéz. Én például olyat csináltam, hogy egy template generál HTML kódot. Egy ilyen template közepérő macerás úgy kiugrani, hogy ugyanott tudd folytatni a végrehajtást, ezért csináltam hozzá multithreadet.)   Ha az algoritmusod ismétlődő taszkokra bontható, akkor jobban jársz, ha ezeket a taszkokatt hívogatod sorban és kész. Ha _csak egy_ meg nem szakítható algoritmusod van, akkor azt teheted a főprogramba, és minden más futhat interruptban. Ez még mindig elég egyszerű, nem valódi multitaszk, mert csak egy stacket kell kezelni.

Kicsit más a szemléletünk. A multitask számomra azért érdekes, mert gyűlölöm ha cpu toporog és vár valami eseményre. Az adott task függessze fel magát és adja le a cpu -t. Persze ez nem zárja ki, hogy a cpu több tucat taszkon rohangál és vár valamire.

* Én egy indián vagyok. Minden indián hazudik.

Így van ez a kis processzoroknál. ;)

Még az 512B memóriájú PIC is több esetben 24 bites pointert használ. Azaz nem kell használni, de a U:H:L bájtok közül törlöm az U-t a program elején. Bár a reset is törli, de biztos, ami biztos.

Ha belegondolsz, ez éppen a hordozhatóságot támogatja. Amint nagy memóriával rendelkező vagy külső memóriával ellátható típusra hordozod a programot, rögtön nem kell semmit tenni. (Es nem biztos, hogy csak a C-ben lehet ilyet tenni.)

Ha a fordító támogat egy processzor típust, akkor van hozzá header, ami leírja mi hol mennyi van. Ezt kell tanulmányoznod és az ott található szimbólumokkal kell dolgoznod. Bár a szitaxis miatt külön asm és C headerek lehetnek, de lényegében ugyanazt írják le.

A C-ben nincsen org, a Microchip az absolute direktívát használja helyette. Ezzel lehet megmagyarázni, hogy a cucc ugyan data, de pont hol kell elhelyezni. A header biztosan tartalmaz olyan címkét, amivel az alsó ramra hivatkozhatsz. Erre is igaz, hogy

Elvileg, ha maradsz a compiler által követelt konvencióknál, akkor egy mozdulattal megteheted.

...a nagyobb processzorra váltást.

Itt megint a C aggyal van baj. A régi Intel AS fordítóhoz tartozott linker és lokátor(!). A lefordított programmodulokat "tetszőleges helyre" lehetett linkelni, de később tetszőleges helyre (re)lokálni. Így pl. a tíz programmodulból lefordíthattad az elkészült hármat, összelinkelhetted, és a debugger automatikusan lokálta az ő munkaterületére. Aztán tesztelhetted RAM-ban egy másik helyen, majd EPROMBA égethetted megint másik címtartományokba lokálva. És ez eddig abszolút kód. Aztán jött a C, az obj és ezek a fícsörök köddé váltak... Na, ezért írok abszolút kódban mindent és kézzel "lokálok". Néhány termék után kialakul, hogy az egyes modulokat hol érdemes elhelyezni.

A multitask és a stack beszélgetnek. :-D

Azért látom, nem vagy kezdő a témában. Hasonlót csináltam nagyon-nagyon piciben a 80286 protected hívását utánozva, 8085-ön. Külső memóriával egyszerűbb volt. Készítettem egy contex regisztert, ami belülről írható-olvasható volt, kifelé pedig kicsit beavatkozot a címzésbe. A változók minden taskban ugyanott voltak, de a taskhoz rendelt memóriába íródtak. (Ez már szinte protected mód. ;)) Persze volt egy supervisor is, aminek teljesen máshol volt mindene. Na, ez tudott kezelni 4 kötőgépet (motorindítás, fékezés, sorszámlálás, lakat pozíció), egy kijelzőt és 4 terminált. A terminál 2 led és 2 nyomógombból állt. ;) Ehhez volt 384 bájt RAM, de egyáltalán nem volt kihasználva. Egy nehéz dolog volt benne, a több gépen többszörös hiba esetén a kijelző megszerzéséhez írt prioritásos handshaking. ;)

A "multitasking" az inkább operációs rendszerek alatt értelmezhető. Bár pont az előbb írtam le egy hasonlót, de az csak "ha egy szerkezetet tudok kezelni, akkor négyet is" - némi hardver támogatással.

Ha elmeséled miért vagy annyira a csúnya interruptoktól beszarva ;), akkor szívesen segítek a megértésben. A processzorodban van valami prioritás vezérlő (rutinból: reméljük műküdik), csak azt kell a legbarátibb módba kapcsolni. Aztán az interrupt ugyanolyan, mint a többi program, de legalább csak néha fut. :-D Mivel kifejezetten eseményvezérelt rendszereket írok, nálam az interrupton kívül futó dolgok mennek csodaszámba. Ha ezen túljutsz, más értelme lesz a "kéne egy kis multitasking" gondolatnak is.

A stack...amit én használok, abban 31 szintű hardver stack van. A "magasszintű nyelvek" szoftverből emulálják a függvényhívási konvencióhoz szükséges stacket. Szerintem a 6 mélységet még soha nem értem el, pedig van 2 interrupt level, és egyáltalán nem spagettikódot írok. ;)

Szinte antagonisztikus ellentéteket látok. Ezért mondják, hogy a programozás művészet.
Az én szempontjaim szerint, az irq kiszolgáló kód legyen rövid. A main egy oldalnyi init és egy kupac routin hívás egy hurokban.
A C -nek ott lehet előnye, hogy nem kell megtanulni az mnemmonicot/op-codot, de az architektúrát (milyen perifériáink is vannak)Ö akkor meg kell tanulni (és ez gyártóról gyártóra más).

OFF: Most azon tipródom hogy vissza kéne nyúlom az i2c -hez és megcsinálni az interrupt kezelést. Nagyon gusztustalan a "várunk valamire", ahelyett hogy szépen kapok egy interruptot és ledolgozom. Viszont itt nincs univerzális megoldás, muszáj chipenként újra gondolni. Találtam néhány példát a neten, de ezek mind egy-egy konkrét eszközhöz készültek, persze más mint amit én szeretnék. De az is lehet hogy össze kell rakni ver. -1 hw és tesztelni.

* Én egy indián vagyok. Minden indián hazudik.

Viszont itt nincs univerzális megoldás, muszáj chipenként újra gondolni

Egy FIFO-szeru absztrakciot az I2C fole is fel tudsz huzni relative egyszeruen. Es egy FIFO-t kenyelmesen tudsz etetni "kivulrol" es fogyaszani az interruptbol es/vagy forditva, azaz etetni az interruptbol es fogyasztani kivulrol csak ket darab szamlaloval. Es ha a szamlalo meretenel fogva atomi muvelettel kiolvashato akkor semmi mas vedelemmel (critical section, ilyesmi) nem kell torodnod. Szoval egy N elemu fifo_array[N] FIFO eseten az array[(write_ptr++)%N]=... modon eteted, az array[(read_ptr++)%N] modon fogyasztod, es ha (write_ptr%N)==(read_ptr%N), akkor epp' ures. Egyetlen dologra kell figyelned, hogy ne etetsd tul. Ha nem figyelsz erre interrupton belul akkor adatvesztesed lesz. Interrupton kivul meg nem kell mast csinalni csak varni amig lesz megfelelo mennyisegu hely. Ha N=256 es a *_ptr az uint8_t akkor szinten tudsz egyszerusiteni a dolgok meneten. 

Na ez azért szerintem erős. Való igaz, hogy a specifikációban nincs timeout,  de az eszközök időzítései, ha minden rendben van, egy egy adott sebességnek megfelelően lezajlanak a tranzakciók. Vagyis használhatsz timeout -ot, úgy hogy ha az lejár, akkor hiba van, ismételni kell vagy beavatkozni (esetleg mindaddig várni míg a busz magához tér).

Nálam is így jelentkezett néhány elírt sor, beállt az mcu. Persze attól hogy kiléptem az adott várakozó ciklusból még nem javult meg a kommunikáció, de láttam meddig jut el, hol reked meg és javítottam.

* Én egy indián vagyok. Minden indián hazudik.

Naugye. Az egyes alapeset, ha elszúrtad, akkor kijavítod. De utána nem opció a leakadás.

A többi esetre a specifikáció pontosan megadja az elvárt tevékenységet. Ilyen eset (mégis) a firmware hibájából következhet, esetleg zavar miatt fordul elő. Mindkettőt ki lehet és ki kell küszöbölni!

Az utolsó, amikor nem std eseményt kell kezelni: pl. a kliens nem válaszol.

Alaphelyzetben a start, data (8 órajel), ack, stop olyan buszmővelet-sorozat, amelyet az i2c megfelelő beállítással beavatkozás nélkül lekezel. A felsorolt műveletek közül megfelelő(ek)et interrupt alatt kezelve megvalósítható a nem std buszművelet is. Iderakom amit korábban írtam:

A probléma pl. egy EEPROM írásánál kezdődik, ha írás végét szeretnéd megállapítani. Megcímzed az eszközt és nem válaszol. (Lásd 5.1.6, Figure 9) Ugyanitt a másik anomália, ha utána nem akarsz sem írni, sem olvasni. Minkettő megoldásához nem std buszműveletet kell összerakni.

A helyes megoldás oda van rajzolva a folyamatábrába, azt kell összerakni. És akkor a start, data (8 órajel), ack, stop helyett más lesz, de azt kell csinálni. Itt pontosan az a helyzet, hogy a megcímzett eszköz elfoglalt, és a hardver nem támogatja azt, hogy eközben válaszoljon. Mintha leakadt volna. A timeout nem opció. A megadott műveletek biztosítják, hogy a buszon levő más eszköz se akadjon le.

Ez nagyon elmélet szagú, s ha aktatologató lennél, még el is hinném az érvedet. Ugyanakkor képzeljünk el egy műszert, ami i2c-n kommunikál a belsejében, majd három napra magába fordul az egyik device, ami azért feléled három nap múlva. Addig persze azon a buszon nem megy semmi. Ez a műszer így helyesen fog működni?

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Pont azért alakult ki az smbus, mert ha valaki tartósan alacsony szinten tartja bármelyik vonalat, akkor ott világvége van. Értem, hogy specifikáció, de tekinthetjük úgy, hogy kimaradt ez a doksiból.

Különben amit írsz, abból az következik, hogy tilos lenne watchdog használata, mert ha megdöglik a buszon valaki, s adott idő múlva elrántja őt a watchdog, akkor is timeout lett implementálva az i2c buszra, ami meg nem része a specifikációnak. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ja, kimaradt a doksiból néhány évtizedig, pedig már akkor megmodtad, hogy szar az egész. ;)

Éppen azért hoztam az EEPROM-os példát, hogy van olyan, amikor valamelyik eszköz nem válaszol. Maradjunk ennél a példánál! Az EEPROM írási ideje max. 5ms. Természetesen jogodban áll ezt vizsgálni és megállapítani, hogy pl. 10ms után a szerkezet beszart. Ezt nevezheted timeoutnak is, de a busz működését nem befolyásolja. Vagy tervezhetsz saját hardvert, ami 10ms után bedöglött státuszt kap. Ilyenkor a specifikációban megadottak szerint resetelni kell. Ezt a hardvert jogosan tervezted így (akár a kiakadást is beletervezhetted), és kiakadáskor pontosan úgy járhatsz el ahogyan szeretnél. De úgy is megtervezheted, hogy két nap után térjen magához.

Az smbus esetén van saját busz timeout:

Device timeout definitions and conditions
The t TIMEOUT,MIN  parameter allows a master or slave to conclude that a defective device
is holding the clock low indefinitely or a master is intentionally trying to drive devices
off the bus. It is highly recommended that a slave device release the bus (stop driving
the bus and let SMBCLK and SMBDAT float high) when it detects any single clock
held low longer than t TIMEOUT,MIN . Devices that have detected this condition must reset
their communication interface and be able to receive a new START condition in no
later than t TIMEOUT,MAX .

Az előbbi saját kialakítású hardverrel szemben az smbus korlátozottabb/más lehetőséget ad. A timeout leteltével minden eszköznek automatikusan le kell válnia a buszról. (javasolt)

A Master is allowed to abort the transaction in progress to any slave that violates the
t LOW:SEXT  or t TIMEOUT,MIN  specifications. This can be accomplished by the Master issuing a
STOP condition at the conclusion of the byte transfer in progress.

A master visszalőheti a tranzakciót, ha valaki rakoncátlankodik.

A timeout tiltható és értéke talán be is állítható.

Ezek az elemek  nincsenek az i2c buszon, de vannak az smbuszon.

Bonyi?

Bus clear
In the unlikely event where the clock (SCL) is stuck LOW, the preferential procedure is to
reset the bus using the HW reset signal if your I2C devices have HW reset inputs. If the
I2C devices do not have HW reset inputs, cycle power to the devices to activate the
mandatory internal Power-On Reset (POR) circuit.
If the data line (SDA) is stuck LOW, the master should send nine clock pulses. The device
that held the bus LOW should release it sometime within those nine clocks. If not, then
use the HW reset or cycle power to clear the bus.

és

Unresponsive slave reset
In the unlikely event where the slave becomes unresponsive (for example, determined
through external feedback, not through UFm I2C-bus), the preferential procedure is to
reset the slave by using the software reset command or the hardware reset signal. If the
slaves do not support these features, then cycle power to the devices to activate the
mandatory internal Power-On Reset (POR) circuit.

Legalábbis az NXP szerint. ;)

A 0Hz azt jelenti, hogy a timeout nem értelmezett.

Troll: Azt még a Philips specifikálta.
Minden szava igaz (bár ezt a 9 óra pulzust még nem próbáltam). Tartom magam ahhoz, hogy timeout -ot lehet és kell csinálni.

Viszont ami az előző állapot automatás elképzelést is kicsit módosítja, hiszen így előfordulhat, hogy sosem fejeződik be a művelet (nem kapunk interruptot) és megáll az élet. Valószínűleg ezt a hibát, nem az i2c interrupt handlerbében kell majd megoldani (talán a tick timer jó lehet erre).

* Én egy indián vagyok. Minden indián hazudik.

Inkább képzeld el az itt leírt áramkört!

Mondjuk 4 csatornáról felváltva olvasgatsz adatblokokat és beírod FRAM-ba. Közben néhány egyszerűbb perifériát írsz-olvasol és a kijelzőre is írogatsz. (Az utóbbir kiírhatsz stringeket is.) Ez eddig mind i2c. Van egy soros vonal is, amin beszélgetni kell. És van 512 bájt memóriád.

Ha ezt elgondolod, akkor közelebb kerülsz a megoldáshoz. ;)

Nem atomreaktort kell vezérelni, csak olyan technológiát kidolgozni ahol az mcu (amivel dolgozok) egy master és vvan egy vagy több slave és ne kelljen minden újabb eszköznél újraírni mindent.
Van egy állapot automata (valami ilyesmit próbál leírni a dokumentáció is "event" -ekkel) ami kezeli, azt hogy
- címzel, majd írsz 3 bájtot (ina226 kicímzed az egyik konfigurációs regiszterét) majd beleírsz egy 16 bites értéket.
- címzel, írsz egy bájtot (megcímzed a 16 bites áram regisztert)
- újra címzel és kiolvasod a két bájtot
- stb.

Tehát a fifo és a periféria státusz (hiba) vezérli az állapot automatát. Persze könnyebb mondani mint megcsinálni.
 

* Én egy indián vagyok. Minden indián hazudik.

...ne kelljen minden újabb eszköznél újraírni mindent.

Van egy állapot automata (valami ilyesmit próbál leírni a dokumentáció is "event" -ekkel) ami kezeli, azt hogy
- címzel, majd írsz 3 bájtot

Rossz válasz. ;)

A nagy katyvaszt az OSI-modellhez hasonlóan rétegekre kell bontani, hogy átlásd a zűrzavart. Némi rendszerezés után minden réteghez tartozhatnak bizonyos tevékenységek, amelyeket valamilyen rendszer szerint el kell végezni.

Az alábbiakban egy hozzávetőleges leírás vázlata következik pl. az ina226 kezeléséhez.

  1. fizikai réteg
    • Nem részletezem.
  2. i2c réteg
    • start condition
    • restart condition
    • stop condition
    • write address
    • write data
    • read data
    • read ack
    • stb.
  3. smbus réteg
    • write register
    • read register
    • alert kezelés (opcionális)
  4. alkalmazás réteg
    • mit csinálunk az adatokkal?
  5. felhasználói réteg
    • pl. mérés, kijezés

A 2. réteg: Az i2c busz kezelése, amihez kell a hardver specifikáció. Minden ehhez tartozó interrupt-hoz meg kell írni a hozzá tartozó akció(ka)t.

A 3. réteg: Az ina smbusz(-szerű) protokollal kommunikál. Ehhez meg kell írni az általa használt smbusz parancsokhoz szükséges akciók sorozatát. Ezeket a következő rétegből lehet hívni. *

A 4. réteg: busz kommunikáció adatait valahonnan vagy valahová kell rakosgatni.

Az 5. réteg: Végül a megszerzett adatokkal valamit kell csinálni - ez a főprogram.

A leírtakhoz képest mindig létezik egyszerűbb út, amit általában sokkal nehezebb megvalósítani. ;) Ez a felépítés lehetővé teszi még a kezdő programozónak is, hogy tyúklépésben, hiba nélkül oldja meg a feladatot. Persze nem árt még egy kis segítség: a liberó! Ennek az eszköznek a segítségével könnyedén szerkeszthetsz állapotautomatát. Ha nem is használod, akkor is érdemes elolvasni, mert át fogja alakítani a szemléletmódodat. Ezzel az eszközzel felvértezett komplex programrendszert a tojáshéjas seggű ifjoncok már 2-3 hét múlva programozták, azaz képesek voltak termelni.

* És itt jön az, hogy más, tetszőleges hasfájásal kommunikáló eszközt is könnyedén be tudsz illeszteni.

Nem atomreaktort kell vezérelni, csak olyan technológiát kidolgozni ahol az mcu (amivel dolgozok)

Nincs itt semilyen atomreaktor! Tetszőleges hardverhez jó, és tetszőleges nyelven írhatod. Csak C-ben kicsit bonyolultabb... ;)

Én meg csak dumálok a levegőbe... Amint lesz időm dolgozni :-D, éppen egy új i2c eszközt kell illesztenem. Majd megírom, hogy hány munkaórába került a fenti technológiával.

"Nem atomreaktort kell vezérelni ..."
Én ezt a multimaster módra és hasonló bonyolultságokra gondoltam.

OFF: Úgy látom neked sem igen van kivel kibeszélni a problémákat. Szép analízis
Az ina-t azért hoztam fel, mert azt az egyszerű lujji féle polling -al már megírtam, "csak" át kell ültetni interrupt kezelésbe. Minél általánosabban annál jobb. De a multimaster felállásra nem akarok felkészülni, azért ez elég ritka.

* Én egy indián vagyok. Minden indián hazudik.

Úgy látom neked sem igen van kivel kibeszélni a problémákat.

Amikor legtöbb a munka, akkor fórumozok legöbbet. ;)

A multimaster elég ritka, még egy bonyolult rendszernél sem igazán látom a kihasználhatóságát. Talán valamilyen prioritás kezelésére jó lehet, de azt már nem így oldanám meg. Ennél egyszerűb feladat (több) ina alert kezelése - ajánlom gyakorlásnak.

Szép analízis

Nem analízis! Tényleg így működnek a programjaim. Analizátorral akár agy nélkül is fel lehet építeni a protokollt. Viszont kihagytam az i2c protokoll egyes elemeinek a hardver/állapotgép megvalósítását, amit az 1. réteg után kell beszúrni. Ezt lényegében megcsinálja a processzorod, nem kell vele foglalkozni.

Az i2c interruptok megértéséhez tényleg meg kellene nézned egy pic adatlapban leközölt impulzusdiagrammokat! Meg a liberót.

Szeretném megérteni és átlátni, hogy működik. Ilyen esetekben a legjobb ha magamnak leképezem.
Ha produktum lenne és nem amolyan hobbi, akkor minden működő segítség jöhet.

OFF: Pl. adatbázis kezeléshez a Clarion nevű RAD -ot használom. Már a DOS -os világba is létezett, mostanra gyakorlatilag ha jól leírod az adatbázis struktúráját, legenerálja a kódot, amit aztán "csak" finomítani kell. Egyszer már megértettem a btree -t és a relációs adatbázisok felépítésének menetét, és nem akarok foglalkozni a windows esemény hurkokkal. Ráadásul, C programot is lehet illeszteni hozzá, így anno, gyorsan felépítettem mondjuk olyat is, hogy FFT offline analízis és megjelenítés.

* Én egy indián vagyok. Minden indián hazudik.

Ha produktum lenne és nem amolyan hobbi, akkor minden működő segítség jöhet.

Ez mindegy is. Nem fizetnek ugyan, de próbállak a helyes útra terelni. ;)

A megéréshez elengedhetetlen az, hogy mit kell megérteni. Lásd pl. fent és lent locsemege és apal huptársunknak tett kiigazításomat!

A forrás: I2C-bus specification and user manual

Az első az i2c specifikáció birtokosának a dokumentuma, mert minden gyártó ehhez igazodik(, vagy ettől tér el ;)). Ha szeretnéd megérteni, akkor ebből derülnek ki az alapvetések. Utána jöhet egy pic adatlap, ahol az is le van rajzolva, amit az stm8 ugyan tud, de az adtlap csak megemlíti. Hacsak nincs az stm8-hoz egy külön i2c füzetecske.

No erre még nem gondoltam, hogy a PIC i2c leírását összevessem az STM8 leírásával. Melyik Microchip leírást javaslod?

Egyébként nem is akkora hülyeség mint elsőre tűnik. Az i2c amolyan ipari szabvány, ráadásul ha használni akarod, akkor fizetned is kell érte (mára gyártónak) ezért van az hogy az AVR "Byte-oriented 2-wire Serial Interface (Philips i2c compatible) izének hívja. A Microchip nem vacakolt, kiperkálta.

Sok párhuzamos leírást lehet találni, pl. az ADC felbontás növeléséről ír a Silab, a Atmel és a Microchip is.

* Én egy indián vagyok. Minden indián hazudik.

Hát valamit valamiért. A relativen olcsó 16-24 bites ADC mind delta-szigma ami alapból lassú.
Amit inkább furcsállok, hogy miért kell a zajt az ADC bemenetére tenni, miért nem lehet az eredményekhez hozzáadni? Miért kell az analóg csatornán átengedni?
Inkább az aggaszt, hogy sokat olvastam arról hogy az mcu -ba beépített ADC -k zajosak, csúnyán meghamisíthatják a mérést, érdemes akár "halt" -ba tenni a mérés idejére.

* Én egy indián vagyok. Minden indián hazudik.

Ez egy frankó téma, amit szeretünk használni.
Szóval gondolj egy olyan jelre, amely a kvantálásnál kisebb amplitudójú. Hogy könnyebb legyen elképzelni,
   1 kHz alatti frekvenciájú jelet akarsz digitalizálni, de az amplitudója csak tizede a kvantálási szintnek ... ezt nem tudod így közvetlenül digitalizálni.
Keverj hozzá egy mondjuk 2 kHz-es 10..20 kvantálási értékű színuszos jelet. Digitalizáld be együtt például 500 ksps tempóval.
Digitális térben húzz rá egy szűrőt, ami 1 kHz alatt átenged, 2 kHz-en és felette viszont legalább 60 dB elnyomással rendelkezik.
És megkapod az 1 kHz alatti frekvenciájú tized kvantálási értékű, azaz "lehetetlen közvetlen digitalizálni" jeledet.

Rádióamatőr területen: digitalizáld be közvetlenül az antennáról érkező rövidhullámot 120 Msps 16 bittel. Aztán keverés a digitális térben, decimálás ... szedd ki azt a 100 Hz széles távírószeletet, amire kíváncsi vagy. A dinamikatartomány nem 16 bit, hanem nagyjából 26 bit. Azaz például 1 V-os, kábelen bejövő jelamplitudóból 16 biten A/D-zve ki tudod digitális térben szedni és erősítés után meghallod az eredetileg csak tized mikrovoltosként beérkező távírójelet is.
Egy élő demót rá például itt látsz: http://websdr.ewi.utwente.nl:8901/ Rajtad kívül sokan hallgatnak éppen más-más frekvenciáról ezen a hardveren éppen adást.

A kolléga itt fölöttem elvitte picit a matematika irányába ezt, s nem biztos, hogy szemléletből látható. Megpróbálok adni egy fizikai képet hozzá, ami közvetlenül elképzelhető.

Az analóg jeled két kvantálási érték között van. Legyen mondjuk 5 és 6 között, tegyük fel, 5.8. Ezt alap esetben mindig 5-nek mérné az A/D konvertered. Most adj a bemenethez zajt, amelynek egyenletes az eloszlása. Mivel a zajunk lefelé és felfelé ugyanolyan valószínűséggel mozdítja el a bemenetet, s az 5.8 közelebb van a 6-hoz, egymást követő mérésekben gyakrabban fogja átlépni a 6-os küszöböt felfelé, mint az 5-öset lefelé. Azaz, elég sokszor mérsz majd 5-öt, még többször 6-ot, nagyon ritkán 4-et, s igen ritkán 7-et. Ezek átlaga 5.8-at fog majd adni. Ha nem osztod el a mérések darabszámával, akkor csak megnőtt a felbontásod virtuálisan, de ehhez időt kell áldozni, sok mérés kell.

Azért nem jó digitálisan hozzáadni a zajt, mert annak semmi értelme. :) Ha az 5.8-ra mindig 5-öt mérsz, akkor már elveszítetted azt az információtartalmat, hogy ez közelebb volt - analóg jelszintben - a 6-hoz, mint az 5-höz. Ha ehhez digitálisan zajt adsz, majd átlagolod, pontosan 5-öt kapsz vissza, illetve némi zajjal terheled a jeled, de semmi hasznod ebből.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

:) fontos, hogy a mérendő jel frekvenciatartományába ne essen zajkomponensből, mert azt nem tudod eltaposni a digitális térben például aluláteresztő szűrővel.
Viszont amint fentebb írtam, ha a hozzáadott komponens frekvenciatartománya garantáltan elkülönül a mérésed frekvenciatartományától, akkor digitális térben szépen ki tudod szűrni az áltlad analóg térben hozzáadott "zajt".

Megjegyzem, ezt a trükköt képre is alkalmazzák. Emlékeztek még a régi fekete-fehér újságokra? Ott tényleg az volt, hogy vagy volt tinta vagy nem.
Jobb híján a kétállapotú nyomtatáshoz adj nagyfrekvenciás zajt és bízd az ember integráló képességére az átlagolást:
      https://images-na.ssl-images-amazon.com/images/I/51c0Dc4BPgL.png (nagyítsd-kicsinyítsd ... máshogy integrál a látásod)
Egyébként erre is ráereszthetsz procival aluláteresztő szűrőt és az erről a képről kétállapotúan kapott pixelek helyett szürkeárnyalatos képet kapsz.

az mcu -ba beépített ADC -k zajosak, csúnyán meghamisíthatják a mérést, érdemes akár "halt" -ba tenni a mérés idejére

No, meg érdemes

  • A gyártó által előírt szűréseket is odatenni, úgy és oda, ahogy leírták.
  • Olyan tokot választani, melyen külön Vref és Vanalog csatlakozás van.
  • Gondosan megtervezni az analóg és digitális táplálást és földeket.
  • Gondosan megtervezni a topológiát.
  • Gondosan beállitani a határfrekvenciát.
  • Ha kell, a digitális jelből kicsit kiszűrni a kvantálási zajt és az érzékelő zaját. 

Utána meg elolvashatod az adatlapon, hogy mit tud az adc. :-D

Persze a felhasználói élmény kicsit csökkenti, ha kontakthibás usb kábelen, fostalicska tápú pécéről táplálod. :( De azért azt a zajt is lehet csökkenteni, legalábbis 10 bithez képest.

Amilyen jó vagyok hozzád, adtam egy +1-et. :) A kapcsolási rajz bármit elbír, ott még bátor voltam. Aztán jött a feketeleves. Amikor a PCB-t terveztem egy ilyen csodához, már az alkatrészek elhelyezésénél majdnem válságos állapotba kerültem. A hidegítő kondenzátorokat közel kell rakni a táplábakhoz, de akkor hogy a fenébe jövök el a nem is tudom, hogy 0.635 mm-re vagy 0.5 mm-re lévő lábaktól? Egy idő után el jut az ember oda, hogy már a via-knak sincs hely, vagy a track-et nem tudja elvinni, vagy a szigetelési távolság limitál.

Egyébként ha az ember jól ráérez az elhelyezésre, egy jó placement fél siker, sőt, talán több is annál. Nagyon sokat számít a topológia kialakításában.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

És még egy fontos: SMD kerámiakondi ESR-jére is figyeljetek. Ezzel szívtam, amikor 20 MHz-re kellett tized ohmos kapacitív földelést csinálnom, miközben mint utólag kiderült, a kerámiakondi ESR-je ezt a tized ohmot eleve meghaladta. Pedig a kockás papíron én ideális kondenzátort rajzoltam oda, 0 ohmos ESR-rel. :)
Megoldás: a kívánt leszívó kört több kisebb kondi párhuzamos eredőjeként összerakni.

Amire persze nincs helyed. Igen, szokták azt is, hogy párhuzamosan kötik a különböző nagyságrendeket, pl. 100 nF, 10 nF, 1 nF. Ráadásul az első valószínűleg X5R vagy X7R anyagú lesz, az utolsó C0G (NP0).

A másik kedvencem: kapcsolóüzemű táp végén egymással párhuzamosan low-ESR elkók. Igen ám, de ezekkel párhuzamosan már nem tehetsz kerámia kondit tovább csökkentendő az ESR-t, mert el fog fogyni a szabályozó fázistartaléka, és begerjed, oszcillál majd az egész kóceráj. Tehát oké, hogy low-ESR, de eszeveszetten nem csökkentheted, néhány milliohmnak maradnia kell azért.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Megpróbálom összefogni a tanultakat.
Amikor az ADC felbontásáról beszélünk, akkor az alsó régióról van szó, az érzékenységi határ(on).
10 bitnél (3,3V tápfesz és referencia egyben) 32mV, 12 bit 8mV, 16(15) bit 100uV és végül 24(23) bit kevesebb mint 1uV.
(A 16 és 24 bit ADC esetében az MSB az előjel szokott lenni)

Mivel így, hogy "nóniusz" nem sok mindent találtam. Hamarjában két filozófia lehet, az egyik a logarléc a másik pl. a toló mérőkön (subler) található kisebb léptékű a mérést pontosító skáláról van szó. Vagyis mondjuk két ADC -t használunk úgy, hogy az egyik nagyobb erősítőt kap és különbözeti feszültséget (analóg előtét) így pontosíthatjuk a mérést a kvantálási szintek között. Persze ezt lehet úgy is, hogy egy DAC -t használsz és kétszer (vagy többször) mérsz különböző skálán. A megoldás hátulütője a precíziós analóg elektronika (sample and hold és "zero" offset és drift).
Elképzelhtő egy olyan változat is (szinte minden ADC bemenetén van egy illesztő OPAM) ahol a mérések között a feszültséget egy fél digittel shifteljük el, ezzel pedig eljutunk a keverj bele zajt megoldáshoz.

Mindezeket megspékelve a nyomtatott áramkör, a tápfeszültség és a referencia feszültség problematikájával. Húzós dolgok.

* Én egy indián vagyok. Minden indián hazudik.

A húzós dolgok ott kezdődnek, amikor lazán leírod a 100uV-ot. ;)

Illesztettem 2.000N-os 4 huzalos (10mv) erőmérő cellát hx711-hez (20mV), ami 23+előjel bites. Kellett némi szakirodalom a csatlakozókhoz is, amíg megbízhatóan meg tudtam mérni negyed kiló kávét. Az volt otthon. ;)

Ennél a felállásnál 1 bit = 24nV, amikor az áramkör zaja 90nV (RMS).  Aztán jön az apróbb ellenálások, a kontaktusok, a tápegység és a környezet zaja. Maradt 11-12 bit. Ha reprodukálható, akkor elég jó. (Részletekkel nem fárasztottalak, de ennyi a végeredmény.)

Két féle típus létezik.

1) Az "eredeti" Microchip adc-t tartalmaz. Több példányt bemértek (talán németek?) mérőlaborban és legalább olyan pontos, mint a specifikáció. Szóval megdöbbentek a fiúk. ;)

2) A másik verzió kínai csippel készült. Van benne egy finombeállító potméter. Ilyenjeim is vannak, de még nem értem rá foglalkozni velük.

Az lutri, hogy melyiket kapod.

A cégnél készült műszereket az 1 típussal "hitelesítjük". Magyarázat: Ezek a műszerek nem hitelesek a szó szabványügy értelmében. A hitelesített műszer annyit tud, hogy bármely két eladott példánya ~0,1% pontossággal méri mondjuk az akkufeszültséget 23 fokon, és 0..40 fok között is a hiba <1%.

Ezeknek a kis műszereknek hasonló lehet a hitelesítési módszere ahhoz, amit mi használunk.

A csip tartalmaz egy referenciát, aminek pl. 1% tűrése. Ezt a referenciát egy etalon referenciához hasonlítva (értékét megmérve), és a továbbiakban a pontos értéket használva közel az etalon pontosságával megegyező lesz a műszer is.

Ha a bemeneten osztó is van, mint ebben a kis műszerben, akkor az osztó méretezéskor keletkezett hibáját és tűrését egy szorzóval lehet korrigálni.

Végezetül, ha a hőfokfüggést és a stabilitást is szeretnéd hegyezni, akkor jóval pontosabb és kisebb hőfokfüggésű ellenállások kellenek az osztóba. A következő lépcső a referencia stabilizálása.

Az általad linkelt műszernél is érdemes elolvasni a következő hozzászólást: 10th October 2016 at 10:14 pm

Összeesküvés vagy sem, nem is értem miért szégyellik a saját iparukat.

Mindent összevéve, fiókon van AD7793BRU (eBay, 24 bit belső band gap referencia, de "beáldozva" egy bemenet párost külső is jöhet), mcu és sokféle kijelző lehetőség (még mindig jobban szeretem a 7 szegmens LED -et).

Egyedül a referencia ami zavarba ejtő. Van egy kis AD584 referencia panelem is - a multimétereimet szoktam vele ellenőrizni/kalibrálni.

Ami nincs, az a pici NYÁK és dobozka.

Ha lesz időm, összerakok egy ilyet, de egyenlőre a 15+1 bit elégésgesnek tűnik. 4,5 digitet azzal is el lehet érni ami máris több mint a szokvány 3,5 digites multiméterek.
(Az INA226 azért is olyan szimpatikus, mert szinte semmi nem kell mellé, labortáphoz, műterheléshez, akku töltőhöz tökéletes.)

* Én egy indián vagyok. Minden indián hazudik.

Az  AD7793 ± 0.01%-os referenciája - ha jól elcseszed - 12 bit abszolút pontosságot eredményez. Ha csinálsz hozzá termosztátot, akkor térdig hóban is mérhetsz. ;)

(Bizalmas, magánjellegű keresztkérdés: Űrhajót épitesz? :-D)

Vagy ahogy a mondás tartja: Nem tudja az a tejföl, hogy hányadika van. ;)

Szerintem a bazinagy (elméleti) pontosság helyett sokkal nagyobb figyelmet kell fordítani az osztókra. Még a jobb ellenállások között is van 2..250ppm hőfüggésű. A hiper-szuper adc helyett a teljes áramkör hőfokfüggését és esetlag a hosszúidejű stabilitását kell megcélozni. Az abszolút pontosságnál fontosabb, ha 30 fok különbségnél is tudod mit mérsz. Ekkora különbség már a tél és nyár között is előfordulhat.

A gyakorlatban általában elegendő egy 10 bites adc és egy 50 forintos referencia, ha jól van összerakva.

Nem építek űrhajót.

A lavinát a 48V -> 5V/3A -es POE táp indította el. Mintegy 6-7 különféle, eBay beszerezhjetőségű tápot kellett megvizsgálnom (ill. játszottam azzal is, hogy AC 230V -> DC48V/4A tápot használni, de végül kikötöttem a Meanwell -nél).
A mérési összeállítás igényelt volna egy működő műterhelést. Először összeraktam egy a Rádiótechnika újságból kiollózott (Bassó féle) 2N3055 -re alapuló kapcsolást (a 2N3055 -öt lecseréltem 2N3773 -ra az már akár 160V) de eléggé monstruózusra sikerült (a legdrágább eleme a hűtőborda). Majd találtam eBay 170W FET -es panelt (KIT) és végül felcsaptam (volna) egy 100V/10A (VC288 ?) kis panel műszert. Na itt kezdődtek a bonyodalmak, ez a VC288 egy igazi bull shit, a feszültség mérés még úgy ahogy de az áram köszönő viszonyban sincs a valósággal. Próbálkoztam más verziókkal, de az eredmény hasonló lett.

A VC288 áram mérő ága egy LM358 -al kezdődik, amit 3,3 járatnak (erről megy az mcu és a led kijelzők is!). Az LM358 nem rail-to-rail és a precíziótol elég messze esik. Nem értem hogy működhetne egyáltalán. Megtaláltam egy eredeti kapcsolást az STM8S103K -val ahol az opam külön tápról megy - így akár jó is lehetne, de akkor a NYÁK kuka.

Szóval eljutottam arra a pontra, hogy ha akarok egy jót akkor magamnak kell megcsinálni. Keresgélés és felesleges körök után eljutottam az INA226 -hoz, ami egy tokban tudja azt ami nekem kell. Egyedül a feszültség mérésben kell egy jó osztó. A kijelzést és a kommunikációt a chippel már intézheti akár egy STM8S103, ráadásul soroson naplózhatok is (a soros mehet BLE vagy WiFi így a galvanikus leválasztás ius megvan). A használat szoba hőmérsékletre kell csak (nem akarom beépíteni az űrhajómba).

* Én egy indián vagyok. Minden indián hazudik.

Röviden szólva elkezdtél fejlődni. ;)

Kell némi rutint szerezni az ebay választékának megítéléséhez! Gyakran szembejön a 40-50 éves technológia (a 2N3055 és a LM358 se kutya), dilettáns tervezés, silány alkatrészek. Sokszor a kellő felbontású termékfotó alapján döntök.

A VC288-nak alapvetően nem lenne semmi baja, csak

  • rosszul ollózták
  • hiányzik néhány kondenzátor
  • az STM8-at nem szabad (áram) meghajtásra használni, ha az analóg funkciók lényegesek
  • az árammérésnél nincs offset beállítás
  • a sönt rosszul van méretezve

Egyébként jó. ;) Ilyen esetben érdemes felkeresni orosz oldalakat, ahol visszafejtették és esetleg ki is javították.

Persze egyszerűbb tervezni és építeni egy jobbat.

A műterhelés jó játék. Készítettem erősítő beméréséhez 2x 150W/6 Ohm szerkezetet. Volt két hűtőbordám, ami közé hővezető pasztával éppen befért egy csomó négyszögletes ellenállás. A költsége ~2000Ft.

A TM7707 -ben nincs belső referencia.
Az AD7793BRU tartalmazza.
Megnéztem néhány referencia chip -et, azon túl, hogy elég drágák, még csak nem is precízebbek. Valahol írod hogy "ha elcseszem" akkor 12bit effektív felbontásom lesz.

Rágom, de még mindig nem értem, mit lehet ezen elcseszni úgy, hogy 24 bit helyett 12bit felbontásom legyen?

* Én egy indián vagyok. Minden indián hazudik.

Nem írtam, hogy a TM7707-ben van-e referencia, és nem is hasonlítottam össze mással.

Az a leírás egy hasonló felépítésű általános műszer pontosításáról szólt.

Valahol írod hogy "ha elcseszem" akkor 12bit effektív felbontásom lesz.

Rágom, de még mindig nem értem, mit lehet ezen elcseszni úgy, hogy 24 bit helyett 12bit felbontásom legyen?

Nézzük, mit is írtam:

Az  AD7793 ± 0.01%-os referenciája - ha jól elcseszed - 12 bit abszolút pontosságot eredményez.

Tehát nem effektív, hanem abszolút, és nem felbontás, hanem pontosság.

Vagyis az ős Volthoz képest - amit Párizsban őriznek a az ős Métertől balra ;) - a referencia tűrése miatt, ± 0.01% hibád lehet. Ez megfelel ~13,29 bitnek. Tehát elméletileg abszolút 1/10.000 pontosságú lehet a mérés. A gyakorlatban - hacsak nem 1,17 voltot mérsz - ennél mindig rosszabb.

Ha "kilépsz" az áramkörből, akkor jöhet a felbontás vesztesége, amiről itt írtam. A felbontás ugyan marad, de a hasznos bitek száma csökken.

Ez olyan jelenség, mint a CD, amelynek a bitszámból következő jel-zaj viszonya 90dB, míg a felvételé általában csak 55dB, de attól még megmarad 16bitesnek.

Azt hiszem értem miről beszélsz. 12 bit abszolút pontosság nagyon jól hangzik.

Mint rádiós (elég rég volt) a néhány uV bemeneti érzékenység igencsak jónak számított, figyelembe véve az elérhető eszközöket és a kriogén berendezések hiányát. Ami ráadásul váltóáramon értendő, nagyon más mint az egyenáram. Te végig csak a zajokról beszélsz, de ott vannak különféle elemek driftje is. A pontosság szinte csak átmeneti állapot.

Mindenesetre, rendeltem az általad is megjelölt cuccból 2 db -ot, nagyon kíváncsi leszek rá mit lehet vele elérni. Van még fiókon pár darab LT1021DCN8-10 chipem is, ami 10V +/- 0,05% 5ppm/°C lesz mivel kipróbálni és kalibrálni. (Párizs szép lehet de kihagynám)

* Én egy indián vagyok. Minden indián hazudik.

Mondom, nem csak leírás van, hanem ipulzusdiagram. Annak alapján rögtön látod melyik interrupt mit csinál, mitől függ és mi jöhet utána.

Én a PIC18F14K22 és a PIC18F24K50 (meg egy PIC16) típusokkal dolgoztam, és tizenvalahány féle eszközt használtam i2c-n.

Az i2c "ipari szabvány", de a specifikációban van egy táblázat: Applicability of I2C-bus protocol features, és vannak optional és mandatory fícsörök benne. ;) A gyakorlati implementációkban meg anomáliák. :-D A Microchip meg szinte az összeset megcsinálta, tán ezért is hívja másképp, mint az AVR.

Én a programot költeményhez szoktam hasonlítani. :-D

Az én szempontjaim szerint, az irq kiszolgáló kód legyen rövid.

Hát olajoshal. ;) Kiegészíteném a "rövid" meghatározást: időben rövid. De ez sem egyértelmű.

Ha van egy timer interrupt, akkor célszerű a kódnak lefutnia, mielőtt jön a következő. Ez világos.

DE!

MCU-ra nem mindig operációs rendszert írunk. ;) Ezért - ha van értelme - az interrupt alatt elvégezhető feldolgozásokat is elvégzem. Persze lehet bufferelni, buffer pointert kezelni, buffer fullt kezelni, és ugyanezt megcsinálja a main is, hogy szép és hosszú programot írhassunk. Az van ilyenkor, hogy akár több perifériával is dolgozhatsz, de ebből nem következik, hogy a másik nem várhat. Ilyen elvek mellett roppant egyszerű lesz a kód, hiszen az interrupt (esemény -> akció) egy olyan önálló program, amit általában nem kell mutexekkel körberakni, hiszen önálló program és automatikusan lockolja magát. A futásidő ellenőrzésére szoktam bevetni az analizátort. Bár tudom, hogy rövid gyors programot írok és a processzor is szinte túl gyors, de azért ellenőrzöm.

A C -nek ott lehet előnye, hogy nem kell megtanulni az mnemmonicot...

A kis PIC-nek 35, a nagyobbaknak 76 utasítása van. De hallottam már egy egyszerű feladat kapcsán 2500 java osztályról is. XD

Bizony kihívás!

A 8085-nek 76 utasítása van, az STM8 kb. ez a nagyságrend, csak kicsit ;) több fajta címzésmód és ugrás van. Ha érted a változók hosszát (ezt C-ben is meg kell adni, hogy a fordító ellenőrizhesse), és a memória szerkezetét - ezen is alapulnak a címzés- és adatmódok -, akkor némi gyakorlattal nem fog problémát jelenteni. Bár C program íráskor elveszik az a varázs, hogy akár hülye alultájékozott is lehetsz ;), mert tudod kb. mire fordul egy deklaráció vagy utasítás.

LATAbits.LATA3 ^= 1;

#define LED LATA, LATA3, a (vagy) LED LATA, 3, a
	btg		LED

A fenti kis példa a ledvillogtató szoftver lelke. ;) Az első sor C. A led a LATA (PORT A latch mód) bit 3-ra van kötve. Az alsó két sor asm. Új szerkezet tervezésekor lemásolom az adatlapot és a lábkiosztásnál jegyzeteket írok, hogy mi hova van kötve. Az adatlapban használt kifejezés a LATA, az asm headerben a bit definíció LATA3. Odakötök egy ledet, és a definiálom a címzésével (a) együtt. A LATAbits egy C definíció, nem találod meg az adatlapban. És ez csak egy egyszerű példa. (A btg utasítás = bit toggle)

Most azon tipródom hogy vissza kéne nyúlom az i2c -hez és megcsinálni az interrupt kezelést.

Most hallom először, hogy interrupt nélkül is lehet. :-D

Itt a koronavírus, ezért (is) nekiálltam ózongenerátort bütykölni. Kell hozzá táp, táp vezérlés és ellenőrzés, hűtőventillátor sebességszabályzással, hőmérő, időzítő, billentyűzet és kijelző. Az utóbbihoz van i2c-lcd1602 modulom, aztán elkezdtem vakargatni a fejemet. Előhúztam egy régebbi rajzot, mert csináltam már hasonlót.

A régi projekt (sajnos bedöglött) négy (autó) kerék helyére szerelt elektrodinamikus fék vezérő központja. Az egész egy hordozható, terepen is használható 1000LE teljesítményű fékpad lett volna.

A központ a négy féket vezérli, adatot gyűjt 4db 5m hosszú i2c interfészen (a fékek 200A 100kHz - szinte zavarmentes ;) meghajtással mennek). Az adatok i2c FRAM-ba kerülnek, illetve soros porton mennek a számítógépre, ahonnan jön vissza a vezérlés. Van ezen kívül néhány nyomógomb, lcd kijelző, a processzor vezérli a tápegységet is. Az utóbbi (és a soros port) kivételével minden i2c.

Ehhez elegendő egy 512 bájt rammal rendelkező processzor. Az i2c-hez rendeltem egy parancs buffert, ahova a parancs elhelyezi az adatokat is. Az i2c meg feldolgozza az interruptok alatt. Az egyes parancsokat token sorozatból állítottam össze. Eleinte nehézkes, de aztán mindent meg lehet vele csinálni- akár a nem std i2c műveleteket is. Egy-egy interrupt egy ugrótáblából és néhány sornyi kódból áll.

Pl. lehet frissíteni a 4 féken csücsülő processzorban a firmware-t i2c-n keresztül. A vezérlő kiadja a frissítés parancsot, a címet és a program blokkot. A kliens besüti a blokkot - és addig nem ad ACK-t - majd (N)ACK-val jelzi, hogy sikeres volt-e. Ez 1db i2c adatsor!

Nnnna, ilyet nem lehet a soros porttá hülyített i2c-vel megcsinálni. (hashtagek: Arduino, twi, rpi, serial_write, stb.)

Az stm8 i2c implemetációja talán az egyik legjobban kidolgozott, amit eddig láttam. (talán működik is) Viszont a megértéséhez természetesen egy PIC adatlapot javaslok. Abban szemléletes impulzusdiagrammokkal minden mozzanatot elmagyaráznak - oda van rajzolva a sok-sok interrupt is. ;)

A vezérlő kiadja a frissítés parancsot, a címet és a program blokkot. A kliens besüti a blokkot - és addig nem ad ACK-t - majd (N)ACK-val jelzi, hogy sikeres volt-e. Ez 1db i2c adatsor! Nnnna, ilyet nem lehet a soros porttá hülyített i2c-vel megcsinálni. (hashtagek: Arduino, twi, rpi, serial_write, stb.)

Marmint ugyerted hogy egy master transmit -> slave receive kommunikacional a slave sem az address match-ot, sem az egyedi adatbyte-okat nem ACK-olja le, kiveve a legutolsot? 

A kommunikáció végig szabályos. Az utolsó adat után a master elengedi az SDA-t, hogy a slave adhassa az ACK-t. Ehhez a master adna egy órajelet, de a slave addig tartja 0 szinten, amíg nem végzett a blokk a blokk írásával - ami több ms. Az írás sikerességének függvényében beállítja az ACK-t és elengedi az órajelet. Ez a clock stretching, ami teljesen normál buszművelet, ha implementált.

Mivel itt két processzor beszélget, bármit meg lehetne csinálni.

A probléma pl. egy EEPROM írásánál kezdődik, ha írás végét szeretnéd megállapítani. Megcímzed az eszközt és nem válaszol. (Lásd 5.1.6, Figure 9) Ugyanitt a másik anomália, ha utána nem akarsz sem írni, sem olvasni. Minkettő megoldásához nem std buszműveletet kell összerakni.

Tehát a bájtonként továbbított adatok helyett - mert ilyen üzemmódba is kapcsolhatsz - sokszor a buszciklus egyes elemeire is programot kell írni. A serial_write() erre nem alkalmas, de egyes hardvereket nem is tudsz programozni, mert csak a kötelező minimumot implemetálták az i2c protokollból.

Bonyolítsuk tovább a helyzetet, mert eddig még mindent össze lehetett rakni az i2c perifériát programozva. Pl. az AM2320 i2c/smbus protokollját sem tudod összerakni. A Figure 15 -> min 800us és a Figure 17 -> min 30us késleltetések nem valósíthatók meg az egyszerű i2c hardverrel. Csak az a megoldás marad, hogy i2c elemekre bontva + program + időzítés. Persze csak akkor, ha nem akarsz megállni és NOP-okkal késleltetni. ;) Marad az a megoldás, hogy az anomáliánál timer beállít és interrupt vége - majd, ha a timer lejárt folytatódik. Közben a processzor végrehajthat 300 utasítást.

Ez utóbbit szoktam iskolapéldaként emlegetni. Ember megírja rpi-re az AM2320 illesztését, fölrakja a githubra. Aztán vesz egy gyorsabb rpi-t és a program nem működik. Bezzeg, ha az adatlapot is elolvasta volna, vagy tisztába lett volna a serial_write() mögötti történésekkel, akkor akár hordozható programot is írhatott volna. :-D

Ez a clock stretching, ami teljesen normál buszművelet, ha implementált.

Igenigen, de ez szerintem abszolute resze az altalad is emlitett "ötelező minimumnak". Es ha jol lattam, pl az atmel-avr vonalon is tudja ezt a rendszer, es halistennek pont ugy fogalmazza meg ahogy kell, meglehetosen lakonikusan: While the TWINT Flag is set, the SCL low period is stretched. Szoval akar transmitter akar receiver modban vagy, es nincs lezarva az elozo folyamat es/vagy nem tudsz uj adattal felkeszulni akkor hagyod az interupt flag-ot ahogy van, es az huzza a clock-ot. 

Mikor FPGA-kon jatszottam i2c-vel akkor viszonylag gyorsan felfogtam hogy nem "master" meg "slave" meg "receiver" meg "transmitter" - vagyis enneka 4 kombinaciojaval leirhato - modzatok vannak itt hanem van egy "transciever" meg van egy "clock generator". A master az abban kulonbozik a slave-tol hogy ott van egy clock generator is, de az egesz allapotgepet (beleertve clock stretching-et) joval logikusabb ugy implementalni hogy csinalsz egy transcievert, ami lehuzza a clock-ot ha epp' szeretne/kellene nem tud tovabblepni a kovetkezo allapotba. A slave oldalon ez pont azt is csinalhatja amit mondasz (azaz "a kovetkezo allapot az az lenne mikor az EEPROM befejezte az irast", de boven ugyanez a kategoria az is hogy "slave transmitter modban vagyok de a processzor meg nem kuldott semmi atkuldendo byte-ot", de az is hogy "slave vagyok, megcimeztek, de a processzor nem szolt hogy ezt a cimet ack-olhatom most vagy sem". A master oldalon meg siman lehet ez akar a "meg nincs adat de majd biztos lesz" allapot. Azaz tkp a 8+1 bit barmelyik fazisaban huzhatod a clock-ot, ha epp' ugy jon ki a lepes :) 

Ettol fuggetlenul persze, az igaz, hogy a "ket processzor beszelget" esetben lehet kavarni a mindennel ;) De ez ezeket az alapokat nem kell hogy erintse. 

A Figure 15 -> min 800us és a Figure 17 -> min 30us késleltetések nem valósíthatók meg az egyszerű i2c hardverrel

Ld. fentebb. Ha ATmega328p-n csinalod, akkor egyszeruen varsz egy kicsit miutan megkaptad a TWINT-et es nem lepsz tovabb a kovetkezo allapotba (fig 15-nel a TWSTO-ba, fig 17-nel meg nem ugrasz at egy darabig meg a master receiver kovetkezo, TWCR =(1<<TWINT)|(1<<TWEN)|(1<<TWEA) allapotaba). Ez lehuzza az SCL-t, es pont azt csinalja ami az abran van.

egyszeruen varsz egy kicsit miutan megkaptad a TWINT-et es nem lepsz tovabb a kovetkezo allapotba

Ez az, ami soha nem fordulhat elő! El kell dönteni, hogy eseményvezérelt-e a program, vagy szoftver loopokkal időzítgetsz! Amikor egy ilyen driver elkészül, soha nem tudhatod mi lesz még mellette, hány interrupt várakozik - amelyek lefuthatnának a "kis várakozás" alatt. Legyen az a definíció, hogy a program mindig csak annyi ideig futhat, ami a feladatok végrehajtásához szükséges! Ezzel az ideológiával bármikor jöhet extra feladat, bele fog férni a megmaradt időbe.

Jól néztem volna ki, ha nem így írom meg! Pont ennél a munkánál szerettem volna debuggert használni, de nem ment. Némi küzdelem után kiderítettem a little bugot: ez az üzemmód csak feleakkora órajelnél működik. :-D Természetesen minden a CLOCK-ból számíitódik, de akkor is elveszik a késleltetés ideje, a többi meg kétszer annyi ideig tart. (A "minél többet vásárolsz, annál többet takarítasz meg" elv alapján: csak feleannyi utasítás veszik el. ;))

Most egy nagyon pszeudo kód következik:

I2C_DelayAddress
	Start_Timer_With	Delay_Address
	Return_From_Interrupt
---------------------
I2C_WriteAddress
	...
---------------------
I2C_StartConditionD
	Start_Timer_With	Delay_StartCondition
	Return_From_Interrupt
---------------------
I2C_StartCondition
	...
---------------------
Timer_Interrupt
	Set I2C_Interrupt_Flag
	NOP
	Return_From_Interrupt

Az i2c a WriteAddress helyett a DelayAddress tokent hajtja végre, ami csak beállítja a Timer-t a cím írásáig előírt késleltetésre. (30us)

A ha a Timer lejárt, akkor előidéz egy I2C_Interrupt-ot, ami végrehajtja a késleltetés utáni WriteAddress műveletet.

Nyereség: 28us.

Az i2c StartCondition helyett a StartConditionD tokent hajtja végre, ami csak beállítja a Timer-t a StartCondition indításáig előírt késleltetésre. (800us)

A ha a Timer lejárt, akkor előidéz egy I2C_Interrupt-ot, ami végrehajtja a késleltetés utáni StartCondition műveletet.

Nyereség: 798us.

A NOP direkt került oda (valójában 3db), mert a timer alacsony, míg az i2c magas prioritásu interrupt, ami a NOP-ok alatt el is indul.

WTF token? - Mint írtam, a buszművelet sorozatot tokenek sorozataként adom meg. Így akármit le tudok írni. Minden tokenhez csak néhány sor kód tartozik.

Tehát várakozás nincs.

FYI: Az emlitett Arduino meg egyebebekkel par ora alatt megirod az egesz ozongeneratoros projectet, mert be tudod huzni az i2c atalakitos 1602 libet, a homeros libet, - ha van ilyen - a prellmentesitett billentyuvezerlodet, a hutoventihez felhasznalhatod az egyik PWM labat, az idozitest meg megcsinalhatod interruptbol, varakozassal, vagy a micros/millis ertekeket nezve, stb. (mondjuk ha van eleg lab, az i2c modult kisporolnam belole) Nem lesz olyan profi, mint ha 0-rol ASM-ben irod, de minimalis tapasztalattal is hamar mukodni fog. Lehet, hogy nem fog beferni 512 byte RAM-ba, de nem baj, mert a legkisebb hivatalos Arduinokban is 2k van (Atmega328P), bar vannak kisebbek is 3rd partybol. Ha akarod, akkor visszanyulhatsz a regiszterek butykoleseig (mert hatekonyabb - ki gondolta volna), de ha meg tudod allni a kesztetest, akkor akar STM32-n vagy ESP-n is futni tud, ha idokozben valtozik az igeny. Hobbiprojectnel, ha nem kell minden centet kioptimalizalni, mert egy peldany keszul belole, megfelelhet. Ja, es az Arduino hozza kb. az 512 byte-os PIC-ed araban van, esetleg kicsit meg az alatt is (Arduino Mini Pro $1.5 korul szokott lenni Alin, bar ahhoz kell egy USB atalakito is). Ha sajat nyakot is tervezel hozza, akkor meg plane ($1.1 korul van az SMD valtozat, ha kisebb project, es belefersz mondjuk az Atmega8-ba, akkor 40-50 cent korul meguszod).

Egyik baratom szereti a PIC-et ASM-ben programozni. Honapokig el tud szoszmotolni nehany projectjevel, amig megirja benne a program menujet, ami sem idoben sem RAM-ban/flash-ben nem lenne kritikus (jo, munka mellett ertendo az a par honap). Ha megirna C-ben, es csak az idokritikus reszeket irna ASM-ben, hamarabb vegezne, kevesebb bug lenne benne, es futasidoben semmit nem vesztene (mert az maradhat ASM-ben).

A strange game. The only winning move is not to play. How about a nice game of chess?

FYI: Ugyan sokat barkácsolok, de valamit elfelejtettél: Én ebből élek. ;)

Másrészt fogadjunk, hogy legalább 2x annyi processzort/panelt fel tudok sorolni - tekintet nélkül, hogy megfelelőek a feladatra, vagy sem. :-D

Egyébként van itthon néhány száz PIC, de van 2db DESZKA MODELL is. :-D

Fölülről, az óramutató járásával ellenkezően:

  • -akku (etc) csatlakozó - a processzor vezérli a tápot is
  • nyomógombok
  • belső i2c busz
  • ICSP (soros programozó)
  • 2x izolált di2c, min 5m
  • rs232 - host kapcsolat és debug
  • jobb felső sarokban a saját+izolált tápegység

Tehát mindezekre (meg ami a kijelző alatt csücsül) kész a firmware. Ezen kívül van még egy hőmérő is ugyanezzel a processzorral, ami 4 féle i2c csipet támogat. Lehet, hogy Arduino 1602 lib nélkül is össze tudom hozni. ;)

Az sem fog a földhöz vágni, hogy a firmware-k  megfelelő részleteit felhasználva új áramkört építsek: processzor + PCF8574 + kijelző + 2 fet + passzív elemek és egy pc táp. Bár ennek nem sok előnye van, de a kijelzőt is feleannyi idő alatt tudom írni. No nem az asm miatt, hanem mert néhány drót máshova van kötve. ;) Így aztán a maradék portokra bőven elfér egy gagyi kis numerikus billentyűzet.

Hidd el, nem a sebesség terel az asm irányába, mert C-ben is meg tudom írni ugyanazt a funkcionalitást a feladathoz elegendő sebességgel. Nagyon ritka az, amikor "időkritikus" valami és csak asm a megoldás. Ilyen esetek inkább szervezési hibából, vagy hibás alkatrészválasztásból adódnak.

És azért nem C, mert tudom mit akarok csinálni, de ahhoz nem valók a magasszintű nyelv vagy egy operációs rendszer konvenciói.

Ez így igaz. De a lassúságot lehet fokozni:
   - Assembly (normálisan)
   - C normális fordítóval, -O2 az minimum. Ahol kell időzítés miatt, ott assembly betét.
   - Assembly (kezdő szinten)
   - C "szolgai fordítóval" ... ilyen fordítóval is van mikrovezérlős tapasztalatom.
   - Rust (mikrovezérlőre): időzítésre kényes helyeken assembly betét jól jöhet. AVR, NXP, STM32 véges számú mikrovezérlőire van egyelőre jól használható modulokkal ellátva.
 

Így amennyit nyersz assembly-ben való utolsó utasítás optimalizálással

Ezt nem is értem. Nem C programot írok, nem "optimalizálok", hanem megírom a programot. 83 óta programozok assemblerben, nekem ez nem kihívás. ;)

A 5V toleranciát meg a hajamra kenhetem, mert az ADC-hez akkor is osztó kell. Aztán pl. a 12x56 méretű panel egyik oldalán a 4 nyomásmérő, a másik oldalon az USB kábel és minden. A 4db osztó sem férne el, hát még a tápegység és a meleg. ;) Rögtön drágább lesz az olcsóbb processzor.

A 10 bites ADC értéket nem érdemes 32 biten ábrázolni, hardver szorzó pedig van.

a 8 bites történelmi darabokat

Évek óta a Microchip új fejlesztéseinek a java része PIC16. Ez azért lehet, mert nem kédeztek meg ;), vagy mégiscsak létezik az iparnak egy olyan szegmense, ahol nem naaaagy szoftvereket írnak a mirokontrollerre csak használják. Bár lehet a kicsiket is C-ben programozni.

Nem hiszem bárki vitatná az assembly programozási képességedet, viszont nehezen vagy nem hordozható. Az iparban valamiért (nem tudnám felsorolni a pontos okokat) de a C a szabvány.

OFF: Egyébként találkoztam olyan eszközzel, ahol 386/486 PC re írtak úgy assembly -ben szoftvert mintha egy jól körülépített mikrokontroller lenne, viszont az ilyen alaplapok beszerzése már nagyon keserves és drága, újra kellene írni az egész programot, úgy hogy az 100% -ban fedje az eredeti funkcionalitást, aminek a dokumentációja a szegényesen kommentezett forráskód. Buuu

Egyébként, szerintem a C egy zseniálisan kitalált szimbolikus assembler.

* Én egy indián vagyok. Minden indián hazudik.

Nem aról írtam, hogy az iparban mi a szabványos nyelv, hanem (ahogy írod) a jól körülépített pici PIC-ekből rengeteg fogy és egy csomó új fejlesztés is van.

Régen úgy mondtuk: A C struktúrált assembler. - Azóta már sokkal fejlettebbek a C fordítók, nincs szükség a kézi asm optimalizálásra.

Jön a HA! Ha szoftvert írsz, akkor igaz. Én nem szoftvert írok, hanem firmware-t. Tulajdonképpen csak felparaméterezem a hardvert, hogy azt csinálja, amit kell. (Erre szívesen írok egy példát, ha érdekel.) Néha kell szorozni, meg összeadni, sőt valamilyen logikát leírni, de ezek egyáltalán nem kritikus dolgok.

A rosseb sem akarja hordozni ezeket a programokat! Elkészül egy szerkezet és gyártjuk. Van olyan termékünk, amit másik cég is gyárt. Egyetlenegy konkrét processzort tudunk használni. A 16k helyett 24k flash váltáskor meg ugyanaz a kód fog futni, csak néhány config word lesz 2 bittel gazdagabb. ;)

Ha másik processzorra kerülne a sor (mondjuk egy 16 bites PIC, vagy akármi más), és a nem hordozhatóság miatt át kell írni az USB drivert, akkor sincs gond. Eleve az "én driveremet" valaki más írta, disassemblált forrásból indultam ki, amely szinte bitre megegyezik egy publikus C forrással. Ezt kijavítgattam, kiegészítettem és töröltem néhány dolgot, így használhatóbb lett. Viszont pontosan tudom mi van benne. Ha egész héten ki se jövök a kocsmából, akkor is képes vagyok bármire átírni. :-D

Akik ugyanilyet C-ben programoznak, valamelyik gyártó libjét használva, ennél kevesebbet tudnak. Felhívták a figyelmemet, hogy mindig a legfrissebb libet használjam. Kiröhögtem őket. Az én driverem többféle és több, mint 1000 szerkezetben működik már 6 éve, sohasem volt vele hiba. A jótanácsadók interfésze instabil - és nem is én mondtam. Na, melyik a jobb.

Az meg soha nem fog előfordulni, hogy a PIC-ből kimarad az I és holnaptól PC-n kkell futnia a programnak. ;)

A rosseb sem akarja hordozni ezeket a programokat!

Hat, a francsetudja :) Mostanaban eleg sok kommunikacios szirszart programozgattam, es elegge nagy volt az orom amikor ugyanazok a (tipikusan layer2-3, szoval lentebbi) dolgok valtoztatas nelkul mukdtek rendes linuxos pc-s kornyezetben, stm32f0-n, atmega-n illetve sajat avr2-es szoft cpu-n is. Es a kommunikacio jellegebol adodoan azert elegge szamitott a futasido is, sokminden ment interrupt handlerben, stbstb.

Szoval ez hogy ki mennyire akarja hordozhatova tenni vagy nem akarja hordozhatova tenni a (C) kodjat az erosen alkalmazasfuggo kijelentes ;] 

ki mennyire akarja hordozhatova tenni vagy nem akarja hordozhatova tenni a (C) kodjat az erosen alkalmazasfuggo kijelentes

Ember! Ez nem alkalmazás, hanem HARDVER. Az ALKALMAZÁS Windowson fut C#-ban.

Nem layer2-3, hanem layer1, már ha rá lehet fogni. A C libekkel semmit sem tudok kezdeni, mert nem erre készültek.

A kommunikáció USB HID. Adok egy excel táblát és megírod pillanatok alatt.

Egy mosógépben is atmega van. Biztosan C-ben van írva. Fogod-e futtatni linuxos pc környezetben? És ha igen, akkor miért nem. :-D

Tehát ennek vagy ennek hova hordoznád a kódját és miért?

Épp arra készültem, hogy rákérdezzek miért kerülnek ilyen algoritmusok mint a FIR szűrő a mikrokontrollerbe, amikor az adatot kiöntöd egy (a PIC -hez képest erőműbe). "Mert gyorsabb vagyok, mint a Core i7 C# -ban"

A C# programozó pénzét is megkapod legalább?

* Én egy indián vagyok. Minden indián hazudik.

Szerencsére nem. ;)

Az egyik ingyen dolgozik, de minimális jutalékért - nemrég nősült, inkább az asszonnyal foglalkozik. A másik zseniális programozó, de nem dolgozik - most rúgtam ki. A harmadik tanít, de nem profi, lassan dolgozik. A negyedik meg nem dolgozik velünk - ellenkező esetben én távoznék.

Ezzel részben megindokoltam, hogy bárminél gyorsabb vagyok.

A 16 bites adattal a FIR mondjuk 32 utasítás TAP-onként, tehát legrosszabb esetben 165us. Másodpercenként 4000 mérést kell végezni és minden eredményt megszorozni egy konstanssal, hozzáadni egy offsetet. A processzor nem csinál semmit, ami kb. 20us mérésenként. A maradék 230us időbe belefér a 165us. Az adat pont olyan sebességgel érkezik, mint előtte.

Dicső szoftvereseinknek míg elmagyarázom a tennivalókat, annál sokkal rövidebb, ha én írom meg. Az is sokkal hosszabb, ha ők írják meg. A végeredmény biztosan lassan futna. Aztán évekig javítgatnák, én meg tesztelgethetném és konzultálgathatnám. (Az esetek többségében nem is értik, hogy pontosan mit mérünk.) Hidd el, így a leghatékonyabb!

És ezzel megindokoltam, hogy bárkinél gyorsabb vagyok. (Az adott környezetben.)

Azért nem irigylem a munkáltatódat, ha téged elüt a hajókötél bezárhatja a boltot?

Próbálom összerakni, egy bizonyos iparágba tevékenykedsz akár 20 éve vagy régebbről. Óriási rutin és tapasztalat. Együtt fejlődtél az iparággal. Így azért könnyű, már amíg valami ménkű be nem csap. Nekem nem sikerült ennyire szakosodnom, így talán több választási lehetőségem van, viszont mindenhez értek és semmihez (eléggé), régen volt '84 amikor diplomáztam.

* Én egy indián vagyok. Minden indián hazudik.

Bizony, ilyen egy kalákában működő kis cég.

Egy kicsit vagyok csak öregebb, mert 83-ban diplomáztam, mint gépészmérnök. Már jóval korábban is érdekelt az elektronika, tervezgettem is egyszerűbb dolgokat. Utána 7 év a VIFI-ben (Videoton Fejleszési Intézet: Hardver főosztály/Elektromechanika osztály - mint villamos fejlesztőmérnök), ahol a szakma nagy öregjeivel* dolgozhattam. Rengeteget fektettem a tanulásba, a végén az öregek teljesen közéjük tartozóként kezeltek. (Na, azért volt némi fejlődés is. A bucko sokat pofázik. => A buckonak mindig igaza van, de nagyon sokat pofázik. ;))

*Define öreg: Szakmai önéletrajz elején - A Videoton összes nyomtatójának fejlesztésében részt vettem. - Megsúgom: Nem takarítónőként.

Utána a kisebb bakugrásoktól eltekintve 19 év AIX rendszerprogramozás és üzemeltetés. (Hidd el, az pont olyan, mint a PIC! ;)) Közben egy-két kisebb hardver munka, az elektronika megmaradt hobbinak.

Most meg 7 éve motordiagnosztikai műszerecskéket fejlesztek, illetve újratervezem a csúnyán távozott elődöm egyes munkáit.

Bár nem vagyok Bill Gates, de elmondom az én trükkömet: Önképzés, precizitás minden áron, és csak azt csinálom, amihez értek és kedvelem is. Akár rosszabb anyagi feltételek mellett is. Kell egy kis szerencse, jó helyen kell lenni jó időben.

Júl kimásztál a gépészmérnökségből.
Tanulni? Evidencia, muszáj.

Én Moszkvában diplomáztam 1984 -ben nagyjából a "híradástechnika hírközlés" megnevezéssel (minden ami rádióhullám a hosszú és mikró) az egyszerűség kedvéért "gyengeáramú villamosmérnök". Akár találkozhattunk is én a Mechanika Laboratóriumnál kezdtem (az utolsó nagy munkánk az L16 volt, koprodukcióban többek közt a Videotonnal). Igen gyorsan elkezdtem programozgatni és ha szigorúan vesszük és firmware -ket írtam (munkaállomás firmware). Néhány darab megtekinthető a Hadtörténeti múzeumban ;)

Aztán elmentem vállalkozóba és megrendelésre építettem egy rádiós biztonsági rendszert az átjátszó állomásoktól a központi monitoring szoftverig. Közben egy külföldi tulajdonú vállalatnak is dolgoztam mint szervizes (áruvédelem, behatolásvédelem, tűzjelzők, CCTV szinte minden ami biztonságtechnika).

A gépészeti tudásodat, már ha mg is kopott azért irigylem.

Az általad felsoroltakhoz én odabiggyeszteném a tesztelést is. Ma lépten-nyomon bele ütközhetünk a firmware -k hibáiba. A szoftverekről inkább ne is beszéljünk.

* Én egy indián vagyok. Minden indián hazudik.

Gépészeti tudás, felhívtam a főnökömet:

- Mondd már, hogyan működik a négyütemű motor?

- Ezt most hogy érted?

:-D De azért nem ilyen rossz a helyzet.

Azzal sértettek meg igazán, hogy "Persze, ti assembler programozók addig tesztelitek a programot, amíg jó nem lesz."

A válasz pedig az, ha nem tervezem meg és nem dolgozok pontosan, akkor törik vagy kigyullad a gép. Ne felejtsd, hogy nem ledvillogtatással kezdtem, hanem mechanikavezérléssel! Persze voltak fiatalkori botlások. Pl. az egyik hobbiprojekt kötőgépvezérlő, mikor a 26 kilós lakat nagy sebességel elindult a júzer feje irányába. ;)

Megint csak azt mondom, hogy az assembler azért jó, mert pontosan az történik, amit odaírsz. (jobbára ;)) A javított hibák 99%-a elgépelés, ami fodításkor kijavítható. A maradék - ha van - kiderül amikor a főnök mér a prototípussal.

A hibák (másé) jó része az ismeretek hiányából fakad. Kolléga távhőmérőt programoz, de nem szeret olvasni. Az adatlap 50 oldal, DE van arduino lib!! Jövök gonoszkodni:

- Mennyi időnként kérdezed le?

- 0,3s, az tökéletesen elég.

- És az nem zavar, hogy gyárilag 1,2s frissítésre van paraméterezve az eszköz?

Szerintem megint két malomban örlünk.
A 2x4x8 -hoz, HC164 (nincs output latch) 8x16 bitet aza 128 bitet kell kishiftelni ahhoz hogy minden doigiten megjelenjen a szám.
Ahhoz hogy ezt egybefüggőnek (folyamatosnak) lásd min. 20ms mind a 8 digitet ki kell shiftelned.
A w0...w3 -at n em is értem, van 2x 4 dgitem és két darab 8 bites shift regiszterem sorban mi a w0...w3?

"Hát azért parázslik, mert az 1 ms szünet alatt fals érték van rajta." Nincs rajta fals érték, 1ms - 10us egy digitnek megfelelő érték van kinn a regiszterek kimenetén. Úgy tűnik, ez kevés, és mondjuzk 2ms - 10us kell ahhoz hogy ne legyen parázslás, de ezt még ki kell próbálnom.

Örülök, hogy megy olyan jól, hogy mindig van a kezed ügyébe egy szkóp.

A 30-50 KSMPS jól hangzik, viszont a számításokhoz,. megfelelő mennyiségű RAM is kell. Az én fapados STM8S103F3 (SSOP20) mindössze 1K -m van (emiatt is elvetettem az OLED kijelzőt).
Természetesen mindenre van cél eszköz, (pl. amit sosem értettem az a tojás főző készülék). Multimétert se használhatok? Csak külön amper, volt és ellenállás mérőt? Egy ilyen kis kütyüvel, azon túl hogy kijelzi a feszültséget, áramot, kiszámolhatja a teljesítményt (ina226 feature),  szolgálhat mint biztosíték is, naplózni is lehet. (Ha ránézel a piacra, ha naplózási lehetőség kell  az ár rögtön +50%). Így viszont elküldheted akár galvanikusan leválasztva, bl vagy wifi esetleg RF (433MHz).

* Én egy indián vagyok. Minden indián hazudik.

Szerintem háromban, de megmagyarázom. :-D

Egy kicsit nem figyeltem, ez igaz. Aztán jött ez a hozzászólásod, amikor közöltél egy kódrészletet. Ekkor kicsit szűklátókörűen elvesztettem a fonalat.

Tehát egy C hívás konvencionálisan

-megkapja a stack-en egy int16-ban a ( shft_seg[8] shft_dig ) értékét

-aztán mégegyszer előveszed a shft_dig-et és mégegyszer shiftelgeted

- a C fordító miatt még korrigálod teljesen feleslegesen

Ebből elhamarkodottan arra a következtetésre jutottam, hogy két digitet írsz ki egyszerre, ami miatt 4x hívod meg a függvényt 4 int16 értékkel.

Ez se nagyobb marhaság, mint amit a C fordító előállított. ;)

8x---

Örülök, hogy megy olyan jól, hogy mindig van a kezed ügyébe egy szkóp.

A cégé, amelynek dolgozom. De sajnos nem táltos. Egy kicsit gyengébbet már néhányszor tízezerért lehet kapni.

Végszükség esetén neked is van szkópod, már ha van hangkártya a gépedben. ;)

Azt meg egyáltalán nem mondtam, hogy ne használj multimétert. Legfeljebb arra céloztam, hogy van amit kéziműszerrel nem lehet megmérni.

 

Mielőtt tovább okoskodnék két kérdésem van.

- Van-e egy szabad kimeneted?

- A 2x164-es áramkört tudod-e módosítani?

Nem is azért szóltam, de tényleg jól jön egy kis segítség (ha más nem is leírom a bajomat és közben rájövök mit kell csinálni).
Egyébként van a kezemügyében egy szkóp, igaz lehet nálam is öregebb de már benne van a két sugarasítás és kettős kérleltetett eltérítés. Van egy kis BitScope nevű cuccom (max. 40 MSPS) de már a bitbang sebességével felsült, túl rövid a pulzus. Az i2c -nél viszont rengeteget segített. Multiméterből meg van vagy 4 db (köztük egy antik USSR de csak ez tud 6A mérni folyamatosan). Igen a cégé amelyiknek dolgozom - én.
- 2-3 van szabad kimenetem még akad (de ha nem akkor váltok egy nagyobb chipre)
- a 2x164 egyelőre nem kiváltható (az 595 -el nem láb kompatibilis és a 164 -es  so14 talán) és csak ennek a modulnak van a két kijelzője egymás alatt és nem mellett.

Úgy egyébként van MAX7219, TM1637, és van hc595 is, de ezekhez NYÁK kellene, én meg most akarok egy "protót" csinálni ahelyett hogy NYÁK tervezéssel bíbelődnék. Ha már kielégítően működik akkor kezdek ezen gondolkodni.

* Én egy indián vagyok. Minden indián hazudik.

Küldhetnél egy linket/képet a modulról.

Most pedig jöjjön a parázslás workaround!

Az a baj, hogy az összes szegmenst végiglépteted az összes digiten.

Ha elvágod a két 164-es között az órajelet és a csatlakozótól távolabbi órajelet külön kivezeted a plusz portra

  • - a digit órajelen egy lépés
    • - inicializáláskor (1x): 7db 0 bit
    • - minden 1. digitnél: 1db 1 bit - ekkor 00000001 lesz
    • - minden további digitnél: 1db 0 bit - 00000010 stb.
  • - a szegmens órajelen 8 lépés

Így egy 8 digites ciklusban mindig csak a "cél" digiten látszanak a shiftelt szegmensek, ami kevesebb, mint az eredeti felállás.

Avagy a digit meghajtó hibás helyen csak nyolcad annyit ideig lesz bekapcsolva.

 

Ami biztosan nem fog földhöz vágni: Logikai Analizátor - ha még nincs.

Értem. Az ötlet jó, de szerintem vagdalkozás nélkül is megoldható. Csak ez első durva verziót csináltam meg, még faragom.
Egyébként nem akarok pineket pazarolni, de ha nem találok mást akkor ez lesz a megoldás. Illetve kicsit furcsa is hogy ekkora kitöltési tényezőt látok (1ms/10us).

Ami az analizátort illeti van ilyenem is. Már a koncepció is belopta magát a szívembe. Viszont a sigrok még mindig elég fakezű.
Most ilyet használok https://bitscope.com/product/BS05/ max 40MSPS és a trigger mégsem tudja a most kialakult clockot megfogni, túl rövid a pulzus :(

* Én egy indián vagyok. Minden indián hazudik.

Sajnos a szem olyan, hogy látod. Azért gondolkozz a fenti digit táp megszakításon is! Az a korrekt megoldás, csak többet kell hozzá szerelni és mérni (!).

Rövid a pulzus? Nézd csak meg, hogyan programoztam, és írtam is róla! A belövés alatt rakhatsz bele még néhány NOP-ot.

A FET is hasonló problémát okozhat: Vagy kivárod amíg kapcsol, vagy driver kell hozzá, mert a processzor kevés.

Amire GNU van írva, abból csak a gputils használható. ;) A linuxos dolgok meg általába régen elkezdett befejezetlen amatőr dolgok. Inkább azok csinálnak működő dolgot, akik ebből élnek. A bitszkópot nem ismerem, de ugyanebből az árból meg lehet venni azt a pici koppintott analizátort (vagy kettőt és van egy frekvencia generátorod is, bár még nem próbáltam), meg egy 20-40MHz fostalicska USB 2ch szkópot - ami rendelkezik szkóp-szerű tulajdonságokkal. (Itt látom, hogy néhány dolog majd csak lesz.)

Az analizátor jó, tényleg láttam már protokoll-analizált USB jelet. Ha ezt használod, elfelejtheted a debuggert, de olyat is meg tudsz mérni, amit debuggerrel sem. (A 80-as évek végén 128ch Dolch analizátorral mértem. A triggert max 8 oldalnyi folyamatábrán lehetett beállítani. Beépített disasembler, MP/M, 8 processzor. Az alapgép ára 2M, a fizetésem 8,2k. :-D)

Ezzel nagyon szemezek, de most ez is sok https://www.ebay.com/itm/USB-Logic-DSLogic-Basic-Analyzer-16Ch-100MHz-4Ch-400MHz-Xilinx-Spartan-6-FPGA/133098250816?epid=13032631968&hash=item1efd462240:g:rf0AAOSw5FNZisrk

Egyébként a kis bitscope -al az i2c simán láttam és belőttem.

Ami meg a LED -et illeti ez egy protó, már most jól látszik, hogy a megoldással sok a baj, ja és még szeretnék blink -et is.

* Én egy indián vagyok. Minden indián hazudik.

Visszafejtettem a NYÁK -ot (nem egy kunsztos darab) de csak egy fényképem van a jegyzetről. Sajnos nem tudom hova tudnék képet feltölteni.

Egyébként semmi különös, a két shift regiszter "sorba kötve" (az első regiszter utolsó kimenete megy a második adat bemenetére), a clock -ok összekötve. Az első a sorban hajtja ki a digiteket, a második a szegmenseket. A szegmensek és a regiszter kimenetek közé van kötve egy-egy 1kOhm -os ellenállás. A kapcsolás nagyon egyszerű.
Így végül van egy "data in" egy "clock" és a táp (jelenleg 5V), úgy hogy az mcu 3,3V jár, de eszi.

* Én egy indián vagyok. Minden indián hazudik.

Elképzeltem. ;)

A kijelzőnek a földön vagy a tápon van a közös pontja? Meg lehet úgy szakítani, hogy egy SOT23 méretű FET és két ellenállás beférjen? - Alternatív megoldás: A digitek közös pontját kel kihozni egy dróttal és kívülre az áramkört.

Igaz, olyan kicsi az áram (?), hogy akár tranzisztor is jó lehet. Ez az opció arra az esetre, ha nincs kéznél FET, vagy nem szeretnél smd alkatrészeket szerelni.

Az ötlet: Kimérni, hogy mennyi idő alatt kapcsol a kapcsoló és

- időzítgetni, vagy

- kikapcsolni, a 20ms-ból egyet kihagyni és a következő interruptban shiftelni és visszakapcsolni

A kijelzők közös anód  0,36" elég kicsi (de a fiókban várnak a 0,28" is, illetve a sok sz@r 100V/10A shitmeter szintén 0,28").

Az áram kicsi hiszen 1k minden szegmensenként max 8x5mA azaz 40mA csúcs, egyszerre csak egy digit van bekapcsolva. Sok kapcsolásban látni a bipoláris kapcsoló tranzisztorokat, de itt nem szükséges.
Egyébként a fényerő szabályozás annyira nem érdekel, ahol 10A mérek nem igazán játszik néhány 10mA ide-oda, hacsak nem rángatja a tápot, az viszont táp baja. Az INA226 egyébként is a 3,3V LDO -ról megy, és nem a mért körből fogom nyerni a tápfeszt (ne hamisítsa a méréseket, még az is lehet hogy elem).

Az ötletedet ötletelem én is, már csak a pontos megvalósítás az érdekes. Szeretném ha ezt digitenként beállítható lenne. Lehet itt van az a pont hogy újraírjam az egész eljárást, lehet "tiszta" C. Viszont akkor lehet mégis be kell tenni néhány asm bitműveletet. De még alszom rá, lehet tök felesleges ezzel bíbelődni ha működik (ha átteszem mondjuk STM32 -re akkor eljátszom vele).

* Én egy indián vagyok. Minden indián hazudik.

A frissítés most már egész jó. Végül csak minden harmadik ms frissítek (a 8 digit agy 24ms), nem vibrál, a parázslás már félhomályban is alig érzékelhető. különösen ha minden digitben van valami.

Miközben az osztóval piszmogtam, sikerült olyan kódot írni, hogy nagyon szépen blinkelt/villogott az egész. Kezd kirajzolódni a kód :)
Ha mindenképp kell a fényerő szabályozás, akkor az kóddal nem igazán megoldható, ha a frissítés (shiftelés) és "kinn van a szegmens" arányokon akkor vagy vibrál vagy parázslik. Sokkal magasabb frekvencián (akár 100kHz) kellene beleszaggatni abba az időszakba amikor egy szegmens kinn van vagy módosítani a kapcsoláson. Az én céljaimra (ha megcsinálom a villogtatást is ez elég lesz.
 

* Én egy indián vagyok. Minden indián hazudik.

Ha mindenképp kell a fényerő szabályozás, akkor az kóddal nem igazán megoldható, ha a frissítés (shiftelés) és "kinn van a szegmens" arányokon akkor vagy vibrál vagy parázslik.

Ezért nem ezt írtam. Ne legyél ennyire skót, áldozd fel azt az egy lábat! ;)

Ha nem akarsz külön drótot, akkor a kijelző tápját is modulálhatod. Eben az esetben a 164-ek tápját egy diódával és egy akkora kondenzátorral kell ellátni, ami bőven kitart egy periódusig.

Nem is értem mi ezzel a probléma. A javaslatom hasonló, mint a népszerű "tápon viszem át az adatot", amit pl. az 1-wire is használ.

Éppen 33 éve jártam úgy, hogy a kijelzőre shiftelő adatkimenet egy olyan latch volt, ami Fairchild gyártmánynál bufferelt a Texasnál meg nem. Elektrosztatikus zavarnál (kötőgép) csupa nyolcas jelent meg a kijelzőn. A legegyszerűbb volt néhány ciklusonként frissíteni. Ha már a DRAM sem szégyeli. ;)

"tápon viszem át" ... hány helyen használja az ipar, csak a boldog halandó nem tud róla:
   - pillanatnyi moduláció nem zavarja a dióda-kondis csúcs csapdát, mint tápfesz "befogást".
   - régi Tiris kártya, mai érintésmentes kártyák: induktív adat & dióda-kondis csúcs csapda szintén tápfesz "befogáshoz".

   - antennaerősítő: soros kondis leválasztás, induktív tápráültetés
   - USD-PD: tápvonalat induktivitáson keresztül vezették ki a Type-C előtti időkben és itt szintén kondin keresztül ráültetett 23,2 MHz-es FSK és az így átvitt csomaggal beszélik meg a kért feszültséget és áramlimiter értékét + ACK/NACK a tápoldal részéről. A Type-C -nél a polaritást figyelő CC1 és CC2 vonalat használják erre, így már nincs 23,2 MHz-re szükség (se tekercs-kondira).
 

Mostanában fogok tervezni egy olajnyomás- és hőmérőt, ami a motorba csavart csavarban ücsörög processzorostól nyomásmérőstől. Max 7 bar és <120 fok. Ez is kihívás, de leginkább az, hogy 10x12 nyákba még vezetékeket is kell forrasztani. Persze raktáron csak nagyobb keresztmetszetű szilikonkábel van, ezért kisebb méretű processzor lesz. ;)

Az apróság oka a nyák ára, ami nem kínai.

De mit csináljak 6 lábú processzorral? A Guiness csak sörben a kedvencem. ;)

Nincs deszkamodell csak első sorozat. Kell 5 láb a táp+programozáshoz (és debug, de nem debuggerrel), kommunikáció és szenzorok kb. 5 láb. A cél a QFN20 4x4x09.

Ettől kezdve egyszerű a választás: PIC18, 125 fok, 5V, QFN20, ami 4 találat (Mouser) 13/4K22 és 13/4K50. Az 50-ben van USB, ezért az előbbi marad. Így +3 lábbal lehet variálni. A 14 lábú PIC16 sem hozna lényegesen jobb eredményt és kisebb méretet. Sőt, még a kódot is lehet "hordozni", mert erre vagy a 24K50-re megírt kódrészletek is felhasználhatók. A PIC18-ban van szorzó és access ram, bankolni sem kell.

A szűk keresztmetszet a vezetékeken kívül nem a processzor, hanem lesz még 2db erősítő és a kommunikáció. Remélem a méretben tévedtem 1-2 milit lefelé. ;)

A hőmérséklet tartományból az alját hiányolom. Hidegen akár -20°C pályafutásom alatt egyszer csináltam gk-ba valamit már a hőmérsékleti szélsőségek egy kihívás. Ha megcsinálod és működik emelem kalapom!

Ami a kábelt illeti, fiókon van némi teflon szigetelésű 0,4mm (amennyire ez mérhető) vezetékem. Viszont tömör, rezgést nem fog sokáig tolerálni.

* Én egy indián vagyok. Minden indián hazudik.

Nem tudom, mi lehet a probléma az alacsony hőmérséklettel. Az "egyszerű" áramköröknél lehet páralecsapódás, vagy hibásan válaszott üzemi hőmérséklet. Mi általában kiöntjük a műszereket. Megnéztem, még a nyomásmérők is -40..125 fok között működnek. A processzor 85 fokig, de itt természtesen 125 fokig működő típust fogok választani. A passzív elemek ennél többet tudnak.

:-D

A "kábeled" wire-wrap vagy kötözőhuzal. Én nem tenném egy motorblokkra lengőcsatlakozóval.

Házi feladat: reflow forrasztás.

Maradjunk az smd alkatrészeknél! Forrasztáskor a gyártó által megadott görbe szerint felmelegítik és lehűtik az egész panelt. A folyamat 1-2 órán át tart, 260 fok max. hőmérsélklettel. A gyártó megadja az alkatrészre, hogy pl. -55..150 fok tartományban lehet az üzemi hőmérséklet. Vagy hazudik a gyártó, vagy igaza van.

Az a baj, hogy az elektronika egy technológia. A fizikaórán tanult R=1000 Ohm nem elég egy áramkör megtervezéséhez. Az amatőr bemegy a boltba és kér egy ellenállást akkor kap. Beforrasztja - működik. Nekem meg az a feladatom (én adtam magamnak, mert a főnököm nem ért hozzá, de éppen ezért végzem én a munkát), hogy a legyártot 1000db műszer közül kiválasztott két darab - adott pontosságon belül -  ugyanazt az értéket mutassa.

Amatőrködésnél is kritikus lehet a melegítés. Ügyelni kell a nem túl magas hőmérsékletre és az összeforrasztandó anyagok egyenletes átmelegítésére. A pákahegy relatíve vastag, lapos és 270 fokos legyen! Ezzel szemben a főnököm tűhegyes 370 fokos pákával szeret dolgozni. Már az is baj, ha beónoz egy viát. A túlmelegedett, de nem egyenletesen melegített forrasztásnál a hirtelen lehűlés "kitépi a lukgalvánt" (megszakítja a furatgalvanizálást :)). Nem is mindig forrasztáskor, hanem akkor, ha a környezet 40 fokkal lehűl.

A mérnöki rutin ott kezdődik, hogy ismered az alkatrészek amatőrök által nem ismert vagy lényegtelennek tartott paramétereit. A tervezésnél el lehet dönteni, hogy mikor mi a lényeges és mi az elhanyagolható és mennyire. Jártam úgy alkatrészboltban, hogy egy két kérdés után megmondták: Mi csak amatőröknek árulunk alkatrészeket. ;) A "tözsboltomban" már ismernek. A megrendelésnél csak odaírom: lehet saját készlet. Ez azt jelenti, hogy a többi alkatrésznél ragaszkodom a nagykerben kiválasztott pontos típushoz.

Nemrég azt is megkaptam, hogy túlságosan magabiztos vagyok. ;) Évek óta nincs deszkamodell, csak megtervezem, legyártatom az első sorozatot és működik. A főnököm ezt nem tudta. :-D

Ehhez kell egy zseniális nyáktervező bácsi (na jó, olyan korú, mint én), akinek nem kell sokat magyarázni. Elég beteges, mert amikor megmondom mennyit növelhet a méreten, akkor kisebbre csinálja. :)

Attól függ mit és mivel mérsz. Az emlékeim '90 évekből származnak és költséghatékonyságból kommersz IC -el dolgoztam, 0-80°C, -20°C még az oszcillátor sem indult. Úgy látszik, ez mára nem probléma, de mi van ha kiviszed mondjuk Lapp földre, a -40°C sem lehetetlen. (Moszkvában láttam olyat hogy szabályosan tüzet raktak a traktor alá)

* Én egy indián vagyok. Minden indián hazudik.

Ha a kommersz hőmérséklettartomány nem elég, akkor azon nem lehet segíteni. De probléma régen se volt, mert sok áramkörnek létezet a MIL STD szerint gyártott és bevizsgált változata. Legrosszabb esetben egy primitívebb elektronika segítségével fel kell fűteni az érzékeny áramkört.

Úgy látszik, nem láttál még a katonaságnál téli hidegindítást. Teljesen üzemszerű, hogy a Csepelek alá be kell gyújtani. A gázolaj tejföl állagú, az olaj dermedt kocsonya, amit a 15-20 perc melegítés után fel kell törni kurblizással.

Annyi fejlemény van, hogy megcsináltam a blinkelést. Kellett hozzá egy maszk byte, egy blink bájt és egy timer byte.
A timernek megfelelően, a blink bájtot xor -zom a maszk bájtlal, a frissítő ciklusban pedig a szegmens bájtot and -om a maszk bájttal, így bármelyik digitet, külön-külön és egyőtt tudom blinkelni.
Sajnos az egy bájtos timer kicsit kevés, próbáltam 16 bitesre átállni de valahogy nem azt csinálja amit várnék.

Minden esetre működik, így már használható áram és fesz mérésre (aztán jöhet a többi ötlet).

* Én egy indián vagyok. Minden indián hazudik.