Пост N: 625
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 19.03.13 13:49. Заголовок: Передача данных по радиоканалу.
В развитие темы, дабы не засорять "чужие". Радио модемы хорошо, особенно при передачи большого количества инфы. Мне же необходимо сделать недорогое устройство, которое бы дублировало некоторую информацию, а именно отображаемую на основном 2- строчном ЖК дисплее. Используется до 7 регистров, вот их значения мне и надо передать на расстояние до 50м на другой блочёк, который бы дублировал показания основного. Конечно, можно приобрести 2 модема и организовать канал передачи. Но в моём случае это слишком избыточно. Связь односторонняя нужна, скорость, как понимаете, тоже не критична. Обновление информации 2 раза за сек. более чем. Да и по деньгам гораздо дешевле. Ведь достаточно небольшого ПРД в основном устройстве, ПП для формирования посылок с данными и устройство приёма и индикации, 1 МК и 1 ЖК. Ну и несколько транзисторов и рассыпухи. Так что попробую вначале своими силами. Сейчас переписываю канал передачи, что бы можно было задавать планируемое количество байт на передачу и последовательно их "выплёвывать". Пока задумка делать это двумя байтами, в одном это будет "адрес" передаваемого регистра, в другом - данные. В приёмнике он определяется и переписывается каждый в своё место для отображения. При чём, вначале они все принимаются, а потом индикация обновляется. Делаю шефу, так что придётся всё довести до "железа"!
Для сведения, глянь интерфейс. http://zalil.ru/34362636 Если заинтересуешься, есть информация: http://www.voti.nl/rfm70/index.html Сам не буду этим заниматься. Знаю, что на отечественных ИК диодах были успешные попытки связи до 100м. Кажется интерфейс RC5.
Пост N: 628
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 20.03.13 12:31. Заголовок: Короче, засада со ск..
Короче, засада со скоростью передачи. Переделал, точнее дополнил, протокол передачи данных, добавив передачу номера байта в цикле передачи. Но передача 1 байта инфы на предложенной скорости примерно 100 мСек., что меня совершенно не устраивает. Мне надо уложиться в 4 мсек, и не более на передачу 1 байта. Если частоту увеличить, скорее всего возникнут проблемы с приёмом, а по радиоканалу ещё и сильнейший фон в эфир, внося помехи в близстоящие приёмники и тд. В Протеусе то работает, проект есть, а вот в железе даже пробовать не стал, т.к. на гране фола! Так что данное устройство хорошо, но для управления, на что и было рассчитано. Вячеслав , а вот модули такие у нас есть в продаже, и даже очень не дорогие click here Так что вполне можно использовать. Если есть по ним инфа, очень буду признателен. И если не затруднит, есть ли отличия существенные RFM70 и RFM73. И какой лучше-проще в запуске-наладке? Ни когда не работал ни с этими модулями ни с протоколами, по которым они работают. Но теперь буду изучать. Всё приходит по мере надобности!
Пост N: 364
Зарегистрирован: 25.09.09
Откуда: г.Саратов
Рейтинг:
1
Отправлено: 20.03.13 13:42. Заголовок: Рад бы помочь, но с ..
Рад бы помочь, но с ними не работал. Просто "проскочила" информация, положил на свой "чердак". Кроме выложенной информации, привожу полный текст с форума, как его сохранил: Начало диалога: " sereg2010 » 07 окт 2012, 16:38 Есть недорогие радиомодули RFM70 2.4 ГГц, пытаюсь организовать простейшую связь, с одной стороны кнопка, с другой стороны светодиод, все это используя ATtiny2313. Нашел в сети несколько примеров: http://www.kner.at/home/news.avr.rfm70.html http://we.easyelectronics.ru/part/radio-modul-rfm70.html http://www.picbasic.ru/forum/5-1162-1 В примерах много непонятного, сделал пока свой программный SPI на Flowcode V4. Если кто делал нечто подобное, подскажите как все это проще написать в Flowcode, чтобы модули хотя бы запустились." Ответ очень крутого гуру: "На основе этих исходников (http://www.hoperf.com/rf_fsk/24g/rfm70.htm) можно сделать для 2313. По крайней мере, то что сделал я, работает в Протеусе... Там все скидано в кучу, пришлось много переделать, и судя по тому что я видел еще, то в программе (в исходниках) много лишнего... Будем считать что исходники, выложенные на сайте - рабочие. Однако я советую брать переводчик и переводить родную документацию, без этого ни как - будет тупое копирование, и если упремся..., то без знаний документа не сможем. Скачай с этого сайта (http://www.voti.nl/rfm70/index.html) RFM70 C library и переведи весь комментарий из программы, там много хороших рекомендаций. Твоя задача - сделать русский перевод." Этим сообщением диалог закончен. Энтузиазм иссяк Большим ничем помочь не могу.
Отправлено: 20.03.13 14:46. Заголовок: 100 мСек. на 1 байт,..
100 мСек. на 1 байт, это что-то из фантастики 100000 тактов при 4 МГц Я же давал скриншоны анализатора лаба. Там 9 бит передаются за 4,5мс И можно уменьшить не напрягаясь
Ок, давай посчитаем. Всего в 1 цикле передачи 70 600 м.ц. Можешь проверить. Если тактовая 4МГц, 1мкс - 1м.ц., получаем 70,6 мс. Это чисто, по исходнику. Я передаю ещё 8 бит адреса, это ещё минимум (если нулевой адрес) 25 000 м.ц. Итого у меня цикл составляет 95 600 м.ц. При 4 МГц это почти 100мс. При этом в пачках генерируется меандр с частотой 5.5кГц. Это не много, применительно к частоте передачи в 400-500МГц, если не учитывать гармоники. А они будут в меандре и ещё какие. Если "сжать" всё это во времени допустим как мне надо в 20 раз, частота меандра возрастёт до 100 кГц и выше, а уровень, как правило, нечётных гармоник в несколько раз. Ну и подсчёт (выделение) импульсов в пачках с частотой 100кГц после ПРМ, где они будут так смазаны, что не выделить, будет практически не реально. По проводу может и прокатит, по радио сомневаюсь.
Мне надо уложиться в 4 мсек, и не более на передачу 1 байта.
Я имел в виду байта полезной инфы, т.е. полного цикла. Иначе такая передача и н......, ну сам понимаешь! А вот ЧМ, это совершенно другая картина, да ещё если 0 и 1 передавать. Частотный дискриминатор (детектор) на многое способен, вот Мбиты и летят.
Пост N: 632
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 20.03.13 16:55. Заголовок: Посчитай в лабе, 32 ..
Посчитай в лабе, 32 старт, 9*18 прямой, 9*9 обратный, 9*18 адрес, плюс 25*16 паузы между ними. Просуммируй и умножь на время формирования 1 импульса в пачках и паузах
Пост N: 633
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 31.03.13 02:30. Заголовок: Всё получилось, данн..
Всё получилось, данные передаются. 6 показаний на двухстрочный индикатор (всего 13 байт информации) передаются примерно 1 раз в 1,5 секунды. Это вполне нормально, если учесть что приёмник с ЖК нужен для мониторинга показаний с основного устройства. Таких "дублёров" можно устанавливать неограниченное количество, что очень удобно, т.к. они работают только на приём. Проект есть тут
SanSanich пишет: [quote]` Опупеть ваш проект похож на мой . Даже папки MASTER, SLAVE как у меня обозваны. Только для передачи данных я использую радиомодули от автосигнализации с двух сторонней связью.
Опупеть ваш проект похож на мой . Даже папки MASTER, SLAVE как у меня обозваны
Не смог раньше ответить, далеко сейчас. Когда разбирался с модулем SPI лопатил инет, нашёл какой то проект, SPI.rar, но он совсем не подошёл, писал всё своё. А название папок видимо так же и сделал. На счёт модулей, было бы интересно взглянуть. Планирую и этот вариант опробовать, по деньгам почти так же выходит, модули по 25 грн и МК простенький с SPI, второй уже есть в устройстве основном, 16F877A. Так что была бы полезна помощь в их инициализации. На счёт плагиата 100% его нет, кроме радиоканала, это у КЕА взял со взлома за основу. Добавил передачу номера байта и убрал кнопки. Взял сам кодер и декодер, и четырехпроводный интерфейс для ЖКИ, слегка переработал, оптимизировал под любую частоту МК и ноги. Ну и арифметика, чего её менять, всё уже придумано! Остальное оригинальное, своё. Может и не оптимально, и говнокод, но свой, рабочий, он мне нравится. Алгоритм работы тоже сам составлял. Да и похожего вряд ли найти, по тому как может показаться что всё через ж... работает. Мастер на самом деле в папке слейв лежит, на 8-ножечном 12F629 организован. Это в процессе написания алгоритм передачи данных поменял, а папки так и остались! 877-й по битно отдаёт каждый байт, ожидая разрешения от мастера на каждый бит. Частоты ЗГ у них разные, вот и пришлось извращаться. Планирую на ЧИПМК статью и исходники свои выложить, как вернусь на родину! Так что код на асме там ни как не может быть похож, совершенно иначе данные передаются. Ради чистоты эксперимента открою код всех трёх МК, мне не жалко. Правда коменты не успел расставить и "причесать" код, но критике всегда рад, главное чтоб аргументированная и по делу. Напоминаю, всё это устойчиво работает! Вот на 16F877A
; !!!ПРАВИЛЬНЫЙ РАБОЧИЙ ПРОЕКТ!!! ;************************************************************************************************** ; Шести канальный вольтметр на PIC 16F877A и четырехпроводный интерфейс для ЖКИ на основе ; м/контроллера HD44780 и аналогичных с использованием любых разрядов разных портов МК. ; ВНИМАТЕЛЬНО НАСТРОИТЬ ПОРТЫ ДЛЯ ЖК как ЦИФРОВЫЕ НА ВЫХОД! ; Передача данных по SPI в режиме ВЕДОМЫЙ ;**************************************************************************************************
Пост N: 638
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 10.04.13 22:38. Заголовок: Это на 12F629 ;****..
Это на 12F629
;*************************************************************************** ; SRADIO_12F629 ; МК Pic 12F629, тактовая 4МГц внутренний, Мастер SPI ; (1 нога)- +5V 8- масса, ; GP5(2 нога)- OUT_PRD GP0(7 нога)- SCK(RC3) ; GP4(3 нога)- PRD_ON GP1(6 нога)- SS(RA5) ; GP3(4 нога)- GP2(5 нога)- SDO(RC5) ; Инициализируем ноги МК, организуем Мастера SPI ; Ведущий на SCK даёт 1 готовность принятия данных и опрашивает флаг прерывания INTF. ; Ведомый опрашивает порт SCK и выдаёт на вывод SDO 1 готовности отдать данные. Переходит в режим SPI, ; загружает байт_1 в буфер SSPBUF и ждёт SCK. ; Ведущий опрашивает флаг прерывания и переходит на ПП формирования SCK, приёма и записи данных. ; Очищает входной регистр и устанавливает бит 0 в единицу (00000001), формирует 0-1 SCK. ; Проверяет состояние на входе SDO, дублирует его в 0 бите входного регистра. ; Производит сдвиг влево и проверяет флаг C. Следующий бит и т.д. ; История: 28.03.2013 - Файл создан ; *************************************************************************** list p=12f629 #include <p12f629.inc>
banksel TRISIO movlw RADIO movwf TRISIO clrf STATUS
; Первый вызов ПП ПЕРЕДАЧИ ДАННЫХ ;1------------------------------------------------------------------------- movf Reg_1,w movwf Reg_Code ; Запись данных для отправки call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ; Не обязательно ;2------------------------------------------------------------------------- ; при передаче каждого последующего байта информации ему присваивается следующий номер movf Reg_2,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;3------------------------------------------------------------------------- movf Reg_3,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;4------------------------------------------------------------------------- movf Reg_4,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;5------------------------------------------------------------------------- movf Reg_5,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;6------------------------------------------------------------------------- movf Reg_6,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;7------------------------------------------------------------------------- movf Reg_7,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;8------------------------------------------------------------------------- movf Reg_8,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;9------------------------------------------------------------------------- movf Reg_9,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;10------------------------------------------------------------------------- movf Reg_10,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;11------------------------------------------------------------------------- movf Reg_11,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;12------------------------------------------------------------------------- movf Reg_12,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных call PAUSE_BT ;13------------------------------------------------------------------------- movf Reg_13,w movwf Reg_Code ; Запись данных для отправки incf Reg_Namber,F ; Увеличиваем номер регистра на 1 call DATA_PRD ; Вызов ПП передачи данных
movlw REG_START movwf Reg_Namber ; После передачи последнего байта в цикле обнуляем ; счётчик нумерации байтов. goto MAIN_PROG ;************************************************************************************************* ; ФУНКЦИИ ;************************************************************************************************* ; SPI Принятие 1 байта. ;************************************************************************************************* DATA_X bcf SS ; Запуск SPI bsf SCK
;******************************************************************************* DATA_PRD START_PRD bsf PRD_ON ; Подача 1 на усилитель мощности передатчика ; и светодиод, если он нужен ;---------------------------------------------------------- ; Формирование "пачки" битов, которая, на приемной стороне, ; позволяет определить условие старта (первые 3 команды). ;---------------------------------------------------------- movlw .32 ; Задание количества movwf Count ; периодов в "пачке" (32). call START_BIT ; Переход в ПП формирования "пачки" битов. ;---------------------------------------------------------- ; Формирование "пачек" импульсов прямого кода. ;---------------------------------------------------------- call DIRECT_CODE ; Прямая передача данных. ;---------------------------------------------------------- ; Формирование "пачек" импульсов инверсного кода. ;---------------------------------------------------------- call INVERT_CODE ; Инверсная передача данных ;---------------------------------------------------------- ; Завершающий этап передачи исполнительной команды. ;---------------------------------------------------------- movf Reg_Namber, W ; Прямая передача номера регистра movwf Reg_Code call DIRECT_CODE bcf PRD_ON ; Усилитель мощности передатчика запирается. return ; Возврат из ПП ;============================================================================================ ; Подпрограмма формирования "пачки" импульсов, которая, на приемной стороне, ; позволяет определить уровень "1" бита кода. ;============================================================================================ TX_1 movlw .18 ; Задание количества movwf Count ; периодов в "пачке" (18). goto START_BIT ; Переход в ПП формирования "пачки" импульсов. ;============================================================================================ ; Подпрограмма формирования "пачки" импульсов, которая, на приемной стороне, ; позволяет определить уровень "0" бита кода. ;============================================================================================ TX_0 movlw .9 ; Задание количества movwf Count ; периодов в "пачке" (9). ;============================================================================================ ; Подпрограмма формирования "пачки" импульсов. ;============================================================================================ START_BIT bsf OUT_PRD ; Включение передатчика. call PAUSE ; Переход в ПП PAUSE. bcf OUT_PRD ; Выключение передатчика. call PAUSE ; Переход в ПП PAUSE. decfsz Count,F ; Count-1=... Результат сохраняется в Count. goto START_BIT ; Если результат не=0, то формируется следующий ; период "пачки". ;-------------------------------------------------------------------------------------------- ; Группа команд формирования паузы между "пачками" импульсов (передатчик не работает). ;-------------------------------------------------------------------------------------------- PAUSE_BT movlw .16 ; Задание количества пауз, movwf Count ; формируемых ПП PAUSE. METKA call PAUSE ; Формирование задержки (разделителя) decfsz Count,F ; Count-1=... Результат сохраняется в Count. goto METKA ; Если результат не=0, то формируется ; следующая пауза. return ; Если результат =0, то происходит возврат по стеку ; либо в "администраторскую" группу команд (если ; исполняется ПП START_BIT), либо в ПП DIRECT_CODE, ; либо в ПП INVERT_CODE. ;============================================================================================ ; ПРЯМАЯ ПЕРЕДАЧА КОДА. Байт передается битом №0 вперед. ; Сначала формируется "пачка" единицы, а затем "пачка" нуля. ;============================================================================================ DIRECT_CODE btfsc Reg_Code,0 ; В бите №0 лежит 1 или 0 ? call TX_1 ; Если 1, то формируется "пачка" единицы. btfss Reg_Code,0 ; В бите №0 лежит 1 или 0 ? call TX_0 ; Если 0, то формируется "пачка" нуля. ;------------------------------------- btfsc Reg_Code,1 ; То же самое call TX_1 ; для бита №1. btfss Reg_Code,1 ; call TX_0 ; ;------------------------------------- btfsc Reg_Code,2 ; То же самое call TX_1 ; для бита №2. btfss Reg_Code,2 ; call TX_0 ; ;------------------------------------- btfsc Reg_Code,3 ; То же самое call TX_1 ; для бита №3. btfss Reg_Code,3 ; call TX_0 ; ;------------------------------------- btfsc Reg_Code,4 ; То же самое call TX_1 ; для бита №4. btfss Reg_Code,4 ; call TX_0 ; ;------------------------------------- btfsc Reg_Code,5 ; То же самое call TX_1 ; для бита №5. btfss Reg_Code,5 ; call TX_0 ; ;------------------------------------- btfsc Reg_Code,6 ; То же самое call TX_1 ; для бита №6. btfss Reg_Code,6 ; call TX_0 ; ;------------------------------------- btfsc Reg_Code,7 ; То же самое call TX_1 ; для бита №7. btfss Reg_Code,7 ; call TX_0 ; ;------------------------------------- return ; Возврат по стеку в "администраторскую" группу команд. ;============================================================================================ ; ИНВЕРСНАЯ ПЕРЕДАЧА КОДА. Байт передается битом №7 вперед. ; Сначала формируется "пачка" нуля, а затем "пачка" единицы. ;============================================================================================ INVERT_CODE btfsc Reg_Code,7 ; В бите №7 лежит 1 или 0 ? call TX_0 ; Если 1, то формируется "пачка" нуля. btfss Reg_Code,7 ; В бите №7 лежит 1 или 0 ? call TX_1 ; Если 0, то формируется "пачка" единицы. ;------------------------------------- btfsc Reg_Code,6 ; То же самое call TX_0 ; для бита №6. btfss Reg_Code,6 ; call TX_1 ; ;------------------------------------- btfsc Reg_Code,5 ; То же самое call TX_0 ; для бита №5. btfss Reg_Code,5 ; call TX_1 ; ;------------------------------------- btfsc Reg_Code,4 ; То же самое call TX_0 ; для бита №4. btfss Reg_Code,4 ; call TX_1 ; ;------------------------------------- btfsc Reg_Code,3 ; То же самое call TX_0 ; для бита №3. btfss Reg_Code,3 ; call TX_1 ; ;------------------------------------- btfsc Reg_Code,2 ; То же самое call TX_0 ; для бита №2. btfss Reg_Code,2 ; call TX_1 ; ;------------------------------------- btfsc Reg_Code,1 ; То же самое call TX_0 ; для бита №1. btfss Reg_Code,1 ; call TX_1 ; ;------------------------------------- btfsc Reg_Code,0 ; То же самое call TX_0 ; для бита №0. btfss Reg_Code,0 ; call TX_1 ; ;------------------------------------- return ; Возврат по стеку в "администраторскую" группу команд. ;============================================================================================ ; Подпрограмма задержки (85 машинных циклов). ;============================================================================================ PAUSE movlw F_CONST ; Запись времязадающей movwf Sec ; константы в регистр Sec.
W_R clrwdt ; Сброс WDT. decfsz Sec,F ; 1-разрядный, вычитающий счетчик goto W_R ; с "врезкой" команды clrwdt.
return
;******************************************************************************* ; Конец программы ;******************************************************************************* END
Пост N: 639
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 10.04.13 22:41. Заголовок: Это приёмник с ЖК на..
Это приёмник с ЖК на 16F628A
;******************************************************************************************** ; ДЕКОДЕР ;******************************************************************************************** list p=16F628a INCLUDE "P16F628A.inc"
; Используется м/контроллер PIC16F628A. __CONFIG 3F10h ; Защита выключена, режим низковольтного программирования ; выключен, сброс BOR запрещен, вывод MCLR (RA5) работает ; как порт ввода (вне зависимости от настройки направления ; работы), PWRT включен, WDT выключен, режим работы ; тактового генератора от внутренней RC цепочки ; (по умолчанию, тактовая частота равна 4 Мгц.) ;************************************************************************************************* ; КОНСТАНТЫ ПОЛЬЗОВАТЕЛЯ (могут меняться в зависимости от режима) ;************************************************************************************************* LAST_BYTE equ 0x2C ; 0x20+ количество передаваемых битов (последний регистр принемаемых байтов) F_OSC equ .4 ; НЕ МЕНЕЕ .1 Тактовая частота (МГц) MODE_DISP equ b'00001100' ; Дисплей включен, курсор выключен, мерцание выключено. MODE_SET equ b'00000110' ; Увеличение указателя при операции с памятью, сдвигание дисплея выключено. ;******************************************************************************* ; КОНСТАНТЫ РАБОЧИЕ ; ;******************************************************************************* ;------------------------------------------------------------------------------- ; Порты ввода вывода ;------------------------------------------------------------------------------- TRISA_CONST equ b'00000110' ; RA1, RA2 работают на вход, остальные выход PORTA_CONST equ b'00000000'
TRISB_CONST equ b'00000000' ; Все выходы PORTB_CONST equ b'00010000' ; Выход СТАБ отключён
;------------------------------------------------------------------------------------------------- ; Определение регистров и битов в этих регистрах для подключения к ЖКИ, схема подключения: ;------------------------------------------------------------------------------------------------- #Define DB7 PORTB,3 ; При этом необходимо удостовериться #Define DB6 PORTB,2 ; что выбранные порты настроены как #Define DB5 PORTB,1 ; цифровые выводы и не заняты, #Define DB4 PORTB,0 ; а так же настроенны на выход. #Define E PORTA,7 ; Учесть при инициализации МК. #Define RS PORTA,6 ; LCD R/W, D0-D3 – заземлить.
;============================================================================================ ; Регистрация принятых импульсов. ; Фактом наличия импульса считается нулевой уровень бита №7 регистра CMCON ; (0 на выходе компаратора). ;============================================================================================ METKA btfss CMCON,7 ; Импульс (CMCON,7=0) есть или нет? goto OBRABOTKA ; Если есть, то переход в ПП OBRABOTKA. goto METKA ; Если импульса нет, то закольцовка в ; "вечном кольце" (многократный переход ; на начало полного цикла программы). ;******************************************************************************************** ; ПП обработки принятого сигнала. ;******************************************************************************************** OBRABOTKA clrf Reg_Code ; Подготовка к заполнению регистра кода ; данными (единицами). clrf Reg_Namber call SYNHRO ; Переход в ПП SYNHRO с целью поиска btfss Temp,2 ; Temp,2=0 (условия старта нет) или =1 (условие старта есть)? goto METKA ; Если Temp,2=0, то уход в поиск условия старта. ; Если Temp,2=1, то программа исполняется далее. ;============================================================================================ ; Заполнение регистра Reg_Code принятыми единицами. ;============================================================================================ call FILTER ; Переход в ПП FILTER с целью обнаружения или нет ;----> Возврат по стеку из ПП FILTER. ; условия старта. В последнем случае (возврат по стеку), ; переход на анализ состояния бита №1 регистра Temp. btfsc Temp,1 ; Бит №1 регистра Temp =0 или =1? bsf Reg_Code,0 ; Если = 1, то в бит №0 Reg_Code записывается 1. ; Если = 0, то в бит №0 Reg_Code ничего не ; записывается (предустановлен 0) и программа ; исполняется далее. ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №1 регистра Reg_Code. bsf Reg_Code,1 ; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №2 регистра Reg_Code. bsf Reg_Code,2 ; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №3 регистра Reg_Code. bsf Reg_Code,3 ; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №4 регистра Reg_Code. bsf Reg_Code,4 ; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №5 регистра Reg_Code. bsf Reg_Code,5 ; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №6 регистра Reg_Code. bsf Reg_Code,6 ; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №7 регистра Reg_Code. bsf Reg_Code,7 ; ------------------"-------------------- ;============================================================================================ ; Заполнение регистра Reg_Invert принятыми единицами. ;============================================================================================ clrf Reg_Invert ; Подготовка к заполнению данными ; дублирующего регистра кода. call FILTER ; Переход в ПП FILTER с целью обнаружения или нет ;----> Возврат по стеку из ПП FILTER. ; условия старта. В последнем случае (возврат по стеку), ; переход на анализ состояния бита №1 регистра Temp. btfsc Temp,1 ; Бит №1 регистра Temp =0 или =1? bsf Reg_Invert,7; Если = 1, то в бит №7 Reg_Invert записывается 1. ; Если = 0, то в бит №7 Reg_Invert ничего не ; записывается (предустановлен 0) и программа ; исполняется далее. ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №6 регистра Reg_Invert. bsf Reg_Invert,6; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №5 регистра Reg_Invert. bsf Reg_Invert,5; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №4 регистра Reg_Invert. bsf Reg_Invert,4; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №3 регистра Reg_Invert. bsf Reg_Invert,3; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №2 регистра Reg_Invert. bsf Reg_Invert,2; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №1 регистра Reg_Invert. bsf Reg_Invert,1; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №0 регистра Reg_Invert. bsf Reg_Invert,0; ------------------"--------------------
;============================================================================================ ; Заполнение регистра Reg_Namber принятыми единицами. ;============================================================================================ clrf Reg_Namber ; Подготовка к заполнению данными ; дублирующего регистра кода. call FILTER ; Переход в ПП FILTER с целью обнаружения или нет ;----> Возврат по стеку из ПП FILTER. ; условия старта. В последнем случае (возврат по стеку), ; переход на анализ состояния бита №1 регистра Temp. btfsc Temp,1 ; Бит №1 регистра Temp =0 или =1? bsf Reg_Namber,0; Если = 1, то в бит №7 Reg_Invert записывается 1. ; Если = 0, то в бит №7 Reg_Invert ничего не ; записывается (предустановлен 0) и программа ; исполняется далее. ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №6 регистра Reg_Invert. bsf Reg_Namber,1; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №5 регистра Reg_Invert. bsf Reg_Namber,2; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №4 регистра Reg_Invert. bsf Reg_Namber,3; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №3 регистра Reg_Invert. bsf Reg_Namber,4; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №2 регистра Reg_Invert. bsf Reg_Namber,5; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №1 регистра Reg_Invert. bsf Reg_Namber,6; ------------------"-------------------- ;------------------------------------- call FILTER ; ------------------"-------------------- ;----> Возврат по стеку из ПП FILTER. btfsc Temp,1 ; То же самое для бита №0 регистра Reg_Invert. bsf Reg_Namber,7; ------------------"--------------------
;########################################################################### ; Регистры Reg_Code (прямой код) и Reg_Invert (инверсный код) заполнены. ;########################################################################### ;-------------------------------------------------------------------------------------------- ; Операции с контрольной суммой: проверка ошибочности ; или безошибочности принятого байта исполнительной команды. ;-------------------------------------------------------------------------------------------- comf Reg_Invert,F ; Инверсия всех битов байта инверсного кода. ; Получается прямой код. movf Reg_Code,W ; ------"------ subwf Reg_Invert,W ; Reg_Invert-Reg_Code(через W)=... (результат - в W). btfss STATUS,Z ; Результат операции =0 или не=0 ? goto METKA ; Если не=0 (совпадения не произошло), то все по новой. ; Если =0 (совпадение произошло), то программа ; исполняется далее. ;============================================================================================ ; Исполнение команды (ЗАПИСЬ БАЙТА В ЯЧЕЙКУ С ПЕРЕДАННЫМ АДРЕСОМ). ;============================================================================================ bcf STATUS,IRP ; Установить банк 0,1 movf Reg_Namber,w movwf FSR movf Reg_Code,w movwf INDF clrf STATUS
movlw LAST_BYTE subwf Reg_Namber,w ; Reg_Invert-Reg_Code(через W)=... (результат - в W). btfss STATUS,Z ; Результат операции =0 или не=0 ? goto METKA ; Если не=0 (совпадения не произошло), то все по новой. goto MAIN_PROG ; Если =0 (совпадение произошло), то программа исполняется далее. ;------------------------------------- clrf TMR0 ; Начало отсчета. bcf INTCON,2 ; Сброс флага переполнения Tmr0.
goto METKA ; Переход на следующий полный цикл программы. ;******************************************************************************************** ; ПП заполнения битов №№0,1,2 регистра Temp (на основе подсчета количества импульсов). ;******************************************************************************************** ; Реализован ЦИФРОВОЙ КОМПАРАТОР, реагирующий на попадание числа принятых ; импульсов (между разделителями) в один из пяти его числовых диапазонов: ; - меньше 6 : ошибка (помеха) - переход на начало полного цикла программы, ; - от 6 до 15 : принят бит с уровнем 0, ; - от 15 до 24: принят бит с уровнем 1, ; - от 24 до 40: принят стартовый бит (условие старта), ; - больше 40 : ошибка (помеха) - переход на начало полного цикла программы. ;----------------------------------------------------------- ; Напоминание: на передающей стороне ; - 9 импульсов : передается бит с уровнем 0, ; - 18 импульсов: передается бит с уровнем 1, ; - 32 импульса : передается стартовый бит (условие старта). ;-------------------------------------------------------------------------------------------- ; Поиск импульса. ;-------------------------------------------------------------------------------------------- SYNHRO clrf Temp ; Подготовка к работе регистра Temp. movlw .10 ; Запись константы в регистр movwf SecH ; старшего разряда счетчика.
WR_1 clrwdt ; Сброс WDT. btfss CMCON,7 ; Импульс (CMCON,7=0) есть или нет? goto IMPULS_1 ; Если есть, то переход в ПП IMPULS_1. ; Если нет, то программа исполняется далее. movlw .10 ; Запись константы в регистр movwf SecL ; младшего разряда счетчика.
WR_2 clrwdt ; Сброс WDT. btfss CMCON,7 ; Импульс (CMCON,7=0) есть или нет? goto IMPULS_1 ; Если есть, то переход в ПП IMPULS_1. ; Если нет, то программа исполняется далее.
goto METKA ; Если счетчик досчитывает до конца, то есть, проходит разделитель, ; то происходит переход на начало полного цикла программы. ;--------------------------------------------------------------------------- ; Отрабатывается если импульс есть (на выходе компаратора - низкий уровень). ;--------------------------------------------------------------------------- IMPULS_1 incf Temp,F ; Temp+1=... к (результат - в Temp). movlw .255 ; Запись константы в movwf Count ; счетчик проходов. ;----------------------------------- ; Ожидание окончания импульса. ;----------------------------------- WR_3 clrwdt ; Сброс WDT. btfsc CMCON,7 ; Импульс закончился (CMCON,7=1) или нет (CMCON,7=0) ? goto IMPULS_0 ; Если закончился, то переход в ПП IMPULS_0. ; Если не закончился, то программа исполняется далее. decfsz Count,F ; Одноразрядный вычитающий goto WR_3 ; счетчик с "врезкой". goto ANALYSE ; Если импульс слишком длинный, то уходим в ; ПП ANALYSE с текущим значением регистра Temp. ;---------------------------------------------------------------------------- ; Отрабатывается если импульса нет (на выходе компаратора - высокий уровень). ;---------------------------------------------------------------------------- IMPULS_0 movlw .255 ; Запись константы в movwf Count ; счетчик проходов. ;----------------------------------- ; Ожидание начала импульса. ;----------------------------------- WR_4 clrwdt ; Сброс WDT. btfss CMCON,7 ; Импульс начался (CMCON,7=0) или нет (CMCON,7=1) ? goto IMPULS_1 ; Если начался, то переход в ПП IMPULS_1. ; Если не начался, то программа исполняется далее. decfsz Count,F ; Одноразрядный вычитающий goto WR_4 ; счетчик с "врезкой". ; Если импульс так и не начался, то уходим в ; ПП ANALYSE с текущим значением регистра Temp. ;============================================================================================ ; ПП анализа количества принятых импульсов. ;============================================================================================ ; Количество импульсов в "пачке" больше или меньше 6-ти ? ;-------------------------------------------------------- ANALYSE movlw .6 ; Запись "эталона" (.6) в movwf Count ; регистр Count.
WR_5 clrwdt ; Сброс WDT. decf Temp,F ; Temp-1=... btfsc STATUS,Z ; Результат декремента содержимого регистра Temp =0 или не=0 ? goto METKA ; Если в принятой "пачке" меньше 6 импульсов, то ; переход на начало полного цикла программы (METKA). decfsz Count,F ; Одноразрядный, вычитающий goto WR_5 ; счетчик с "врезкой". ; Если в принятой "пачке" больше 6 импульсов, то счетчик ; досчитывает до 0, после чего программа исполняется далее. ;-------------------------------------------------------- ; Если количество импульсов в "пачке" от 6 до 15. ;-------------------------------------------------------- movlw .9 ; Запись "эталона" (.9) в movwf Count ; регистр Count.
WR_6 clrwdt ; Сброс WDT. decf Temp,F ; Temp-1=... btfsc STATUS,Z ; Результат декремента содержимого регистра Temp =0 или не=0 ? bsf Temp,0 ; Если в принятой "пачке" от 6 до 6+9=15 импульсов, то пишем 1 в Temp,0. ; Если в принятой "пачке" более 6+9=15 импульсов, то 1 в Temp,0 ; не записывается и производится еще одна проверка состояния Z. btfsc STATUS,Z ; Результат декремента содержимого регистра Temp =0 или не=0 ? return ; Если в принятой "пачке" от 6 до 6+9=15 импульсов, то выход ; из подпрограммы SYNHRO c 1 в Temp,0. decfsz Count,F ; Одноразрядный, вычитающий goto WR_6 ; счетчик с "врезкой". ; Если в принятой "пачке" больше 6+9=15 импульсов, то счетчик ; досчитывает до 0, после чего программа исполняется далее (Temp,0=0). ;-------------------------------------------------------- ; Если количество импульсов в "пачке" от 15 до 24. ;-------------------------------------------------------- movlw .9 ; Запись "эталона" (.9) в movwf Count ; регистр Count.
WR_7 clrwdt ; ------"------ decf Temp,F ; То же самое, что и выше, но только для btfsc STATUS,Z ; "пачки" от 15 до 15+9=24 импульсов. bsf Temp,1 ; ------"------ btfsc STATUS,Z ; ------"------ return ; Если в принятой "пачке" от 15 до 15+9=24 импульсов, то выход ; из подпрограммы SYNHRO c 1 в Temp,1. decfsz Count,F ; ------"------ goto WR_7 ; ------"------ ; Если в принятой "пачке" больше 15+9=24 импульсов, то счетчик ; досчитывает до 0, после чего программа исполняется далее (Temp,1=0). ;-------------------------------------------------------- ; Если количество импульсов в "пачке" от 24 до 40. ;-------------------------------------------------------- movlw .16 ; Запись "эталона" (.16) в movwf Count ; регистр Count.
WR_8 clrwdt ; ------"------ decf Temp,F ; То же самое, что и выше, но только для btfsc STATUS,Z ; "пачки" от 24 до 24+16=40 импульсов. bsf Temp,2 ; ------"------ btfsc STATUS,Z ; ------"------ return ; Если в принятой "пачке" от 24 до 24+16=40 импульсов, то выход ; из подпрограммы SYNHRO c 1 в Temp,2.
decfsz Count,F ; ------"------ goto WR_8 ; ------"------ ; Если в принятой "пачке" больше 24+16=40 импульсов, то счетчик ; досчитывает до 0, после чего программа исполняется далее (Temp,2=0). ;-------------------------------------------------------- ; Если количество импульсов в "пачке" больше 40. ;-------------------------------------------------------- goto METKA ; Переход на начало полного цикла программы с нулями в битах ; №№0,1,2 регистра Temp (состояния остальных битов не важно). ;############################################################### ; Таким образом, ; если Temp,0 = 1, значит принят бит с уровнем 0, ; если Temp,1 = 1, значит принят бит с уровнем 1, ; если Temp,2 = 1, значит принято условие старта. ;###############################################################
;============================================================================================ ; ПП обнаружения (или нет) условия старта. ;============================================================================================ FILTER call SYNHRO ; Переход в ПП SYNHRO с целью заполнения ;----> Возврат по стеку из ПП SYNHRO. ; битов №№0,1,2 регистра Temp. btfsc Temp,2 ; Temp,2=0 (условия старта нет) или =1 (условие старта есть)? goto METKA ; Если Temp,2=1, то это считается ошибкой. ; В этом случае, переход на начало полного цикла программы. return ; Если Temp,2=0, то возврат по стеку в ПП OBRABOTKA ; (разрешение обработки принятых "пачек" импульсов).
Пост N: 640
Зарегистрирован: 16.03.09
Откуда: Родина, Севастополь
Рейтинг:
1
Отправлено: 10.04.13 22:42. Заголовок: Продолжение ;*******..
Продолжение
;************************************************************************************************* ; ФУНКЦИИ ;************************************************************************************************* ; Инициализация МК. ;-------------------------------------------------------------------------------------------- INIT_MK bsf STATUS,RP0 ; Переход в 1-й банк. movlw TRISA_CONST movwf TRISA movlw TRISB_CONST movwf TRISB ; работают на выход. clrf OPTION_REG ; Подтягивающие резисторы включены, TMR0 считает ; внутренний такт, предделитель (1:2) подключен к TMR0. bcf STATUS,RP0 ; Переход в 0-й банк. movlw b'10100101' ; Работает один компаратор, movwf CMCON ; состояния выхода - инверсные. clrf INTCON ; Запрет прерываний. movlw PORTA_CONST movwf PORTA ; Сброс в 0 защелок порта А. movlw PORTB_CONST movwf PORTB ; Сброс в 0 защелок порта В. return ;************************************************************************************************* INIT_LCD ;------------------------------------------------------------------------------------------------- ; FUNCTION SET ;------------------------------------------------------------------------------------------------- movlw b'00100000' ; Запись только одного старшего п/байта "0010". movwf Temp ; Перепишем команду во временный регистр. bcf RS ; RS=0 - запись команды. call One ; Вывод только одного младшего п/байта "0010". movlw b'00101000' ; 4x битный интерфейс двустрочный дисплей шрифт 5х8. call Zap_com ; Записать команду. ;------------------------------------------------------------------------------------------------- ; DISPLAY ON/OFF MODE ;------------------------------------------------------------------------------------------------- movlw MODE_DISP ; Дисплей включен, курсор выключен, мерцание выключено. call Zap_com ; Записать команду. ;------------------------------------------------------------------------------------------------- ; DISPLAY CLEAR с паузой > 1.53 ms. ;------------------------------------------------------------------------------------------------- movlw b'00000001' ; Очистка дисплея. call Zap_com ; Записать команду.
movlw .113 ; 113 Установка 1500 мкс call Pause_X_10 ; Переход в ПП задержки (1500мкс.+40мкс с паузой ПП Zap_com). ;------------------------------------------------------------------------------------------------- ; ENTRY MODE SET ;------------------------------------------------------------------------------------------------- movlw MODE_SET ; Увеличение указателя при операции с памятью, сдвигание дисплея выключено. call Zap_com ; Записать команду. return ;------------------------------------------------------------------------------------------------- ; Процедура записи байта сообщения в защелки портов ;------------------------------------------------------------------------------------------------- Out_byte_ind btfsc Temp,7 ; Если 7-й бит посылки = 0, то следующая команда пропускается. bsf DB7 ; DB7=1. btfss Temp,7 ; Если 7-й бит посылки = 1, то следующая команда пропускается. bcf DB7 ; DB7=0. ;-------------------------------------- btfsc Temp,6 ; Если 6-й бит посылки = 0, то следующая команда пропускается. bsf DB6 ; DB6=1. btfss Temp,6 ; Если 6-й бит посылки = 1, то следующая команда пропускается. bcf DB6 ; DB6=0. ;-------------------------------------- btfsc Temp,5 ; Если 5-й бит посылки = 0, то следующая команда пропускается. bsf DB5 ; DB5=1. btfss Temp,5 ; Если 5-й бит посылки = 1, то следующая команда пропускается. bcf DB5 ; DB5=0. ;-------------------------------------- btfsc Temp,4 ; Если 4-й бит посылки = 0, то следующая команда пропускается. bsf DB4 ; DB4=1. btfss Temp,4 ; Если 4-й бит посылки = 1, то следующая команда пропускается. bcf DB4 ; DB4=0. return ;------------------------------------------------------------------------------------------------- ; ПП записи данных и команды. ;------------------------------------------------------------------------------------------------- Zap_com bcf RS ; RS=1 - запись команды. movwf Temp ; Перепишем команду во временный регистр. goto Zap_c_d Zap_dig andlw b'00001111' ; Процедура обнуления старшего полубайта и прибавления 0x30 addlw 0x30 Zap_dan bsf RS ; RS=1 - запись данных. movwf Temp ; Перепишем данные во временный регистр. Zap_c_d call Out_byte_ind ; Подготовка к записи байта. call Zapis ; Запись байта. swapf Temp,F ; Поменяем местами п/байты регистра Temp. One call Out_byte_ind ; Подготовка к записи байта. call Zapis ; Запись байта. movlw .3 call Pause_X_10 ; Переход в ПП задержки (задержка = 10мкс.). return ;------------------------------------------------------------------------------------------------- ; Момент записи в LCD. ;------------------------------------------------------------------------------------------------- Zapis bsf E ; E=1 - запись. goto $+1 ; 1 мкс - пауза для записи. goto $+1 ; Делаем 6 м.ц., для любой F_OSC goto $+1 ; bcf E ; E=0 - выключить запись. return ;------------------------------------------------------------------------------------------------- ; Регулируемая ПП задержки. ;------------------------------------------------------------------------------------------------- Pause_X_10 movwf Count1 ; Копирование количества проходов из W в Count1. Pause_10 ; ПП 1 паузы примерно на 10мкс при F_OSC от 4МГц movlw F_OSC movwf T_Del decfsz T_Del,F goto $-1 decfsz Count1,F goto Pause_10 return ; Если Count1 декрементирован до 0,то возврат по стеку.
end ; Конец программы.
Возможны не совпадения коментов, т.к. повторюсь, не поправлял ещё. Но код работает в протеусе.
Все даты в формате GMT
3 час. Хитов сегодня: 8
Права: смайлы да, картинки да, шрифты нет, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет