Доброго времени суток. Снова я со свои программным UART-ом. Никак не получается написать прием на прерываниях. Ниже код, в нем есть закоментированый кусок передачи лат. символа "А", он работает нормально. Тоесть передача работает нормально (она пока не на прерываниях, всему свое время). Проблема возникает, когда пытаюсь передавать символ, который принял (в прерывании) - передает не то, что отправлял в терминале. Просьба подсказать, где ошибка. Спойлер
Код:
list p=16f629 __config _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDTE_OFF & _FOSC_INTRCIO include p12f629.inc
#define RX_ 2 #define TX_ 1 #define RX GPIO,RX_ ; В качестве приемника может быть только эта ножка #define TX GPIO,TX_ ; А вот в качестве передатчика можем назначить любую, даже ту же
#define BITS_DELAY .30 ; Задержка длинной 1 бит - 104 мкс при 9600 бод и частоте 4 МГц #define RX_Complete 0 ; Флаг завершения приема
; В прерывании только прием байта (побитно), и выставление флага окончания приема, который уже анализируется в основном цикле ;====================== Soft_UART udata_shr w_temp res 1 status_temp res 1 TX_byte res 1 RX_byte res 1 UART_counter res 1 delay_counter res 1 Flags res 1 ;====================== push macro ; movwf w_temp ; swapf STATUS,w ; movwf status_temp
movwf w_temp ; save off current W register contents movfw STATUS ; move status register into W register movwf status_temp ; save off contents of STATUS register endm
pop macro ; swapf status_temp,w ; movwf STATUS ; swapf w_temp,f ; swapf w_temp,w
movfw status_temp ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents endm ;====================== RESET_VECTOR code 0h goto Ini ;====================== ISR code 4h ; Вектор прерывания Interrupt_Heandler push ; Сохраним контекст btfsc INTCON,INTF goto Start_bit ; Если есть флаг внешнего прерывания - пришел старт-бит btfsc INTCON,T0IF goto Receive_bit ; Если флаг таймера, значит принимаем очередной бит посылки End_Interrupt_Heandler pop ; Восстановим контекст retfie ;====================== Start_bit bcf INTCON,INTF ; Сбросим флаг внешнего прерывания movlw .191 ; Перезапишем таймер для периода переполнения в 156 мкс (середина 1 бита данных) movwf TMR0 movlw .8 ; Загрузим количество принимаемых битов movwf UART_counter clrf RX_byte ; Очистим приемник bcf INTCON,INTE ; Запрещаем внешнее прерывание (4 бит) bsf INTCON,T0IE ; Разрешаем прерывание по переполнению Таймера 0 (5 бит) bcf INTCON,T0IF ; Сбросим флаг переполнения Таймера 0, он почти наверняка переполнился, пока мы ждали старт-бит goto End_Interrupt_Heandler ;====================== Receive_bit movlw .211 ; Перезапишем таймер для периода переполнения в 104 мкс movwf TMR0 bcf INTCON,T0IF ; Сбросим флаг переполнения Таймера 0 bcf STATUS,C ; Сбросим бит переноса rrf RX_byte ; Задвигаем сброшеный бит переноса в приемный регистр btfsc RX ; А теперь проверяем, что на самом деле надо было туда задвинуть bsf RX_byte,7 ; Если 1, надо срочно подкорректировать, ведь мы задвинули 0 decfsz UART_counter ; Весь байт принят ? goto End_Interrupt_Heandler ; Нет, идем принимать следующий бит bsf Flags,RX_Complete ; Поставим флажок окончания приема байта bcf INTCON,T0IE ; Запрещаем прерывание по переполнению Таймера 0 (5 бит) bsf INTCON,INTE ; Разрешаем внешнее прерывание (4 бит) для приема следующего старт-бита goto End_Interrupt_Heandler ; На выход ;====================== Ini clrf Flags ; Сбросим все флаги movlw b'111111' ; Заранее установим необходимые уровни на выходах, чтобы в момент переключения с входов на выходы му уже имели на них нужные значения movwf GPIO ; Init GPIO banksel OSCCAL ; Bank 1 call 3FFh movwf OSCCAL if RX_ != TX_ bcf TX ; Настроим TX на выход endif movlw b'11000000' ; Подтягивающие резисторы включены, внешнее прерывание по переднему фронту, тактирование Таймера 0 от внутреннего генератора, пределитель 1 к 2, что дает 512 мкс на частоте 4 Мгц movwf OPTION_REG banksel GPIO ; Bank 0 movlw b'00000111' movwf CMCON ; Выключим аналоговый компаратор movlw b'10010000' ; Разрешаем прерывания вообще (7 бит) и внешнее прерывание (4 бит) movwf INTCON ;====================== ; movlw 'A' ; call Send_TX_byte Main ; goto Main
btfss Flags,RX_Complete ; Анализируем флажок приема байта goto Main ; Нет флажка - нет принятого байта movfw RX_byte ; Засунем принятый байт в рабочий регистр call Send_TX_byte ; И отправим назад bcf Flags,RX_Complete ; Скинем флажок принятого байта goto Main ;====================== Send_TX_byte ; Подпрограмма передачи 1 байта bcf INTCON,GIE ; Запрещаем прерывания if RX_ == TX_ banksel TRISIO ; Bank 1 bcf TX ; Настроим TX на выход banksel GPIO ; Bank 0 endif ;---------- bcf TX ; Шлем старт бит movwf TX_byte ; Загрузим передавемый байт movlw .8 ; Загрузим количесвто передаваемых битов movwf UART_counter nop Transmit_Next_Bit nop call Delay_1bit ; Длинной 1 бит rrf TX_byte ; Продвигаем в бит переноса все биты, начиная с младшего btfsc STATUS,C ; Проверяем, что выдавилось в бит переноса bsf TX ; Если 1, выставляем 1 на ТХ btfss STATUS,C bcf TX ; Если 0, выставляем 0 на ТХ decfsz UART_counter ; Весь байт отослан ? goto Transmit_Next_Bit ; Нет, идем слать следующий бит call Delay_1bit ; Задержка длинной 1 бит nop nop nop nop nop bsf TX ; Шлем стоп-бит call Delay_1bit ; Задержка длинной 1 бит ;---------- if RX_ == TX_ banksel TRISIO ; Bank 1 bsf TX ; Настроим ножку на вход banksel GPIO ; Bank 0 endif bcf INTCON,T0IF ; Сбросим флаг переполнения Таймера 0 bcf INTCON,INTF ; Сбросим флаг внешнего прерывания bsf INTCON,GIE ; Разрешаем прерывания return ;====================== Delay_1bit movlw BITS_DELAY ; 104 мкс для 9600 бод movwf delay_counter Loop_Delay decfsz delay_counter goto Loop_Delay return
end
Последний раз редактировалось Пока_без_кота Вт авг 23, 2016 12:00:32, всего редактировалось 1 раз.
Снова повторяю напоминание - необходимо использовать штатный шаблон для обработчика прерываний ( ; MOVWF W_TEMP ; save off current W register contents ; MOVF STATUS,w ; move status register into W register ; MOVWF STATUS_TEMP ; save off contents of STATUS register
здесь собственно прожка
; MOVF STATUS_TEMP,w ; retrieve copy of STATUS register ; MOVWF STATUS ; restore pre-isr STATUS register contents ; SWAPF W_TEMP,f ; SWAPF W_TEMP,w ; restore pre-isr W register contents ; RETFIE ; return from interrupt ) ИБО... W и STATUS требуют предварительного сохранения и последующего восстановления! а чего у Вас в макросах (push & pop)? Это минимум - глубше не вникал.
Помимо прочего не рекомендую злоупотреблять #define в тех случаях, когда более оправданно-понимаемо применение стандартных директив equ и других...
То книжка от вредоносного СУСАНИНА - ибо копируется в программный стек содержимое W и STATUS без разворотов, а вот при восстановлении хитрый SWАP применяется для того, чтобы содержимое флажков в STATUS не испортить прямым загрузом W из регистра временного хранения (точно по каким соображениям - ШКЛЕРОЗЬ - смотреть конспехты надо /сейчас мозги АВРкой забиты).
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Сделал по-вашему, ничего не изменилось. Скорее всего дело не в этом, я где-то в алгоритме или его реализации накосячил. Что уже обнаружил и исправил: Внешнее прерывание перенастроил по переднему фронту (установил 6 бит в OPTION при инициализации). Но это еще не все, есть что-то еще. Алгоритм следующий: 1. Жду прерывание на внешней ноге. 2. Захожу в обработчик по внешнему прерыванию, настраиваю таймер на прерывание через полтора бита (середина 1 бита данных), инициализирую счетчик битов, запрещаю внешнее прерывание, разрешаю прерывание по таймеру. 3. Захожу в обработчик по прерыванию таймера, настраиваю таймер на перывание через 1 бит, принимаю бит, уменьшаю счетчик, если не 0, просто выхожу. 4. Если счетчик 0, выставляю флажок окончания приема, запрещаю прерывание по таймеру, разрешаю внешнее прерывание для следующего старт бита.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Верно. Только кто ж будет разбираться с этим дальше ? Тут действующих программистов под PIC - полтора человека :) А PIC12F1822 стоит дешевле, чем то время, что они потратят на анализ вашего кода.
... А PIC12F1822 стоит дешевле, чем то время, что они потратят на анализ вашего кода.
А Вам отличия по ассемблеру для PIC12F1822 известны? Человек еще с "стандартным среднемладшим" еще не разобрался, а тут гибрид 18-й серии. Как по структуре ядра, так и по системе команд (не говоря уже о необходимости иметь программатор с регулировками напряжения прошивки и соответствующие дополнения по самой IDE - в "штатном" 8.92 это семейство только начинает рассматриваться к применению). Да и не у всех доступ к столь широкому ассортименту имеется.
Закончу тест-заготовку под WS2812 можно будет и отвлечся...
Заголовок сообщения: Re: Вопросы начинающих PIC ASM
Добавлено: Вт авг 23, 2016 07:43:00
Модератор
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4510 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Вы пишите о проблеме с передачей :
Пока_без_кота писал(а):
Проблема возникает, когда пытаюсь передавать символ, который принял (в прерывании) - передает не то, что отправлял в терминале. Просьба подсказать, где ошибка
А алгоритм приводите приёма :
Пока_без_кота писал(а):
1. Жду прерывание на внешней ноге.2. Захожу в обработчик по внешнему прерыванию, настраиваю таймер на прерывание через полтора бита (середина 1 бита данных), ...........
Как это понимать ? И в чём конкретно проблема, в передаче или приёме ?
Как это понимать ? И в чём конкретно проблема, в передаче или приёме ?
Прошу прощения, нечетко выражаю мысли. Проблема именно в приеме. Передача у меня реализована пока не в прерыаниях, она уже опробована и с ней проблем нет, у меня есть в программе закомментированые строчки:
Код:
; movlw 'A' ; call Send_TX_byte Main ; goto Main
Если их раскомментировать, то в этом месте происходит передача ASCII кода англ. символа "А" и зацикливание программы, из чего я делаю вывод, что передача у меня работает корректно. Проблема в том, что если я включаю прием на прерываниях, то назад в компьютер передается не тот символ, который я отправлял в контроллер. Значит проблема в приеме
Возможно ошибка не в прерывании, а в согласовании обмена (принятом протоколе для связи МК и ПК). Принимать/отправлять "просто так" в компе только простейшие терминальные прожки могут.
А может и алгоритм не совсем корректен - включи логический анализатор(в МПлабе) и посмотри чего там происходит в пошагово в дебаггере.
Ну, на стороне ПК с прогой проблем я думаю нет, потому что когда прием был написан не на прерывании мне контроллер возвращал тот символ, который я ему отправлял. А дебагером я и отлаживал сперва (прежде чем вопить здесь о помощи ), НОП-ы ставил как раз для того, чтобы подобрать точные задержки при передаче (104 мкс между битами). При отладке в дебагере у меня точно выдерживаються все временные интевалы. Процесс отладки выглядит так: 1. Запускаю прогу на выполнение, жду немного, ставлю на паузу. 2. Выставляю 1 бит в INTCON. Опять запускаю на выполнение. 3. Захожу в прерывание по INT (стоит брекпоинт), запускаю секундомер, выхожу. 4. На момент считывания бита по таймеру у меня стоит точка отладки, до нее от момента входа в прерывание INT ровно 156 мкс. 5. Потом между моментами считывания бита по переполнению таймера у меня ровно 104 мкс. Стоп-бит я не ловлю.
Анализатор векторов и сама обработка прерываний весьма неудачна. Возможны "гонки" источников прерываний - при исполнении внешнего прерывания "перекрывается" таймер и наоборот. Лучше использовать флаг-транслятор вместо INTCON,T0IF (T0IF лишь отметка времени, а требование исполнения - дополнительный флаг, сбрасываемый уже исполнительной прожкой). Да и обращение с самим таймером - смена значения "на лету" не есть хорошо - сначала стоп счета, затем запись и затем пуск будет стабильнее работать (здесь нет буфера для синхронного переноса данных). При необходимости оперативного изменения "плавающего коэффициента счета" у ПИКа используется TMR1 в режиме "Сброс TMR1 триггером модуля CCP"
Анализатор векторов и сама обработка прерываний весьма неудачна...
Спасибо, переделал, все работает !!!! Сижу и думаю, как я мог такое написать, ведь действительно источники прерываний "перекрывали" друг друга. Просто до этого не имел дела со множеством прерываний на 1 векторе, немного непривычно Результирующий код: Спойлер
Код:
list p=16f629 __config _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDTE_OFF & _FOSC_INTRCIO include p12f629.inc
#define RX_ 2 #define TX_ 1 #define RX GPIO,RX_ ; В качестве приемника может быть только эта ножка #define TX GPIO,TX_ ; А вот в качестве передатчика можем назначить любую, даже ту же
#define BITS_DELAY .30 ; Задержка длинной 1 бит - 104 мкс при 9600 бод и частоте 4 МГц #define RX_Complete 0 ; Флаг завершения приема #define Receive_in_Process 1 ; Флаг-признак процесса приема байта
; В прерывании только прием байта (побитно), и выставление флага окончания приема, который уже анализируется в основном цикле ;====================== Soft_UART udata_shr w_temp res 1 status_temp res 1 TX_byte res 1 RX_byte res 1 UART_counter res 1 delay_counter res 1 Flags res 1 ;====================== push macro ; movwf w_temp ; swapf STATUS,w ; movwf status_temp
movwf w_temp ; save off current W register contents movfw STATUS ; move status register into W register movwf status_temp ; save off contents of STATUS register endm
pop macro ; swapf status_temp,w ; movwf STATUS ; swapf w_temp,f ; swapf w_temp,w
movfw status_temp ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents endm ;====================== RESET_VECTOR code 0h goto Ini ;====================== ISR code 4h ; Вектор прерывания Interrupt_Heandler push ; Сохраним контекст btfsc Flags,Receive_in_Process goto Receive_bit ; Если флаг-признак процесса приема бита установлен - принимаем очередной бит посылки btfsc INTCON,INTF goto Start_bit ; Если есть флаг внешнего прерывания - пришел старт-бит End_Interrupt_Heandler bcf INTCON,T0IF ; Сбросим флаг переполнения Таймера 0 bcf INTCON,INTF ; Сбросим флаг внешнего прерывания pop ; Восстановим контекст retfie ;====================== Start_bit movlw .190 ; Перезапишем таймер для периода переполнения в 156 мкс (середина 1 бита данных) movwf TMR0 movlw .8 ; Загрузим количество принимаемых битов movwf UART_counter clrf RX_byte ; Очистим приемник bsf Flags,Receive_in_Process ; Установим флаг-признак процесса приема байта bcf INTCON,INTE ; Запрещаем внешнее прерывание (4 бит) bsf INTCON,T0IE ; Разрешаем прерывание по переполнению Таймера 0 (5 бит) goto End_Interrupt_Heandler ;====================== Receive_bit movlw .210 ; Перезапишем таймер для периода переполнения в 104 мкс movwf TMR0 bcf STATUS,C ; Сбросим бит переноса rrf RX_byte ; Задвигаем сброшенный бит переноса в приемный регистр btfsc RX ; А теперь проверяем, что на самом деле надо было туда задвинуть bsf RX_byte,7 ; Если 1, надо срочно подкорректировать, ведь мы задвинули 0 decfsz UART_counter ; Весь байт принят ? goto End_Interrupt_Heandler ; Нет, идем принимать следующий бит bcf Flags,Receive_in_Process ; Сбросим флаг-признак процесса приема байта bsf Flags,RX_Complete ; Поставим флажок окончания приема байта bcf INTCON,T0IE ; Запрещаем прерывание по переполнению Таймера 0 (5 бит) bsf INTCON,INTE ; Разрешаем внешнее прерывание (4 бит) для приема следующего старт-бита goto End_Interrupt_Heandler ; На выход ;====================== Ini clrf Flags ; Сбросим все флаги movlw b'111111' ; Заранее установим необходимые уровни на выходах, чтобы в момент переключения с входов на выходы му уже имели на них нужные значения movwf GPIO ; Init GPIO banksel OSCCAL ; Bank 1 call 3FFh movwf OSCCAL if RX_ != TX_ bcf TX ; Настроим TX на выход endif movlw b'10000000' ; Подтягивающие резисторы включены, внешнее прерывание по заднему фронту, тактирование Таймера 0 от внутреннего генератора, пределитель 1 к 2, что дает 512 мкс на частоте 4 Мгц movwf OPTION_REG banksel GPIO ; Bank 0 movlw b'00000111' movwf CMCON ; Выключим аналоговый компаратор movlw b'10010000' ; Разрешаем прерывания вообще (7 бит) и внешнее прерывание (4 бит) movwf INTCON ;====================== bcf Flags,Receive_in_Process ; Сбросим флаг-признак процесса приема байта
; movlw 'A' ; call Send_TX_byte Main ; goto Main
btfss Flags,RX_Complete ; Анализируем флажок приема байта goto Main ; Нет флажка - нет принятого байта Wait_Receive_complete btfss RX ; Ожидаем стоп бит goto Wait_Receive_complete movfw RX_byte ; Засунем принятый байт в рабочий регистр call Send_TX_byte ; И отправим назад bcf Flags,RX_Complete ; Скинем флажок принятого байта goto Main ;====================== Send_TX_byte ; Подпрограмма передачи 1 байта bcf INTCON,GIE ; Запрещаем прерывания if RX_ == TX_ banksel TRISIO ; Bank 1 bcf TX ; Настроим TX на выход banksel GPIO ; Bank 0 endif ;---------- bcf TX ; Шлем старт бит movwf TX_byte ; Загрузим передаваемый байт movlw .8 ; Загрузим количество передаваемых битов movwf UART_counter nop Transmit_Next_Bit nop call Delay_1bit ; Длинной 1 бит rrf TX_byte ; Продвигаем в бит переноса все биты, начиная с младшего btfsc STATUS,C ; Проверяем, что выдавилось в бит переноса bsf TX ; Если 1, выставляем 1 на ТХ btfss STATUS,C bcf TX ; Если 0, выставляем 0 на ТХ decfsz UART_counter ; Весь байт отослан ? goto Transmit_Next_Bit ; Нет, идем слать следующий бит call Delay_1bit ; Задержка длинной 1 бит nop nop nop nop nop bsf TX ; Шлем стоп-бит call Delay_1bit ; Задержка длинной 1 бит ;---------- if RX_ == TX_ banksel TRISIO ; Bank 1 bsf TX ; Настроим ножку на вход banksel GPIO ; Bank 0 endif bcf INTCON,T0IF ; Сбросим флаг переполнения Таймера 0 bcf INTCON,INTF ; Сбросим флаг внешнего прерывания bsf INTCON,GIE ; Разрешаем прерывания return ;====================== Delay_1bit movlw BITS_DELAY ; 104 мкс для 9600 бод movwf delay_counter Loop_Delay decfsz delay_counter goto Loop_Delay return
Доброго времени суток. Подскажите пожалуйста, как объявить переменную в EEPROM-памяти, чтобы значение в нее заносилась на этапе компиляции программы (и получался отдельный файл для EEPROM), и потом, при прошивке МК просто надо было прошить EEPROM, и получить там нужное значение. Можно конечно вручную выбрать View - EEPROM и там в нужную ячейку внести все ручками, но хотелось бы, чтобы все делалось само на автомате. Нашел директиву DE, но там пример какой-то не совсем понятный:
Код:
org H'2100' de <value>
Это вроде как для абсолютного кода. Как мне быть, если у меня перемещаемые сегменты кода (проект состоит из нескольких файлов) ?
Ап: 2 botchin - спасибо, получилось Теперь найти бы опцию в MPLAB, чтобы обновлять все содержимое EEPROM после компиляции, а то я сделал адрес H'2101', компильнул - там стало нужное значение, потом вернул адрес H'2100', опять компильнул, там тоже стало нужное значение, но и по адресу H'2101' осталось старое Ручками что-ли затирать ???
Последний раз редактировалось Пока_без_кота Вс авг 28, 2016 21:10:50, всего редактировалось 5 раз(а).
;EEPROM данни ORG 0X2100 ;sHZ DE 'H','z',0x00 ; 0x00 sind de 0xa5,0xbd,0xe3,'y',0xba,0xbf,0xb8,0xb3,0xbd,'o','c',0xbf,0x00 ;0x03 sFreq DE 0xab,'e','c',0xbf,'o',0xbf,'a',0x00 ;0x24 - честота shello DE 0xa4,0xe3,'p','a',0xb3,'e',0xb9,0x00 ;0x2c - Здравей sname DE 'B','a',0xbb,'e','p',0xb8,0xb9,0x00 ; Валерий
;ds18b20_1 de 0x28,0x8a,0xba,0x0e,0x02,0x00,0x00,0x93 ;0x93 - CRC ;ds18b20_2 de 0x28,0xcc,0x94,0x0e,0x02,0x00,0x00,0x0e ;0x0e - CRC stemp de ' ','B',0xc2,0xbd,0x00 ;Вън stemp1 de 'B',0xc2,0xbf,'p','e',0x00 ;Вътре ds1 de 0xa1,0,0,0x02,0x0e,0xad,0xee,0x28 ds2 de 0x0e,0,0,0x02,0x0e,0x94,0xcc,0x28 ccp_1 de 0xff, 0xff, 0xff, 0xff ccp_2 de 0xff, 0xff, 0xff, 0xff
_________________ Лом - ето город в Болгарии, а не инструмент юстировки електроники.
Заголовок сообщения: Re: Вопросы начинающих PIC ASM
Добавлено: Вс авг 28, 2016 22:45:01
Модератор
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4510 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Цитата:
Теперь найти бы опцию в MPLAB, чтобы обновлять все содержимое EEPROM после компиляции, а то я сделал адрес H'2101', компильнул - там стало нужное значение, потом вернул адрес H'2100', опять компильнул, там тоже стало нужное значение, но и по адресу H'2101' осталось старое Ручками что-ли затирать ???
Только ручками. Причём там это делается всё в пару кликов. Правая кнопка мыши, и выбираем что-то типа "fill memory", или что-то в этом роде. Вводим значение и все ячейки заполняются этим значением.
Директива DE одинакова как для абсолютного, так и для относительного режимов адресации (то же касается и директив разметки таблиц/данных в ПЗУ) - там будет выполнено или явное указание адреса или "склеивание" с последним предшествующим значением. Отличия будут только в синтаксисе МК/МП при совмещенной памяти программ/данных (STM8 и I8080-подобных) и то в плане дополнительных директив/префиксов-суффиксов обработки сегментов ("склейка", наложение/перекрытие и прочие...). Для mcs51, avr, pic директивы размещения таблиц/данных действуют одинаково (иногда наблюдаются отличия в названии директив).
Спасибо за разъяснение Теперь такой вопрос. Есть у меня запись в EEPROM внутри программы. При этом я жду окончания записи тупым циклом с задержкой. Хотелось бы сделать это красивее, и например поспать в это время Но при этом не хочется усложнять обработчик прерываний, потому что это процедура довольно редкая, и не хотелось бы в обработчике городить еще проверку и сброс флага EEIF. Вычитал что "микроконтроллер выходит из режима SLEEP независимо от состояния бита GIE. Если GIE=0 выполняется следующая инструкция после SLEEP, без перехода по вектору прерываний". Отлично, то что надо, могу поспать, и в обработчик лезть не надо, делаю так:
Код:
; где то в начале инициализации bsf INTCON,PEIE ; Разрешаем прерывания от периферии bsf PIE1,EEIE ; Разрешаем прерывания по окончанию записи в EEPROM
; много кода
; Здесь запись в EEPROM, прерывания запрещены sleep ; Засыпаем в ожидании завершения записи nop bcf PIR1,EEIF ; Просыпаемся, и сбросываем флаг окончания записи в EEPROM, чтобы не переходить в обработчик после разрешения прерываний bsf INTCON,GIE ; Разрешаем прерывания, но не переходим на обработчик прерываний, посколькe флаг уже сброшен ; Продолжаем выполнение программы с удачно завершенной записью
...Вычитал что "микроконтроллер выходит из режима SLEEP независимо от состояния бита GIE. Если GIE=0 выполняется следующая инструкция после SLEEP, без перехода по вектору прерываний"...
Дайте ссылку на этот "документ". ---- Если прерывания не разрешены - из спячки по INT не выйдет. Это указано в pdf-е и подтверждено практикой.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения