Например TDA7294

Форум РадиоКот • Просмотр темы - Вопросы начинающих PIC ASM
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Ср апр 24, 2024 22:58:04

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 440 ]    , , , , 5, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Пн авг 22, 2016 14:12:24 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
Доброго времени суток. Снова я со свои программным 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 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Пн авг 22, 2016 15:09:49 
Друг Кота
Аватар пользователя

Карма: 93
Рейтинг сообщений: 1351
Зарегистрирован: Вт мар 16, 2010 22:02:27
Сообщений: 14063
Откуда: ДОНЕЦК
Рейтинг сообщения: 3
Снова повторяю напоминание -
необходимо использовать штатный шаблон для обработчика прерываний
(
; 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)? :wink:
Это минимум - глубше не вникал.
:roll:
Помимо прочего не рекомендую злоупотреблять
#define
в тех случаях, когда более оправданно-понимаемо применение стандартных директив
equ
и других...
8)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Пн авг 22, 2016 15:27:17 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
BOB51 писал(а):
... а чего у Вас в макросах (push & pop)? :wink:

Дык у меня вроде то же самое аналогичное по функционалу, взято из книжки:
push macro
movwf w_temp
swapf STATUS,0
movwf status_temp
endm

pop macro
swapf status_temp,0
movwf STATUS
swapf w_temp,1
swapf w_temp,0
endm

Изображение


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Пн авг 22, 2016 19:12:07 
Друг Кота
Аватар пользователя

Карма: 93
Рейтинг сообщений: 1351
Зарегистрирован: Вт мар 16, 2010 22:02:27
Сообщений: 14063
Откуда: ДОНЕЦК
Рейтинг сообщения: 3
То книжка от вредоносного СУСАНИНА - ибо копируется в программный стек содержимое W и STATUS без разворотов, а вот при восстановлении хитрый SWАP применяется для того, чтобы содержимое флажков в STATUS не испортить прямым загрузом W из регистра временного хранения (точно по каким соображениям - ШКЛЕРОЗЬ - смотреть конспехты надо /сейчас мозги АВРкой забиты).
:?


Вернуться наверх
 
Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Пн авг 22, 2016 21:10:36 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
Сделал по-вашему, ничего не изменилось. Скорее всего дело не в этом, я где-то в алгоритме или его реализации накосячил.
Что уже обнаружил и исправил:
Внешнее прерывание перенастроил по переднему фронту (установил 6 бит в OPTION при инициализации). Но это еще не все, есть что-то еще.
Алгоритм следующий:
1. Жду прерывание на внешней ноге.
2. Захожу в обработчик по внешнему прерыванию, настраиваю таймер на прерывание через полтора бита (середина 1 бита данных), инициализирую счетчик битов, запрещаю внешнее прерывание, разрешаю прерывание по таймеру.
3. Захожу в обработчик по прерыванию таймера, настраиваю таймер на перывание через 1 бит, принимаю бит, уменьшаю счетчик, если не 0, просто выхожу.
4. Если счетчик 0, выставляю флажок окончания приема, запрещаю прерывание по таймеру, разрешаю внешнее прерывание для следующего старт бита.

Вроде все верно ?


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Пн авг 22, 2016 21:49:56 
Собутыльник Кота
Аватар пользователя

Карма: 55
Рейтинг сообщений: 415
Зарегистрирован: Чт мар 20, 2008 01:06:40
Сообщений: 2916
Откуда: Севастополь
Рейтинг сообщения: 1
Верно.
Только кто ж будет разбираться с этим дальше ?
Тут действующих программистов под PIC - полтора человека :)
А PIC12F1822 стоит дешевле, чем то время, что они потратят на анализ вашего кода.

_________________
>(*.*)<
Котище огромно, ушасто, пушисто, глазасто, зубасто, колючелапо и мявай. (c)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вт авг 23, 2016 07:27:32 
Друг Кота
Аватар пользователя

Карма: 93
Рейтинг сообщений: 1351
Зарегистрирован: Вт мар 16, 2010 22:02:27
Сообщений: 14063
Откуда: ДОНЕЦК
Рейтинг сообщения: 0
abc писал(а):
...
А PIC12F1822 стоит дешевле, чем то время, что они потратят на анализ вашего кода.


