Category Archives: MCU

AVR55:dar vienas LCD iš telefono

Seniai mėtėsi stalčiuje, niekaip nekilo rankos jį pajungti. Tačiau kažkaip papuolė po ranka. Tai tikriausiai iš kokio senoviško Siemens telefono LCD ekraniukas su kodu “M15SGFNZ07”, spėtinai iš Siemens A65, M55, C60, MC60, S55, A60 ar panašiai.
Jungiasi per 3V logikos, ir toks pats maitinimas. Pinoutas žiūrint nuo siauresnės ekrano dalies, iš kairės (kai ekrano jungtis kairėje apačioje):
1-CS
2-RESET
3-RS
4-SCL
5-SDA
6- +2.9V Vcc
7- GND
8- LED1+
9- LED1, LED2 GND
10- LED2+

Ties SCL ir SDA tik šiaip panašūs į I2C. Ištikruju ten žymiai paprastesnis protokolas.
Kiek paguglinus buvo rasti du šaltiniai- kažkokio lenko kūryba ir vienas Lietuviškas saitas. Lietuviškas buvo Arduino variantas, todėl jo per daug nesinagrinėjau. O lenko kūryba pasinaudojau, kad bent jau kažką rodytu. Poto gana daug perrašiau pats ir optimizavau. Gavosi kaip ir biblioteka kuri dalinai high-level sutampa su kitų ekraniukų valdymu. Todėl nėra problemų perkelti projektą iš vieno ekraniuko į kitą. A, dar, proporcinis šriftas, nes su monospace ant tokio ekraniuko (100*80) nelabai prasisuksi.

LM15SGFNZ07 ATMEGA AVR
Dėl spalvų tai nežinau- ar tas LCD toks prastas, ar blogai sureguliuotas kontrastas. Beja, šis ekraniukas yra žiauriai lėtas. T.y. pats skystas kristalas lėtas.

Šiaip, dar vienas momentas- čia naudojamas softwarinis SPI. Nes eksperimentuojama buvo ten kur SPI naudojamas kitais tikslais. Tačiau nėra didelė problema padaryti per hardwarinį SPI. Tik vienoje vietoje reikia kiek pakeisti kodą.

Nu ir žinoma:
M55 Siemens LCD ekraniuko AVR source code ir kompiliuotas hex failas (ATMEGA16)

ARM:0016 pertraukimai WTF?

Kartas nuo karto, kai būna laiko vis paknibinėju ARM procesoriuką. Bet kuo toliau, tuo labiau jis mane nervuoja. Šį kartą pašnekėsim apie pertraukimus dėl PIO kojų lygio pasikeitimo…

Biški veikia ir biški veikia keistai…

Susikonfiguruoji koją kaip input:

AT91F_PIO_CfgInput( AT91C_BASE_PIOA, RTC_INT );

Pagalvoji, kad kojai reikėtu pull-up:

AT91F_PIO_CfgPullup( AT91C_BASE_PIOA, RTC_INT );

… pyst neveikia iškarto. Nebereaguoja. Tai šitą eilutę užkomentuojam.

Dėl šito nežinau ar reikia, bet eksperimente panaudojau:

AT91F_PIO_CfgInputFilter( AT91C_BASE_PIOA, RTC_INT );

Dabar konfiguruojam pačio pertraukimo valdymą:

//* configure PIO interrupt and handler
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC,
AT91C_ID_PIOA,	// pertraukimo tipas.
INT_LEVEL,	// pertraukimo lygis
//AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL , 	// nesuprantu kas sukelia pertraukima
AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE , // nes visi sitie veikia vienodai
//AT91C_AIC_SRCTYPE_POSITIVE_EDGE, // visiskai. Nesamone.
ISR_PIO_handler); // paprograme atliekanti INT apdorojimą

Ir kaip parašyta komentaruose, visiškai pofig ką ten konfiguruoji- ar low_level ar external negative edge ar positive edge pertraukimas iššauna visada. Į RTC_INT koją padaviau 1Hz signalą kuris ateina iš nepriklausomo šaltinio. Taigis pertraukimas šaudo ir kai būna LH ir HL perjungimas. Ir visiškai dzin ką ten rašai.

Kita pastebėta nesamonė- nesugebu išjungti pertraukimo. Pas AVR procesoriuką, vieną asemblerio komanda ir pertraukimai išjungti. Čia jau ne. Tačiau yra “makro” komandos:

//AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_PIOA);
//AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_PIOA);

