PIC16F628A: PORTA se chová divně, bsf, bcf a btfss nefunguje

Ahoj,
mohl by mi prosím někdo poradit? Napsal jsem teď jeden prográmek pro 16F628A na 20 MHz, ale PICka se v reálu chová trochu divně. PORTB funguje perfektně. PORTA (celý ve výstupu) funguje divně. PIC je nová, určitě nemůže být poškozená.

Nefungující kód:

[code]#define zarizeni_pow PORTA,0
#define zarizeni_hdd PORTA,1
#define zar2_gnd PORTA,2
#define zar2_vcc PORTA,3
#define zar2_res PORTA,4

bsf	zarizeni_pow
nop
bsf	zarizeni_hdd
nop
bsf	zar2_gnd
nop
bcf	zar2_vcc
nop
bcf	zar2_res
nop[/code]

Kód, který funguje:

movlw b'00000111' movwf PORTA
První kód dělá naprosté hlouposti, movlw a movwf funguje bezvadně.

Taktéž nefunguje následující kód:

	btfss	zar2_gnd

Při testování bitu se PICka také chová dívně - jako by na “zar2_gnd” bylo neustále 0 a to i když na něj zapíšu 1 pomocí movlw, movwf PORTA. Nevíte prosím, co dělám špatně? TRISA mám samozřejmě nastaveno dobře.

Předem moc děkuji.
Bedřich L.

Typický RMW problém, řešilo se to třeba tady: [forum.mcontrollers.com/t/pic16f1939-pri-32-mhz-porty-nestihaji-po-sobe-jdouci-operace/2025/1)

Řešení je udělat si stínový registr PORTA v paměti a tam provádět bitové operace. Potom to pomocí MOVF, MOVWF šoupnout na port.

Ahoj,
díky moc, zkratka R-M-W mě nakopla správným směrem a teď už jsem k tomu našel další informace. O tom problému jsem tak nějak věděl, resp. jsem věděl, že mám mezi bitové operace na portech dávat „nop“. Ten tam ale mám, tak mi nejde do hlavy, proč to nejede. Rád bych to vyřešil jednoduše bez nutností nějakých komplikací a přepisoání programu a jelikož mi moc nejde o rychlost, tak jsem se rozhodl těch „nop“ dát více. Věřte ale, ani toto nefunguje:

bsf zarizeni_pow nop nop nop nop nop nop nop nop nop nop bsf zarizeni_hdd nop nop nop nop nop nop nop nop nop nop bsf zar2_gnd nop nop nop nop nop nop nop nop nop nop bcf zar2_vcc nop nop nop nop nop nop nop nop nop nop bcf zar2_res nop nop nop nop nop nop nop nop nop nop

PIC16F628A mě teda dost zklamala. PIC16F877A, kterou jsem programoval nedávno, tímto netrpěla.
Bedřich L.

Prostě něco děláš špatně, to je to celý, procesor za to nemůže ani náhodou. Neošetřené vstupy, chybně blokované napájecí napětí, přetížení výstupů. Dej sem skutečné schéma, kompletní program a já ti nejspíš řeknu, kde tu chybu děláš. Jinak se nemáme o čem bavit. Nikdy jsem nebyl nucen použít instrukci NOP při V/V operaci, natož jich tam dávat kaskádu. Struktura tebou jmenovaných obvodů je setsakramentsky podobná. Ve většině případů se chovají naprosto stejně.

Předpokládám, že jsi nevypnul komparátor, pak se to chová obvykle tak, jak popisuješ.
Jinak jsi stále nepochopil základní princip. Čtení portu, konfigurovaného jako vstupní není obecně závislé na hodnotě, kterou jsi před tím na daný port konfigurovaný jako výstupní odeslal.
Představ si, že máš na bitu portu rezistor 1Kohm proti zemi. Když na tento port jako výstupní odešleš logickou"H" tak máš na výstupu logickou “H”. V okamžiku, kdy tento port přepneš jako vstupní, tak máš okamžitě na tomto vstupu logickou"L" a také ji tam procesorem přečteš. Lze říct, že když na výstupní port odešleš nějakou hodnotu, tak ji již nikdy nejsi schopen se zárukou správnosti z toho portu přečíst zpět, protože čteš stav vnějšího prostředí.

Já chápu, že Budla zapíše hodnotu na pin a potom ho pomocí BTFSS čte a nepřenastavuje ho jako vstup. Na tomhle nevidím nic špatnýho.

Já osobně jsem se na PIC16 ještě s RMW nesetkal, ale PIC18 mě hned na poprvé napálila.

Budla: co máš navěšenýho na pinech?

Na portech mám dva tranzistory BS170, jeden IRF9540 (gate je přímo na port, vše to je na kontaktním poli, a pro zjednodušení tam nedávám odpor) a jednu LED s odporem, která je katodou na port. Jinak řečeno tam není žádná velká zátěž.

Port ve výstupním režimu čtu naprosto běžně, vždy jsem to tak dělal. Vždyť se ve výstupu chová jako jakýkoliv registr.

Přesně tak. Blikám s LED pomocí timeru a dávám různé zpoždění pro periodu, kdy je LED vypnuta nebo zapnuta a v programu potřebuji nejprve zjistit, zda LED aktuálně svíti (minule byla odeslána log. 0) nebo nesvítí (minule odeslána log. 1).

Ano, to jsem neudělal. V tom asi bude ten zakopaný pes. Zkontroloval jsem si, že 16F628 nemá ADC, který by to chtělo vypnout a na komparátor jsem zapomněl. Podle datasheetu se komparátor vypne takto, že ano: movlw b'00000111' movwf CMCON

Moc Vám děkuji za rady.
Bedřich L.

Myslím si, že když dáš do gate tranzistorů rezistory cca 2K2, tak problém RMW zmizí. Nejspíš to vzniká dík parazitní kapacitě řídící elektrody.

Ale to tiez nieje korektne riesenie ale budiš…

Korektní by bylo použít budiče pro FET, znáš něco lepšího?

Já na PIC16F1936 používám výstpní pin jako nábojovou pumpu.
Mám tam napřímo napojený 2 kondenzátory 100uF a problém s tím není. Zapisuji do do portu ne do latch.

Záleží jak velký napětí tím fetem spíná. Při uzavírání vybíjí kapacitu D - G a to nemá PIC rád.

Celý problém byl v zapnutém komparatoru. Po přidání kódu:

movlw b'00000111' movwf CMCON
vše funguje bez jakýkooliv dalších úprav HW nebo SW. Díky moc za rady.

Bedřich L.