Форум » Для начинающих. » Проблема ЧМЗ » Ответить

Проблема ЧМЗ

Алексей: У начинающих часто возникают вопросы, связанные с работой с портами контроллера. Проявляется это в непредвиденном изменении состояния одного или нескольких выводов контроллера. Очень часто данная проблема связана с непониманием работы процесса чтение\модификация\запись в приложении к работе с портами... Приведу пример, поясняющий это... В частности товарищ Galrad задал вопрос КЕА и пока не получил ответа В общем то этот пример и есть ответ на его вопрос... В качестве отладчика используется протеус, ссылка на проект в конце поста... Схема проста Увеличить ;**************************************************************************** ; Пример для понимания работы ЧМЗ и связанных с этим фокусов... ;**************************************************************************** [pre2] __config 1F01H #include <p16F627A.inc> errorlevel -302 ;============================================================================ ; Определение названия и положения регистров общего назначения. ;============================================================================ cblock 20h ; начальный адрес области данных endc ;============================================================================ ; START ;============================================================================ org 0x000 ; Вектор сброса ;============================================================================ ; Подготовительные операции ;============================================================================ START bcf STATUS, RP0 bcf STATUS, RP1 clrf PORTA clrf PORTB clrf T1CON clrf T2CON clrf CCP1CON clrf RCSTA movlw 07h movwf CMCON bcf INTCON,GIE bsf STATUS, RP0 clrf TXSTA clrf TRISA clrf TRISB movlw b'00001111' movwf OPTION_REG bcf STATUS, RP0 [/pre2] ;============================================================================ ; С этого момента пошагово выполняем программу, внимательно и с интересом ; наблюдаем за тем, что происходит в симуляторе... Получим результат не тот, ; что ожидаем! И такое происходит не только в протеусе!, но и реальном ; железе!!! ;============================================================================ [pre2]main clrf PORTB ; сброшу порт в нули чтобы bsf STATUS,RP0 ; быть уверенным что в выходных clrf TRISB ; защелках записаны 0 bcf STATUS,RP0 ; BsF PORTB,3 ; Понадобится позже... bsf STATUS,RP0 ; Теперь переключу часть выводов movlw b'01001001' ; на вход movwf TRISB ; bcf STATUS,RP0 ; bsf STATUS,RP0 ; Опять переключу порт на выход clrf TRISB ; убедиться что все пока нормально bcf STATUS,RP0 ; В ВЫХОДНЫХ ЗАЩЕЛКАХ ЧИСЛО .8!!! ; Пока проблем не наблюдается :) bsf STATUS,RP0 ; Опять переключу часть выводов movlw b'01001001' ; на вход. За счет резисторов movwf TRISB ; на этих выводах сформируется bcf STATUS,RP0 ; логический 0 или 1... ;============================================================================ ; А ТЕПЕРЬ, ВНИМАНИЕ, ФОКУС!!! Помните?, в защелках записано число .8!!! ;============================================================================ BsF PORTB,1 ; модифицирую порт бит ориентированной ; командой... По логике должен ; измениться только один 1 бит! И в ; результате должно бы получиться .10 bsf STATUS,RP0 ; Опять переключаю порт на выход clrf TRISB ; И ЧТО Я ВИЖУ В ПОРТУ? Совершенно bcf STATUS,RP0 ; не то, что ожидал... А ожидал .10 ; Даже скинулся 3 бит!!! а он был ; установлен мной ранее!!!!!!!!!! И ; я его не трогал!!! ;============================================================================ ; Что мы теперь видим в регистре PORTB? По идее должны бы видеть число ; .10... Была ведь записана .8 и в дополнение я поднял 1 бит... Что в ; в общем случае дает .10... На самом деле видим совершенно другую ; картину, .67, почему??? Причем 3 бит был поднят! а сейчас нет! ; Все дело в способе работы с регистрами в контроллере. Дело в том, ; что даже бит ориентированные команды не работают с одним единственным ; битом регистра. Сначала производится чтение из регистра, затем модификация ; всего байта, независимо от того, какая команда применяется, и только затем ; запись в регистр всех 8 бит с одним модифицированным. Вроде бы ничего ; такого, и проблем никогда с этим не возникает... Но вот такое творится ; только при работе с регистрами PORTx... И тут дело в том, что чтение ; производится исключительно с "выводов" контроллера, а вот запись производится ; в выходные защелки регистра. Т.е. получается что вместо одного регистра ; PORTx фактически имеем целых два! Один из них это выходные защелки порта, ; которые отключаются от физических выводов при работе на ВХОД. Но тем не ; менее чтение происходит "непосредственно" с выводов порта... Таким образом ; имеем, ЕСЛИ ПОРТ ХОТЯ БЫ ЧАСТИЧНО РАБОТАЕТ НА ВХОД, ЛЮБАЯ! КОМАНДА, ; ИЗМЕНЯЮЩАЯ ЗНАЧЕНИЕ РЕГИСТРА PORTX, БУДЕТ РАБОТАТЬ ТАК: ; 1. Чтение всего порта "непосредственно" с выводов контроллера ; 2. Затем его модификация. Причем не важно как мы работаем с портом! даже ; бит ориентированными командами BSF и BCF... ; 3. Ну и запись... Но запись производится не непосредственно на выводы ; порта :), а естественно в выходные защелки. ; Т.е. получается довольно тернистый путь, читаем с одного места, а пишем в ; другое... Что и может вызвать большие затруднения у начинающих программистов. ; Добавлю еще, что такая ситуация наблюдается до 16 серии включительно... За ; исключением новых контроллеров PIC16F(LF)xxxx. В них и более старших ; семействах уже введен дополнительный регистр LATx. Он и есть те самые ; выходные защелки. Чтение же порта происходит из регитра PORTx... В принципе, ; в ситуациях не связанных с ЧМЗ, без разницы к какому регистру обращаться. ; Т.о. разработчики устранили проблему ЧМЗ, но чтобы понимать и в старшем ; семействе откуда надо читать и куда писАть о проблеме ЧМЗ знать надо... ;============================================================================ goto main end[/pre2] Здесь лежит проект в протеусе, созданный специально для данного примера... Использовать в Обмене и статьях КЕА запрещено

Ответов - 68, стр: 1 2 All



полная версия страницы