Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Пак проблеми с PORTA- r-m-w PIC16
http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=5937
Страница 1 от 1

Автор:  dan [ Съб Юли 12, 2008 5:52 am ]
Заглавие:  Пак проблеми с PORTA- r-m-w PIC16

Прочетох във форума и в шитовете на майкрочип за проблема read-modify-write, но не можах да напиша код, който при сетването на даден бит, да не ми изключва друг.
Проблема конкретно е следния:
Трябва при команда от вън да се сетне PORTA,4. Т.к. обаче PORTA,5 може да се промени от програмата, аз няма как да използвам инструкцията:
Код:
MOVLW     B'00110000'
MOVWF     PORTA
или
Код:
MOVLW     B'00010000'
MOVWF     PORTA


Затова реших да чета PORTA,5 и да правя преходи в програмата. Но по някаква причина порта се чете винаги '0', даже когато диода към PORTA,5 свети.

Та как всъщност бих могъл да се справя с това. Времето между включването на двата пина е много- секунди.

Автор:  plameniv [ Съб Юли 12, 2008 8:11 am ]
Заглавие:  Re: Пак проблеми с PORTA- r-m-w PIC16

dan написа:
Прочетох във форума и в шитовете на майкрочип за проблема read-modify-write, но не можах да напиша код, който при сетването на даден бит, да не ми изключва друг.
Проблема конкретно е следния:
Трябва при команда от вън да се сетне PORTA,4. Т.к. обаче PORTA,5 може да се промени от програмата, аз няма как да използвам инструкцията:
Код:
MOVLW     B'00110000'
MOVWF     PORTA
или
Код:
MOVLW     B'00010000'
MOVWF     PORTA


Затова реших да чета PORTA,5 и да правя преходи в програмата. Но по някаква причина порта се чете винаги '0', даже когато диода към PORTA,5 свети.

Та как всъщност бих могъл да се справя с това. Времето между включването на двата пина е много- секунди.

Хехе, малко си чел върни се пак в даташиит и виж какво прави инструкция BSF и BCF !!!
Тези инструкции който си ползвал са за байтов запис а не битов !!!

Автор:  dan [ Съб Юли 12, 2008 8:50 am ]
Заглавие: 

май не съм обяснил какво точно съм правил:
първоначално започнах така:
Код:
BTFSS   STATUS,0
BSF     PORTA,5

;===========
;stava tuk kakvoto stava
;===========

BSF       PORTA,4


Целта ми е ако STATUS,0 е нула, да светне диода, свързах към PORTA,5. Така и става. Проблемът е там, че щом пусна диода, включен към PORTA,4, другия угасва.
А байтовите инструкции, показани в предния ми пост, не знам как мога да ги използвам, при условие, че резултата от изпълнението на програмата е винаги различен и не мога да знам каква стойност точно да заредя в акумолатора и да я пратя към PORTA.
Това, което намерих като решение в един сайт е да използвам shadow променлива, която постоянно да пази последното съдържание на PORTA и при всеки запис на порта да се променя тя, след което да се изпраща към порта.

На друго място намерих следното предложение :
Цитат:
andwf portb, w ; this is fine
iorwf portb, w ; this is fine

но по неизвестна за мен причина не сработи- единия диод пак се изгасяше.
Всъщност не знам дали iorwf и andwf също работят на принципа r-m-w, защото ако четат от порта става безпредметно да ги използвам.

Разбира се, всичко, което съм написал е или прочетено, или мои размишление=> възможно е да греша :)

Автор:  solenoid [ Съб Юли 12, 2008 9:17 am ]
Заглавие: 

И на мен ми късаха нервите по едно време тия R-M-W пинизи. Доколкото си спомням, направо смених изходния порт и човърках нещо по регистрите за настройка как да се държи. Нещо не съм наясно, за какво се налага тази дивотия. Да изпишеш една страница с инструкции само за да напишеш нещо в порта.. :roll:

Автор:  dan [ Съб Юли 12, 2008 10:49 am ]
Заглавие: 

Намерих решение :idea: използвам "сенчест"регистър(по-горе писах за него- shadow register). Ще опиша подробно решението за тези, които в бъдеще ще се сблъскат с този проблем:
В сенчестия регистър(знам, че не е правилно да го наричам така, но мен ме кефи) записвам състоянието на порта след всяка промяна(запис) в него.
Ако искам да запиша '1' на някой пин, в променливата KOMANDA записвам единица в съответния по номер бит, а всички останали битове са нули. След това извършвам логически ИЛИ между командата и сенчестия регистър(чиято стойност е запазена в акумулатора W). По този начин въпросния бит става задължително '1', а всички останали запазват състоянието си.
Т.е. вместо командата
Код:
BSF    PORTA,4
записвам следния код:
Код:
      MOVLW   B'00010000'
      MOVWF   KOMANDA
      
      MOVFW   SHADOW
      IORWF   KOMANDA,0

      MOVWF   SHADOW   ;ZAPAZVAM NOVOTO SYSTOQNIE NA PORTA W SHADOW REGISTYRA
      MOVWF   PORTA


А за да нулирам даден бит в KOMANDA, в съответния по номер бит записвам '0', а всички останали '1'. После извършвам логическо И между командата и сенчестия регистър(чиято стойност е запазена в акумулатора W). По този начин въпросния бит става задължително '0', а всички останали запазват състоянието си.
Т.е. вместо командата
Код:
BCF    PORTA,4
записвам следния код:
Код:
MOVLW   B'11101111'
      MOVWF   KOMANDA
      
      MOVFW   SHADOW
      ANDWF   KOMANDA,0

      MOVWF   SHADOW   ;ZAPAZVAM NOVOTO SYSTOQNIE NA PORTA W SHADOW REGISTYRA
      MOVWF   PORTA