Atrodo kaip tik tas- išjungia pertraukimus pagal PIO. Praktiškai viskas žymiai blogiau. Ta išjungimo komanda susideda iš kelių komandų. O procesorius taigi dirba “asinchroniškai” (pipeline). Ir taip gaunasi, kad kažkuriuo momentu kažkas susimaišo protelyje pas ARMą ir pertraukimas nebeveikia.
Programa tokia: sukasi amžinas ciklas kuris ant spalvoto LCD ekranėlio paišo mažus kvadratėlius ar linijas (tai ne žaidimas), o pertraukimas, kas 1 sekundę parašo- atnaujiną laiką ant to pačio ekrano. Grafinio ekrano paišymo subtilybė- kad nupaišyti primityva atliekamos kelios komandos. Ir jų seka svarbi. Todėl, teoriškai grafinio paišymo metu pertraukimas turi būti išjungtas. Išjungia pertraukimą, nupaiš0 kvadratėlį, įjungia pertraukimą. Ir kai pertraukimas suveikia, ant to pačio ekrano parašo laiką. Ką jus manot? Ogi figuški- per mažiausiai 10 sekundžių, daugiausiai per porą minučių pertraukimas sugenda. Jei nejungti pertraukimo blokavimo, viskas veikia ilgai, tik ant ekrano atsiranda artefaktų dėl nekorektiško valdymo. Programėlę reikia rašyti kitaip, nei įprasta pas ATMEGAs…

Laukių komentarų žmonių kurie žaidė su SAM7 čipu.

Beja, int handleris:

__ramfunc void ISR_PIO_handler(void)
{
volatile unsigned int pin_mask = AT91C_BASE_PIOA->PIO_ISR;
// Int patvirtinimas-isvalymas. Be jo neveikia.

	if(pin_mask & RTC_INT)
	{
	if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & RTC_INT) == 0 )
		{
			AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, _BV(15));
			AT91F_PIO_SetOutput( AT91C_BASE_PIOA,_BV(15));
		}
	}
AT91F_AIC_ClearIt(AT91C_BASE_AIC,AT91C_ID_PIOA); // clear interrupt
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);	// acknowledge interrupt
}

gal čia kažką neteisingai parašiau?

ARM:0015 LCD ILI9341

Greitas portas iš AVR versijos į ARM SAM7S kodą. Čia iškilo smulkių problemų ir nesusipratimų. Tačiau buvo nustatyta, kad ILI9341 datašytas biški meluoja:
Serial Clock Cycle (Write) min 100 – ns (10MHz)
Serial Clock Cycle (Read) min 150 – ns (6.66MHz)

Tačiau man kažkodėl visas SPI puikiausiai veikia su 24MHz SPI CLK!

ARM SAM7 and ILI9341 color LCD SPI
Tekstinis LCD čia beveik nereikalingas, nes jis buvo naudojamas kaip DEBUG, kad pamatyti ar praėjo softas per tam tikrus etapus.

Ko aš nepadariau. SAM7 moka per SPI transliuoti daugiau nei 8 bitus. Tačiau man nepavyko iššifruoti “buferio” persiuntimo per SPI (DMA). Daugelis komandų susideda iš 8 bitų komandos ir 8, 16 ar daugiau bitų duomenų. Tačiau kiek supratau (gal klaidingai), kad pakeisti 8-16-24-32 bitų transliacijas reikia perkonfiguruoti SPI. Tačiau man gi reikia dažnai daryti 8+16 siuntimą ir tada perkonfiguruoti SPI? Nesamonė. Kitas metodas- aprašyti buferį ir nurodyti hardwarei ką ir kaip perduoti. Deja tas man nesigavo.
Todėl teko vietoje “navarotnų” metodų panaudoti tą pačia strategiją kaip ir AVR kontroleryje.

Nu ir aišku source kodas bei kompiliuotas hex kodas, hexas sukompiliuotas Atmel AT91SAM7S256AU serijos čipui

P.S. projektų numeracija atitinka numeriams mano kietam diske. Tai visiškai nesusije su straipsnių seka. Pvz. 14 projektas yra tuščias projektas su minimalia konfiguracija- kad pradedant naują projektą per daug nevargti. Imi 14 projektą, kopijuoji ir darai naują. Template vienu žodžiu.

AVR49: kitas grafinis LCD ILI9341

