Jako svůj druhý soukromý hobby projekt s mikrokontroléry PICAXE (po vcelku úspěšném modulu pro automatické ovádání stopek ve vysílači DX6i) jsem zahájil vývoj řídicí a kontrolní jednotky pro Vojtíškovo elektrické autíčko.
Prvotním impulsem bylo zjištění, že pro instalaci blinkrů, světel, couvaček a brzdovek nevystačím s přepínači, zabudovanými do autíčka od výrobce. Jako nejjednodušší se mi zdá použít mikrokontrolér s několika relé. Na to by stačil PICAXE 08M2. Rozhodl jsem se ale toho využít a doplnit autíčko o další funkce jako je sledování palubního napětí a proudu pohonných motorů (s inteligentním ukazatelem stupně vybití akumulátoru) ev. i s výhledem na zavedení proporcionálního řízení otáček motorů (plynu) někdy v budoucnu. Vznikne tak jakýsi palubní počítač pro elektroautíčko.
Takže jsem zvolil kontrolér PICAXE 28X1, který mám v domácí zásobě z jiného nerealizovného projektu.
Měl by vyhovět jak počty vstupů/výstupů, tak i kapacitami pamětí. (Pokud jste se dosud nesetkali s mikrokontroléry Picaxe, tak vězte, že to množné číslo v předchozí větě je úmyslné a má dobrý důvod. :))
PICAXE 28X1 ovšem má, jak se ukázalo, některé zvláštnosti a hlavně poměrně nepříjemné nedostatky v podpoře ve vývojovém prostředí Picaxe Editor.
Jak je to s těmi paměťmi
Picaxe 28X1 dává uživateli přístup k několika druhům paměti, které se liší způsobem adresování a přístupu (v podstatě pro každý druh paměti má vlastní adresový prostor, jiné příkazy a jiný princip přístupu), volatilitou (zda udrží obsah při odpojení napájení), možností modifikace obsahu (zápisu) a velikostí.
- Paměť programu (interpretovaný program, table, readtable)
- RAM (uživatelsky přístupná "hlavní" pracovní paměť). Má neomezený počet cyklů čtení/zápis, při odpojení napájení či resetu se obsah ztrácí.
- Pojmenované registry ("proměnné") b0-b27, w0-w13 (let, částečně: peek, poke)
- Zbytek RAM - nepojmenované (peek, poke)
- EEPROM (eeprom, write, read). Má omezený (i když vysoký - obvykle se udává 100000) počet cyklů čtení/zápis. Při vypnutí napájení zachová obsah.
- Externí paměť EEPROM (readi2c, writei2c)
- ScratchPad (ptr, get, put)
- SFR - System Function Registers (peeksfr, pokesfr)
Paměť programu
PICAXE 28X1 disponuje 4096B paměti programu. Jedná se o paměť typu EEPROM, naplněnou speciálním běhovým kódem, vzniklým ze zdrojového programu v Basicu při programování mikrokontroléru. Obsah této paměti je interpretován za běhu programu. Do této paměti program, běžící na PICAXE, nemůže zapisovat.
V části této paměti lze direktivou table připravit data pro naplnění oblasti o max velikosti 256B, pro následné čtení za běhu programu pomocí příkazu readtable.
RAM
Uživatelsky přístupnou RAM lze u 28X1 rozdělit na pojmenované registry, využitelné ve většině příkazů Basicu ve formě proměnné a na zbývající část, přístupnou jen příkazy peek a poke.
Pojmenované registry
Nejpoužívanější část paměti RAM jsou pojmenované proměnné (registry) :
- 16 bitové w0-w12
- 8 bitové b0-b27
- 1 bitové bit0-bit31
- w0 sdílí paměť s b0 a b1 (b1 je MSB) a bit0-bit15 (bit15 je MSb)
- w1 sdílí paměť s b2 a b3 (b3 je MSB) a bit16-bit31 (bit31 je MSb)
- w2 sdílí paměť s b4 a b5 (b5 je MSB)
- w12 sdílí paměť s b26 a b27 (b27 je MSB)
Příklad: w0 = $1234
w0
+-----------------------------------------------+
| 1234 |
+-----------------------------------------------+
b1 b0
+-----------------------+-----------------------+
| 12 | 34 |
+-----------------------+-----------------------+
bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 0| 0| 0| 1| 0| 0| 1| 0| 0| 0| 1| 1| 0| 1| 0| 0|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Nepojmenovaná RAM
Uživatelsky přístupná paměť má velikost 108B:
- 14B proměnné,
- 94B = 2 x 47B volné úseky
Příkazy peek, poke umožňují jednotný přístup k celé RAM. Některé typy Picaxe umožňují navíc i nepřímý přístup přes adresu v proměnné bptr (28X1 to neumí, mladší bráška 28X2 již ano). Při vypnutí napájení se ztrácí obsah, po restartu je vynulován.
Jako všechny starší PICAXE (typy bez přípony v označení a řady M, X a X1) má i 28X1 paměť rozdělenu do několika souvislých úseků, obsluhovaných příkazy peek, poke
- Adresy 32 ($20) až 47 ($2F) překrývají obecně použitelné pojmenované registry (b0-b27) - pozor, nejsou zdaleka všechny!
Přes peek/poke jsou přístupné proměnné, odpovídající sudým 16b registrům: w0, w2, w4, w6 , w8, w10, w12- b0<-32 (w0)
- b1<-35
- b4<-36 (w2)
- b5<-37
- b8<-38 (w4)
- b9<-39
- b12<-40 (w6)
- b13<-41
- b16<-42 (w8)
- b17<-43
- b20<-44 (w10)
- b21<-45
- b24<-46 (w12)
- b25<-47
- Adresy $50 až $7E obecně využitelné nepojmenované registry – paměťová místa $70-$7F mohou sdílet fyzické umístění s $F0-$FF
- Adresy $C0 až $EF, využitelné u PICAXE-28X1, 40X1
EEPROM
Lze naplnit při programování čipu (direktivy eeprom, data), za běhu programu pak číst (příkaz read) a zapisovat (write). Pamatuje si obsah trvale i při vypnutí napájení.
PICAXE 28X1 nabízí 128B velkou oblast paměti EEPROM.
Externí EEPROM
Přídavná paměť ve formě samostatného integrovaného obvodu. Někdy i kombinovaná do jednoho pouzdra s jinými funkcemi (hodiny reálného času, teploměr).
Připojená a obsluhovaná přes I2C sběrnici (hi2csetup, hi2cin, hi2cout).
Zatím jsem externí EEPROM nepotřeboval použít.
Scratchpad
128 B velká paměť pro uživatelská data, přístupná přes proměnné ptr, @ptr, @ptrinc, @ptrdec, nebo příkazy get a put.
Může být využívána pro výměnu dat mezi kontroléry Picaxe:
- může být plněna na pozadí přes high-speed serial
- pokud mikrokontrolér funguje jako I2C slave může být zapisována a čtena jiným Picaxe pomocí I2C rozhraní
SFR
System Function Registers (peeksfr, pokesfr) - hodně chaoticky dokumentovaná paměť systémových proměnných s nepředvídatelnými důsledky zápisu. V PICAXE je přístupná jen 1. stránka 0-$100. Podrobnosti lze nalézt v dokumebtaci k typu PIC, ze kterého daný PICAXE vznikl, tedy v případě PICAXE 28X1 je to PIC16F886.
Tímto způsobem může zkušený vývojář využít některé vlastnosti či části mikrokontroleru, se kterými nepracuje PICAXE FW, ev. použití modifikovat. Potíž je v tom, že v dokumentaci k PICAXE nelze prakticky vůbec dohledat které části PIC a k jakému účelu FW používá. I vývojáři firmy Revolution Education, která PICAXE vyvíjí a dodává, se odmítají na podpůrném fóru v diskusích s uživateli k této problematice vyjadřovat.
Prográmek pro testování práce s pamětí
Program cvičně zapisuje do různých druhů pamětí v PICAXE. Scratchpad je zaplněn daty ze struktury Table (data uložená ve formě pole byte v paměti programu). Tím jsem si ověřoval použitelnost této konstrukce. Ostatní paměti pak dostanou jako obsah svoji adresu v rámci daného typu paměti.
; ; Test pameti (test PICAXE 28X1) ; ; Copyright (c) 2016 Zdenek Trojanek ; ; --------------------------------------------------------------- ; Filename: TestPicaxe28X1.bas ; Date: 12.3.2016 ; File Version: 1.0 ; Written by: Zdenek Trojanek ; Last Revision: 12.3.2016 ; Target PICAXE: 28X1 ; --------------------------------------------------------------- ; ; 28X1 ; ; .----..----. ; (RESET) 1 -| RST B.7 |- 28 (Output 7) ; (ULPWU / ADC0 / In a0) 2 -| A.0 B.6 |- 27 (Output 6) ; (ADC1 / In a1) 3 -| A.1 B.5 |- 26 (Output 5) ; (ADC2 / In a2) 4 -| A.2 B.4 |- 25 (Output 4 / hpwm D) ; (ADC3 / In a3) 5 -| A.3 B.3 |- 24 (Output 3) ; (Serial In) 6 -| SI B.2 |- 23 (Output 2 / hpwm B) ; (Serial Out) 7 -| SO B.1 |- 22 (Output 1 / hpwm C) ; 8 -| 0V B.0 |- 21 (Output 0) ; (Resonator) 9 -| XT +V |- 20 ; (Resonator) 10 -| XT 0V |- 19 ; (timer clk / Out c0 / In c0) 11 -| C.0 C.7 |- 18 (In 7 / Out c7 / hserin / kb data) ; (pwm 1 / Out c1 / In c1) 12 -| C.1 C.6 |- 17 (In 6 / Out c6 / hserout / kb clk) ; (hpwm A/ pwm 2 / Out c2 / In c2) 13 -| C.2 C.5 |- 16 (In 5 / Out c5 / spi sdo) ; (spi sck / i2c scl / Out c3 / In c3) 14 -| C.3 C.4 |- 15 (In 4 / Out c4 / i2c sda / spi sdi) ; `----------' ; 28-Pin ; ; Program overuje funkcnost internich pameti pro data mikrokontroleru PICAXE 28X1: ; ; Table: 256B ; ScratchPad memory: 128B ; RAM: 256B (přístupné 108B - 14B proměnné, 96B = 2 x 47B volné úseky) ; EEPROM: 256B ; #Picaxe 28X1 ; ; Test Table ; table (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32) table (33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63) table 65, ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_") table (128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144) table ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_") table (208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224) table ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcd.") start: ; ; Test ScratchPad pameti ; for w0=0 to 127 ; ; Test zapisem dat, nactenych z table ; readtable b0,b2 put b0,b2 next ; ; Test RAM ; ; Do kazde bunky pameti se zapise jeji adresa ; ; POZOR: Nejde ladit pod Picxe editorem V6 (hlasi neplatnou adresu pri poke), ; musi se pouzit v5, ; ; Prostor pracovnich registru. ; Chova se to nejak divne, viz nasl. soupis: ; ; b0 <-32 ; b1 <-35 ; b4 <-36 ; b5 <-37 ; b8 <-38 ; b9 <-39 ; b12<-40 ; b13<-41 ; b16<-42 ; b17<-43 ; b20<-44 ; b21<-45 ; b24<-46 ; b25<-47 ; for b0=32 to 47 poke b0,b0 next ; ; 1. usek RAM (47byte) ; for b0=80 to 127 poke b0,b0 next ; ; 2. usek RAM (47byte) ; for b0=192 to 239 poke b0,b0 next ; ; Test EEPROM ; ; Do kazde bunky pameti se zapise jeji adresa ; for b0=0 to 255 write b0,b0 next end
Co nefunguje v PICAXE Program Editoru?
Picaxe Programming Editor je poměrně dobře navržené a realizované prostředí pro vývoj aplikací s PICAXE. Bohužel, pestrá nabídka mikrokontrolérů a jejich někdy značně odlišné chování, způsobují vývojářům problémy. Poměrně často tak uživatel narazí na problémy s překladem programů a jeho interpretací po nahrání na čipu (to je naštěstí méně časté), nebo na časté problémy se zpracováním programu v simulátoru, který je součástí PE.
Stává se, že překladač odmítne přeložit konstrukci, která je podle dokumentace správná. Pak nezbývá než problém nějak obejít, většinou to jde.
Více problémů bývá v simulátoru. Někdy se jedná o odmítání některé operace provést, nebo jsou prováděny odchylně od skutečného chování mikrokontroléru a tedy chybně. Vývojáři z Revolution Education se snaží problémy řešit, takže je dobré občas aktualizovat na novou verzi PE.
V souvislosti s PICAXE 28X1 jsem narazil na poměrně zásadní problém: simulátor odmítá povolit čtení a zápis z RAM pomocí příkazů peek a poke. Takže používání RAM pomocí těchto příkazů nejde v simulátoru ladit.
Naštěstí jsem našel způsob, jak věc obejít: použít starší verzi PE (v5) namísto aktuální v6. V PE 5.5.6 vše funguje dobře a lze ladit. Bohužel, PE5 a PE6 mají některé rozdíly v syntaxi Basic, takže je nutné program upravit, aby šel na PE5 zpracovávat. Je to škoda, protože jinak je PE6 pohodlnější a srozumitelnější.
Záporná čísla
Ačkoli se v dokumentaci uvádí, že PICAXE nepodporuje práci s čísly se znaménkem, není to tak úplně pravda. Podpora je ovšem jen minimální, přesně taková, aby umožnila vytvoření vlastních algoritmů pro zpracování záporných čísel. Zřejmě to souvisí s původním účelem PICAXE - výukou základů počítačů na základních a středních školách.
Podpora spočívá v tom, že Basic umožňuje zápis záporných konstant a změnu znaménka čísla v proměnné. Výsledek odečtení většího čísla od menšího je kódován v 2. doplňku (doplňkový kód). Sčítání a odečítání pracuje s takto kódovanými čísly správně, pokud nedojde k přetečení. To je vše.
Ostatní věci si musí zařídit programátor. Takže například porovnávání čísel se znaménky a jejich násobení a dělení je třeba ošetřit programově.
Připojování LCD
LCD se dají k Picaxe připojovat mnoha způsoby:
- Paralelní rozhraní s 8b daty
- Paralelní rozhraní s 4b daty
- Sériové rozhraní UART ("RS232")
- Sériové rozhraní I2C
- Sériové rozhraní SPI
Mnohem levnější a dostupnější jsou různé varianty displejů s rozhraním I2C. Bohužel, ty levné s obvodem 8574 jsou s PICAXE (hlavně pro začátečníka) svépomocí většinou prakticky nerozchoditelné. Nejen, že mají často všelijaké obskurní znakové sady, ale hlavně se použité obvody rozhraní musí inicializovat a vědět jak jsou přiřazeny bity v rozhraní displeje k bitům v datech I2C.
Zatímco pro Arduino jsou k dispozici knihovny, které to umí zařídit, na PICAXE jsme odkázání na programování na úrovni základních funkcí použitých řadičů. Dokumentace k LCD s I2C rozhraním v podstatě neexistuje. Jediná šance je analyzovat knihovnu Arduina a pokusit se implementovat příslušné inicializační sekvence a mapování pinů.
Naštěstí je pro některé rozšířené typy těchto I2C LCD displejů možné sehnat na fóru Picaxe vzorové programy, které displej obsluhují. Používání je ale dosti složité a nelze využívat pohodlí funkce writei2c, protože data se displejům s obvyklým obvodem rozhraní 8574 musí posílat po částech (půlkách byte). Je to docela otravné a pomalé, zvláště ve srovnání s LCD s rozhraním UART.
Existují i displeje LCD a OLED, které fungují přes I2C přímo a bez problémů. Bohužel, podle popisu na e-shopech to většinou nejde odhadnout. Snad podle toho, že neobsahují IO 8574, využívají místo něho nějaký mikrokontrolér.
Daleko jednodušší (a v konečném důsledku levnější) se mi zdá použití jednoho z paralelních způsobů připojení. Obvykle je ale (vzhledem k počtu nutných výstupů) nutné použít variantu se 4bitovými daty, což rovněž komplikuje práci podobně jako připojení I2C. Připojování těchto typů LCD (zejména s řadiči kompatibilními s HD44780) je ale velmi dobře popsané v řadě publikací a článků na internetu.
Vcelku se nabízí možnost použití Picaxe (obvykle 20X2 - umí I2C slave režim) jako obvodu rozhraní. Pak lze poměrně jednoduše naprogramovat komunikaci jak přes I2C, tak i UART, ev SPI.
Dobrý den,
OdpovědětVymazatProsím o radu, nemohu naprogramovat LCD displej 1602 s přídavkem i2C převodník pro LCD displej 1602 s I2C expanderem PCF8574). Zapojený s procesorem picaxe 28X2 a v jazyce Basic.
Můžete prosím pomoc. Děkuji
Tomášek.