В гореописания код може да се избегне променливата KOMANDA, но аз я използвам за по-добра четливост и яснота на кода. Вместо нея може директно да се използват стойността й и инструкциите IORLW и ANDLW.

Автор:  ji4ka [ Съб Юли 12, 2008 12:47 pm ]
Заглавие: 

И за мен това решение със шадоу регистъра си е най-добре за ПортА. Ако искаш да променяш ПортА всъщност си бъзикаш с каквито инструкции искаш сянката а после само я прехвърляш в порта. И да не се забравя ,че "рефрешването" трябва да се прави веднага след всяко четене на ПортА. Това е цената на съчетаването на цифров с аналогов вход.

Автор:  MidNighT_SpiRiT [ Нед Юли 13, 2008 12:29 pm ]
Заглавие: 

Не можах да разбера защо не ползваш битови инструкции върху "сенчестия" регистър? Како каза жичката с него всичко можеш да правиш. И аз имах подобен проблем, изхабих много нерви, но така и не разбрах как да избегна този проблем и реших да направя същото като теб. Няма ли да ти бъде по-лесно ако направиш тия неща с макроси, вместо всеки път да ги пишеш, може да сбъркаш, пък и не е четливо. Ето как го направих аз:
Код:
#define     RTS         myPORTA,3
...
SET_RTS     MACRO
            bsf         RTS
            movf        myPORTA,w
            movwf       PORTA
            ENDM
           
CLR_RTS     MACRO
            bcf         RTS
            movf        myPORTA,w
            movwf       PORTA
            ENDM

Само не забравай после, че макросът не е единична инструкция като ползваш инструкцийте за условен преход btfss, btfsc!

Автор:  forest_gump [ Нед Юли 13, 2008 1:42 pm ]
Заглавие: 

Нямаше ли начин да се оправят хардуерно нивата на изходите и входовете на порта, тоест когато порта е подал към краче 1-ца неговото ниво да е около 4.5волта когато е натоварено , според мен точно това е описано във даташита на майкрочип r-m-w примера, идеята им е че ако по някаква причина си натоварил крачето повече входният буфер при четенето може да приеме нивото като нула нищо че в изходният е записана единца, така при последващото вписване във изходният буфер ще се запише нула. Лично аз никога съм нямал подобни проблеми ако хардуера е разчетен добре!

Автор:  ji4ka [ Нед Юли 13, 2008 2:40 pm ]
Заглавие: 

Проблема не е в натоварването - просто когато пина се дефинира като АЦП, входния му цифров буфер се забранява хардуерно и винаги се чете 0. Прави се за да не стигне до него аналогов сигнал и да текнат големи токове през ЦМОС-а. Обикновено тази ситуация се случва когато пиновете се ползват комбинирано и като цифрови и като аналогови. Също и при ПортА,4 който е отворен дрейн и не може "сам" да си поддържа 1-ца.

Автор:  relsys [ Нед Юли 13, 2008 7:54 pm ]
Заглавие: 

Е за т'ва си има 18 серия.... не виждам защо е необходимо да се мъчите с 16....

Автор:  dan [ Пон Юли 14, 2008 9:17 am ]
Заглавие: 

Да, замислих се за макрос, но искам да го направя така, че да не дефинирам отделен макрос за всеки пин, а да ползвам един "общ" макрос, и променлива за номера на бита. В С знам как да го направя, но на асемблер не ми е много ясно. Ще трябва да помисля.
Цитат:
Проблема не е в натоварването - просто когато пина се дефинира като АЦП, входния му цифров буфер се забранява хардуерно и винаги се чете 0. Прави се за да не стигне до него аналогов сигнал и да текнат големи токове през ЦМОС-а. Обикновено тази ситуация се случва когато пиновете се ползват комбинирано и като цифрови и като аналогови. Също и при ПортА,4 който е отворен дрейн и не може "сам" да си поддържа 1-ца.

Доколкото разбрах, проблема r-m-w не съществува само при използване на един и същи порт като цифров и аналогов, но също така и когато пинове в един порт се използват като входове и изходи. В момента на същия контролер, но в друга схема нямам никакви проблеми с r-m-w. Там просто всички пинове на порта са изходи... Може и да бъркам.
В случая PORTA,4 не е отворен колектро- контролера е Pic16f684. Нивото на '1' на изхода е 5V V, т.е. причината надали е в кофти хардуер.

Автор:  MidNighT_SpiRiT [ Вто Юли 15, 2008 12:02 am ]
Заглавие: 

Най-добре е да се избягва да се използва порт А за изходи, изводите ги ползвай или като цифрови входове или като аналогови. Аз използвах същия контролер и проблемите бяха аналогични.

Автор:  ji4ka [ Вто Юли 15, 2008 12:53 am ]
Заглавие: 

dan написа:
В случая PORTA,4 не е отворен колектро- контролера е Pic16f684. Нивото на '1' на изхода е 5V V, т.е. причината надали е в кофти хардуер.

При този модел вече ги има ANSEL битовете (то и при предишните ги е имало но не са били достъпни). Всичко си е ОК с контролерчето , чети внимателно даташита. Виж дали някоя друга периферия не ресетва пина. В 99% проблема е сбъркан софт.
Не си струва макроси да пишеш при толкова малко памет, даже по-голяма каша може да стане. По-добре си нарисувай времедиаграма на състоянието на пина (вход-изход-аналог) и си програмирай внимателно преходите особено ако го товариш с няколко функции.

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/