Šio LCD ekraniuko paleidimas užtrūko. Ir dėl kinų kaltės. Aprašyme buvo parašyta- maitinimas 5 arba 3V. Apžiūrėjau PCB- tikrai, stovi nedidelis reguliatorius, pajungus maitinimą viskas gerai- 3.3V stabilizuotas. Panašiai kaip ir mažesniam ekranėlyje kurį jau aprašiau. Tačiau viena subtilybė- kai gamino mažesnį ekraną, duomenų laiduose sumontavo rezistorius, todėl jungiant prie 5V MCU signalų lygiai daugmaž susitvarko. Ant didesnio ekrano PCB tų rezistorių nėra, todėl per duomenų šyną ir apsauginius diodus, ekrano kontroleris “užsimaitina” iki maždaug 5V. Kas baisiausia, kontroleris veikia- iš jo galima nuskaityti registrus. Netgi mano surastas softas nuskaito kontrolerio modelį ir programa praeina check-point. Bet taigi vaizdo tai nėra! Gal atitinkamai perprogramavus kontrolerį koks nors vaizdas ir atsirastu, bet datašytas sako- 5V niu-niu. Teko sudeginti milijardą nervinių ląstelių ir staiga ekranas pradėjo dirbti:

color LCD SPI ILI9341 AVR
Tas didesnis ekranas, su raudona plokštele tai 320×240 pix SPI ekraniukas su ILI9341 kontroleriu. Palyginkit seno straipsnio nuotrauką ir šią nuotrauką. Iškarto matosi, kad rezoliucija šio ekraniuko žymiai geresnė.

Aišku source kodas AVR šeimos procesoriukams, ir sukompiliuotas HEX skirtas mano universaliai PCB ir ATMEGA16 @12MHz. SPI dažnis maksimalus- 6MHz (Kiek parodė vėlesnis eksperimentas SPI dažnis galimas ir didesnis, LCD ekraniukas dirba ir su ~24MHz CLK dažniu. Todėl čia dažnis maksimalus kokį išspjauna mano ATMEGA16 plokštė). Naudojamas hardwarinis SPI.
ILI9341 LCD SPI source code AVR-ATMEGA16 ir hex.

AVR48B: lietingas savaitgalis

Biški lijo, biški tingėjau… O ir buvo knietulys pažaisti su spalvotu LCD ekraniuku. Todėl, prisimindamas savo seną kompiuterį ATARI, nutariau pasidaryti nedidelį Arkanoid (アルカノイド Arukanoido) kloną.
Kadangi tai nepilnos dienos kūryba, tai pilnas bugų ir klaidų. Bet šiaip sušildė širdį. 🙂

Kai kurie bugai priminė originalų atari variantą, tai gal juos reikės palikti. Jei pabaigsiu ir bus poreikis pas skaitytojus, paviešinsiu source kodą.

AVR 48: ST7735 grafinis LCD

Pajungsim prie mano universalios ATMEGA16 plokštės grafinį LCD ekraniuką iš eBayjaus.
LCD ST7735 with AVR ATMEGA16
Paprastas, pigus spalvotas 1.8″ TFT ekraniukas jungiamas per SPI. Pilnas eBay tokių ekraniukų. Kontroleris ST7735.
Internete pilna visokiausio softo, bet jis skirtas arba kitiems procesoriams, arba su arduino anstatu. O man reikėjo gryno paprasto GNU C. Tai teko kiek pavargti kol suklijavau iš kelių gabaliukų.
Navarotai tokie:
proporcinis ar monospace šriftas (tiesa, fonto duomenys 8 bitų aukščio), proporcinis šriftas tas pats kaip ir ant ARM eksperimento. Tiesa yra galimybė grubiai didinti šriftą. Ką ir rodo iliustracija.
Paišo grafinius primityvus: taškas, užtušuotas stačiakampis, stačiakampis, apskritimas, užtušuotas apskritimas, H ir V linija.
Priima duomenis (blob tipo) ir deda ant ekrano- galima įkelti paveikslėlius. Reikės kiek pavargti ir padaryti “penis harder” paveiksliuko iliustraciją. Priima “nekompresuotą” RGB (24bit) arba supaprastintą RGB (16bit).

Ir aišku source code bei kompiliuotas hex.

ST7735 LCD driver for AVR ATMEGA16, source code.

Laboratorinė maišyklė. Antra dalis

O dabar sudėtingas variantos to, kas jau buvo išbandyta senesniam straipsnyje. Gal galima padaryti magnetine maišyklę be mechanikos- tereikia sukurti besisukantį magnetinį lauką. Tokius laukus turi visi elektros motorai, tai gaunasi, kad mums reikia sukurti elektroninį motoro valdymą. Maišyklei reikia gero pradinio sukimo momento, gal būt “soft start”. Tai pasirinkau industrinį standartą- trys fazės. Gaunasi kaip ir standartinis lėktuvėlio modeliuko kontroleris, tačiau skirtumas, kad šis “dažnio keitiklis” visiškai asinchroninis, nes nėra nei holo jutiklių, nei srovės ar įtampos matavimo. Paprasčiausiai paprastas keitiklis.