А Вам отличия по ассемблеру для PIC12F1822 известны?
Человек еще с "стандартным среднемладшим" еще не разобрался, а тут гибрид 18-й серии.
Как по структуре ядра, так и по системе команд (не говоря уже о необходимости иметь программатор с регулировками напряжения прошивки и соответствующие дополнения по самой IDE - в "штатном" 8.92 это семейство только начинает рассматриваться к применению).
Да и не у всех доступ к столь широкому ассортименту имеется.
8)
Закончу тест-заготовку под WS2812 можно будет и отвлечся...
:beer:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вт авг 23, 2016 07:43:00 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4510
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Вы пишите о проблеме с передачей :
Пока_без_кота писал(а):
Проблема возникает, когда пытаюсь передавать символ, который принял (в прерывании) - передает не то, что отправлял в терминале. Просьба подсказать, где ошибка
А алгоритм приводите приёма :
Пока_без_кота писал(а):
1. Жду прерывание на внешней ноге.2. Захожу в обработчик по внешнему прерыванию, настраиваю таймер на прерывание через полтора бита (середина 1 бита данных),
...........
Как это понимать ? И в чём конкретно проблема, в передаче или приёме ? :dont_know:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вт авг 23, 2016 08:13:07 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
Аlex писал(а):
Как это понимать ? И в чём конкретно проблема, в передаче или приёме ? :dont_know:

Прошу прощения, нечетко выражаю мысли.
Проблема именно в приеме. Передача у меня реализована пока не в прерыаниях, она уже опробована и с ней проблем нет, у меня есть в программе закомментированые строчки:
Код:
;   movlw   'A'
;   call   Send_TX_byte
Main
;   goto   Main

Если их раскомментировать, то в этом месте происходит передача ASCII кода англ. символа "А" и зацикливание программы, из чего я делаю вывод, что передача у меня работает корректно. Проблема в том, что если я включаю прием на прерываниях, то назад в компьютер передается не тот символ, который я отправлял в контроллер. Значит проблема в приеме :)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вт авг 23, 2016 10:47:05 
Друг Кота
Аватар пользователя

Карма: 93
Рейтинг сообщений: 1351
Зарегистрирован: Вт мар 16, 2010 22:02:27
Сообщений: 14063
Откуда: ДОНЕЦК
Рейтинг сообщения: 0
Возможно ошибка не в прерывании, а в согласовании обмена (принятом протоколе для связи МК и ПК).
Принимать/отправлять "просто так" в компе только простейшие терминальные прожки могут.
:dont_know:
А может и алгоритм не совсем корректен - включи логический анализатор(в МПлабе) и посмотри чего там происходит в пошагово в дебаггере.
:roll:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вт авг 23, 2016 10:57:39 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
Ну, на стороне ПК с прогой проблем я думаю нет, потому что когда прием был написан не на прерывании мне контроллер возвращал тот символ, который я ему отправлял.
А дебагером я и отлаживал сперва (прежде чем вопить здесь о помощи :oops: ), НОП-ы ставил как раз для того, чтобы подобрать точные задержки при передаче (104 мкс между битами). При отладке в дебагере у меня точно выдерживаються все временные интевалы. Процесс отладки выглядит так:
1. Запускаю прогу на выполнение, жду немного, ставлю на паузу.
2. Выставляю 1 бит в INTCON. Опять запускаю на выполнение.
3. Захожу в прерывание по INT (стоит брекпоинт), запускаю секундомер, выхожу.
4. На момент считывания бита по таймеру у меня стоит точка отладки, до нее от момента входа в прерывание INT ровно 156 мкс.
5. Потом между моментами считывания бита по переполнению таймера у меня ровно 104 мкс. Стоп-бит я не ловлю.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вт авг 23, 2016 15:04:07 
Друг Кота
Аватар пользователя

Карма: 93
Рейтинг сообщений: 1351
Зарегистрирован: Вт мар 16, 2010 22:02:27
Сообщений: 14063
Откуда: ДОНЕЦК
Рейтинг сообщения: 3
Анализатор векторов и сама обработка прерываний весьма неудачна.
Возможны "гонки" источников прерываний - при исполнении внешнего прерывания "перекрывается" таймер и наоборот.
Лучше использовать флаг-транслятор вместо INTCON,T0IF (T0IF лишь отметка времени, а требование исполнения - дополнительный флаг, сбрасываемый уже исполнительной прожкой).
Да и обращение с самим таймером - смена значения "на лету" не есть хорошо - сначала стоп счета, затем запись и затем пуск будет стабильнее работать (здесь нет буфера для синхронного переноса данных).
При необходимости оперативного изменения "плавающего коэффициента счета" у ПИКа используется TMR1 в режиме "Сброс TMR1 триггером модуля CCP"
:roll:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вт авг 23, 2016 20:29:40 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
BOB51 писал(а):
Анализатор векторов и сама обработка прерываний весьма неудачна... :roll:

Спасибо, переделал, все работает !!!!
Сижу и думаю, как я мог такое написать, ведь действительно источники прерываний "перекрывали" друг друга. Просто до этого не имел дела со множеством прерываний на 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
   
   end


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вс авг 28, 2016 20:45:58 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
Доброго времени суток. Подскажите пожалуйста, как объявить переменную в EEPROM-памяти, чтобы значение в нее заносилась на этапе компиляции программы (и получался отдельный файл для EEPROM), и потом, при прошивке МК просто надо было прошить EEPROM, и получить там нужное значение. Можно конечно вручную выбрать View - EEPROM и там в нужную ячейку внести все ручками, но хотелось бы, чтобы все делалось само на автомате.
Нашел директиву DE, но там пример какой-то не совсем понятный:
Код:
org H'2100'
de  <value>

Это вроде как для абсолютного кода. Как мне быть, если у меня перемещаемые сегменты кода (проект состоит из нескольких файлов) ?

Ап: 2 botchin - спасибо, получилось :beer:
Теперь найти бы опцию в MPLAB, чтобы обновлять все содержимое EEPROM после компиляции, а то я сделал адрес H'2101', компильнул - там стало нужное значение, потом вернул адрес H'2100', опять компильнул, там тоже стало нужное значение, но и по адресу H'2101' осталось старое :roll: Ручками что-ли затирать ???


Последний раз редактировалось Пока_без_кота Вс авг 28, 2016 21:10:50, всего редактировалось 5 раз(а).

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вс авг 28, 2016 20:59:47 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 81
Рейтинг сообщений: 440
Зарегистрирован: Чт дек 27, 2012 20:46:09
Сообщений: 2024
Откуда: Болгария, г. Лом
Рейтинг сообщения: 0
Я на 16F628А делаю так
Код:
;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
Получил миской по аватаре (1)
Цитата:
Теперь найти бы опцию в MPLAB, чтобы обновлять все содержимое EEPROM после компиляции, а то я сделал адрес H'2101', компильнул - там стало нужное значение, потом вернул адрес H'2100', опять компильнул, там тоже стало нужное значение, но и по адресу H'2101' осталось старое Ручками что-ли затирать ???
Только ручками.
Причём там это делается всё в пару кликов. Правая кнопка мыши, и выбираем что-то типа "fill memory", или что-то в этом роде. Вводим значение и все ячейки заполняются этим значением.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Вс авг 28, 2016 23:07:11 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
Аlex писал(а):
Только ручками...

Спасибо, все равно достаточно удобно. Всяко лучше, чем каждую вручную перебивать :)))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Пн авг 29, 2016 06:36:30 
Друг Кота
Аватар пользователя

Карма: 93
Рейтинг сообщений: 1351
Зарегистрирован: Вт мар 16, 2010 22:02:27
Сообщений: 14063
Откуда: ДОНЕЦК
Рейтинг сообщения: 0
Директива DE одинакова как для абсолютного, так и для относительного режимов адресации (то же касается и директив разметки таблиц/данных в ПЗУ) - там будет выполнено или явное указание адреса или "склеивание" с последним предшествующим значением.
Отличия будут только в синтаксисе МК/МП при совмещенной памяти программ/данных (STM8 и I8080-подобных) и то в плане дополнительных директив/префиксов-суффиксов обработки сегментов ("склейка", наложение/перекрытие и прочие...). Для mcs51, avr, pic директивы размещения таблиц/данных действуют одинаково (иногда наблюдаются отличия в названии директив).
8)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Пн авг 29, 2016 19:34:00 
Потрогал лапой паяльник

Карма: 1
Рейтинг сообщений: 13
Зарегистрирован: Чт авг 08, 2013 01:06:54
Сообщений: 359
Рейтинг сообщения: 0
Спасибо за разъяснение :roll:
Теперь такой вопрос. Есть у меня запись в 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 флаг уже сброшен
;   Продолжаем выполнение программы с удачно завершенной записью

И не работает оно почему-то :roll:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы начинающих PIC ASM
СообщениеДобавлено: Пн авг 29, 2016 20:38:33 
Друг Кота
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1859
Зарегистрирован: Чт сен 12, 2013 00:54:12
Сообщений: 4119
Откуда: ЗаМКАДье. Там, где ЦУП
Рейтинг сообщения: 0
Медали: 5
Получил миской по аватаре (5)
Пока_без_кота писал(а):
...Вычитал что "микроконтроллер выходит из режима SLEEP независимо от состояния бита GIE. Если GIE=0 выполняется следующая инструкция после SLEEP, без перехода по вектору прерываний"...
Дайте ссылку на этот "документ".
----
Если прерывания не разрешены - из спячки по INT не выйдет.
Это указано в pdf-е и подтверждено практикой.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 440 ]    , , , , 5, , , ...  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y