Čia jums klasikinės trifazės iliustracija:
AVR trifazis generatorius
Bangos, t.y. fazės pasislinkusios viena kitos atžvilgiu per 120 laipsnių (1/3 apskritimo)
Ir pati banga yra sinusoidė. Todėl kontroleris (šį kartą AVR ATMEGA48V10) turėtų skaičiuoti sinusus. Tačiau trigonometrija pernelyg daug resursų reikalaujantis reikalas, todėl viską prastinam.
Continue reading →

ARM:0012 ADC

Prisikasėm prie šio procesoriuko ADC (analog to digital converter). Čia irgi biški iškilo problemų. Pagrindinė- rodos nereikia nurodinėti, kad ADC koja priskiriama specialiai periferijai, o ne standartiniam PIO. Tipo jei pasirenki ADC kanalą, tai viskas susikonfiguruoja automatiškai. Kažkas man čia neaišku.
Dar dėl ADC periferijos clock, tai tipo jis visada įjungtas ir neišsijungia. Rodos taip parašyta datasheete.

Nu nėra ką čia daugiau pridurti. Veikimo principas panašus kaip ATMEGOJE, tik papildomai yra ne tik paskutinio nuskaityto ADC kanalo registras, bet ir kiekvienas ADC kanalas turi savo “asmeninį” registrą kurį galima vėliau nuskaityti.

Nu ir aišku source kodas bei kompiliuotas hex kodas, hexas sukompiliuotas Atmel AT91SAM7S256AU serijos čipui.

ARM:0011 PWM

Vėl nuo “sudėtingų” einam link pačių paprasčiausių. Šį kartą pabandysim pasileisti hardwarinį PWMą. Dabar viskas tupi vėl pagrindiniam, main.c faile.

Atmel ARM SAM7S PWM

Mano LCD kontrastas valdomas su programiniu PWM. Reikėtu taip kvailai nedaryti, o panaudoti tikrą hardwarinį (kalbainiškai- aparatinį) PWM. Internete susiradau pavyzduką su PWM. Ten naudojamas PWM0 kanalas, ir jo galimos išėjimo kojos labai toli nuo mano LCD lizdo. Tuo tarpu PWM1 kanalo galimo kojos visai patogios. Todėl, kad palengvinti būsimos, pataisytos PCB projektavimą, nutariau užprogramuoti PWM1 kanalą. Source kode yra viskas palikta ir PWM0 kanalo programavimui. O peržvelgus abu variantus, iškarto pasidaro aišku kaip užprogramuoti likusius.
Programoje kiek tai bandoma paaiškinti kaip skaičiuojasi vienas ar kitas parametras- tikslas buvo 2kHz PWM signalas. Bet vistiek rekomenduoju pasiskaityti datašytą.

Kada padarys tokį kontrolerį kurio kojytės bus dar labiau nepririštos prie periferijos?

Aišku:
Atmel ARM SAM7S PWM example with source code and hex, hexas sukompiliuotas Atmel AT91SAM7S256AU serijos čipui.

ARM:0010 grafinis LCD

Tai palengvinta grafinio displėjau valdymo programa. Ji neturi daugybės opcijų ir šiaip ribota. Tai pagrinde lenko Radosław Kwiecień programa, aš ja kiek adaptavau mano stiliui ir prirašiau minimalistinę paprogramę proporciniam šriftui. Deja, šriftas tik 8 pikselių aukščio ir pozicionuojasi Y ašyje kas 8 pikseliai. X ašyje viskas gerai- galima pastumti per vieną pikselį.
Proporcinis šriftas nupaišytas pagal originalų tekstinių LCD šriftų vaizdelį, tik perdarytas proporciniui variantui. Čia man padėjo java programa iš AVR grafinių LCD paketo. Ten viduje failo yra nuorodos.

ARM SAM7S graphic LCD
Kadangi SAM7 turi daug kojų, tai pajungtas ir grafinis ir tekstinis LCD.

Mano turimas LCD tai pats pigiausias kiniškas LCD su KS0108 kontroleriu. Jo vaizdelis invertuotas, todėl jau ne kartą minėtąpenis harder” paveiksliuką teko invertuoti.

Horse penis harder on small LCD LOL
Kadangi sumažinto teksto neįmanoma perskaityti, šukį be kurio paveiksliukas negalioja perrašiau naudodamas savo teksto rašymo paprogrames. Dar viršuje rodomas laikas nuskaitytas iš RTC mikroschemos.

Šio posto source code ir hexas:
Grafinio LCD ARM SAM7S source code ir hex, hexas sukompiliuotas Atmel AT91SAM7S256AU serijos čipui.