Реверс инжиниринг полурабочего «Простого радиоуправляемого радиомикрофона на MRF49XA» от Blaze 1.0
Реверс инжиниринг прошивки PIC12F675 радиоуправляемого радиомикрофона на MRF49XA от Blaze с сайта vrtp.ru. Исправление ошибок.
Источник схемы: vrtp .ru/index.php?act=categories&CODE=article&article=3813
Параметры MRF49XA
- Выпуск начат в 2009 году
- Диапазоны 433 МГц, 868 МГц, 915 МГц
- Приемник с чувствительностью -112 дБмВт (0.5 мкВ) на 433 МГц построен по схеме с прямым преобразованием частоты (привет дедушке Полякову)
- Передатчик имеет мощность 7 дБмВт (5 мВт) на частоте 433 МГц при напряжении питания 3.3В
- Напряжение питания 2.2-3.8В
- Токопотребление 15 мА — передача, 10 мА — прием, 0.3 мкА — сон
- Аналог: SI4421
Недостатки
- Неправильные номиналы емкостей и индуктивностей — заниженная мощность и плохой КСВ.
- Длина идентификатора 1 байт — возможен полный перебор.
- После включения передатчика контроллер не засыпает — завышенное потребление тока.
Не будем останавливаться на проблемах НЧ части. Они полностью разобраны в статье о радиомикрофоне серии “R” от Flight на MAX1472. Просто замените ее хорошей схемой с АРУ от Kotu.
Поскольку длина идентификатора всего лишь 1 байт, а частота по умолчанию 439 МГц ровно, можно сделать «мастер пульт», который будет перебирать все значения от 0 до 255 и включать все радиомикрофоны от Blaze в округе.
Сделать идентификатор 32-битным — это будет ваше первое домашнее задание (контрольную сумму 32-битного идентификатора проверять не обязательно).
Для уменьшения энергопотребления контроллер периодически просыпается, включает приемник MRF49XA и пытается принять посылку с пульта. Вполне рабочая стратегия, но MRF49XA умеет это делать и без помощи контроллера, наверняка расходуя при этом еще меньше (1.5 мкА, стр. 80 даташита) заряда батареи:
The MRF49XA can be made to enter into a Low Duty
Cycle mode operation to decrease the average power
consumption in Receive mode. The Low Duty Cycle
mode is normally used in conjunction with the wake-up
timer for its operation. The DCSREG may be config-
ured so that when the wake-up timer brings the device
out of Sleep mode, the receiver is turned on for a short
time to sample for a signal. Then, the device returns to
Sleep and this process repeats.
3.15 Low Duty Cycle Mode (стр. 61)
In Low Duty Cycle mode, the receiver periodically
wakes up for a short period and checks for the valid
FSK transmission in progress.
Гораздо хуже, что все номиналы индуктивностей и емкостей неправильные, неправильная и схема подключения антенны. Правильную схему и номиналы ВЧ части см. в даташите на стр. 76.
Больше всего отличается индуктивность L1 (обозначение по схеме из даташита на стр. 76) — правильное значение в десять раз больше!
В даташите особо оговорено, что подходят только СВЧ индуктивности с малой паразитной емкостью (стр. 75 и 77), например: LQW18ANR39J00D, MLG1608B33NJ и MLG1608B47NJ. Китайские зеленые дроссели не подходят!
Тем не менее, «работать» с этими номиналами радиомикрофон будет, но гораздо хуже (меньше дальность и, возможно, глюки из-за большого КСВ).
Впрочем, для того и выложена эта схема, чтобы вы не полезли читать даташит и не сделали свою, качественно работающую конструкцию.
Конденсаторов по питанию должно быть три (и четвертый — электролит): 2.2u, 10n, 220p. См. стр. 13 даташита.
Во время работы передатчика микроконтроллер гоняет пустые циклы. Лучше бы он засыпал — было бы меньше токопотребление (это второе ваше домашнее задание).
Жаль, что всякие вкусности микросхемы MRF49 типа детектора разряда батареи и автосброса при скачке по питанию (стр. 45) остались незадействованными. Ведь глубокий разряд аккумуляторов очень быстро приводит их в негодность.
Рекомендуемое напряжение питания MRF49XA 2.2...3.8В (стр. 3), а указанное 5В просто не выводит микросхему из строя (стр. 79). MRF49XA нельзя эксплуатировать с таким высоким напряжением питания.
Как сказано в даташите, надежный запуск кварцевого генератора зависит от наличия полезной паразитной емкости, которую нужно создать искусственно, оставив «землю» под кварцем (стр. 48). Если габариты не позволяют, то нужно подключить 1 пф параллельно кварцу:
The crystal oscillator circuit is sensitive to parasitic
capacitance for start-up. A small amount of parasitic
capacitance is needed to facilitate oscillation. To achieve
this, create a ground plane around the crystal and widen
the connection to the MRF49XA. This is to adjust the ref-
erence frequency and to compensate for stray capaci-
tance that might be introduced due to PCB layout. If the
layout is not possible, a 0.5-1 pF capacitor, soldered
across the crystal, will initiate the start-up. Also, see
Section 3.6 “Crystal Selection Guidelines” for
selecting the right crystal.
Кажется, забыли конденсатор 1n с 7 ноги на землю (возможно, он и не используется, см. стр. 57).
Интересно, что на MRF49XA, возможно, получится сделать радиомикрофон с шумоподобным спектром:
The MRF49XA is the best option for Frequency Hopping
Spread Spectrum (FHSS) applications requiring
frequency agility to meet FCC, IC or ETSI requirements.
Частоту легко можно менять 3000 раз в секунду (см. параметр PLL Lock Time на стр. 82).
Перед сборкой этой схемы обязательно прочитайте даташит на MRF49XA от корки до корки. Также см. AN1252. Если найдете исходники на microchip.com, напишите ссылку в комментариях.
Я ее не собирал! Возможно, я что-то понял неправильно. Возможно, в ней есть и другие ошибки.
Контрольный список для исправления ошибок
- Заменить УНЧ на схему Kotu с АРУ
- ВЧ часть сделать как в даташите на стр. 76
- Крепить радиомикрофон магнитом на металлическую поверхность или использовать противовес
- Развязать варикап по постоянному току, чтобы напряжение на нем не опускалось ниже 1 В
- Не поднимать напряжение питания MRF49XA выше рекомендованных 3.8В
- Зашунтировать микрофон конденсатором 100 пф (уже сделано у Kotu)
- Увеличить в прошивке длину идентификатора до 24-32 бит, прошить в EEPROM уникальный случайный идентификатор (потребуется и модификация пульта)
Сборка (компилирование) прошивки PIC
apt install gputils gpasm mrf49.asm -o mrf49.hex
Перекомпилированная прошивка отличается от оригинальной двумя строками (напишите в комментариях, почему):
-:02400E00CC01E3 +:02400E00CC31B3
Чтобы дезассемблировать прошивку пульта, см. команды в статье «Реверс инжиниринг Трёшки от Eddy71».
Исходник прошивки PIC12F675 радиоуправляемого радиомикрофона на MRF49XA от Blaze
Дизассемблированная прошивка с комментариями:
processor p12f675
radix dec
include p12f675.inc
; The recognition of labels and registers is not always good, therefore
; be treated cautiously the results.
CONFIG FOSC = INTRCIO
CONFIG WDTE = ON
CONFIG PWRTE = ON
CONFIG MCLRE = OFF
CONFIG BOREN = ON
CONFIG CP = OFF
CONFIG CPD = OFF
;===============================================================================
; PINS usage definitions
; PIC 7, MRF 6 - данные MRF49XA
#define MRF49_DATA GP0
; PIC 5 - питание УНЧ
#define AMP_POWER GP2
; PIC 2, MRF 1
#define MRF49_SDI GP5
; PIC 6, MRF 3
#define MRF49_CS GP1
; PIC 3, MRF 2
#define MRF_SCK GP4
;===============================================================================
; Макросы
movlf MACRO value, file
movlw (value)
movwf (file)
ENDM
movff MACRO src, dst
movf (src), W
movwf (dst)
ENDM
;===============================================================================
; Определения
; команды для переключения режимов MRF49XA записаны в EEPROM:
#define EEPROM_MRF_CFG_TX 0x00 ; передача
#define MRF_CFG_ON_LEN 5
#define EEPROM_MRF_CFG_RX 0x10 ; прием
#define MRF_CFG_OFF_LEN 6
; периодическое выключение приемника для экономии заряда
#define EEPROM_SLEEP 0x1c
#define DUTY_CYCLE 100
#define EEPROM_IDENT 0x20 ; смещение уникального идентификатора
#define FA1_433 1
#define FA0_433 43
#define FA1_868 2
#define FA0_868 43
#define FA1_915 3
#define FA0_915 30
#define FVAL_433(freq) ((((freq)/FA1_433) - FA0_433*10000000) / 2500)
#define FVAL_868(freq) ((((freq)/FA1_868) - FA0_868*10000000) / 2500)
#define FVAL_915(freq) ((((freq)/FA1_915) - FA0_915*10000000) / 2500)
; см. стр. 28 даташита
#define RX_FVAL FVAL_433(439000000) ; частота приемника (шаг 2.5 кГц)
#define RX_BAND MRF_FBS_434
#define TX_FVAL FVAL_433(439000000) ; частота передатчика (шаг 2.5 кГц)
#define TX_BAND MRF_FBS_434
; проверка границ установки частоты
if (RX_FVAL < 96) || (RX_FVAL > 3903)
error "Receiver frequency out of range"
endif
if (TX_FVAL < 96) || (TX_FVAL > 3903)
error "Transmitter frequency out of range"
endif
; скорость передачи данных 407296 бит/с и полоса 400 кГц -
; явно бредовая комбинация, см. формулу на стр. 56 и далее параграф
; 3.10.2 DIGITAL FILTERING MODE на стр. 57
#define REMOTE_CONTROL_RATE 407296
#define SELECTED_MRF_BW MRF_RXBW_400K
;===============================================================================
; MRF49XA
; https://raw.githubusercontent.com/dvdfreitag/MRF49XA-Library/refs/heads/master/MRF49XA_definitions.h
; Created by William Dillon on 11/2/10.
; Copyright 2010 Oregon State University. All rights reserved.
; Modified by David Freitag on 1/13/15
; General Configuration Register
#define MRF_GENCREG 0x8000 ; General configuration register addres
#define MRF_TXDEN 0x0080 ; TX Data Register enable bit
#define MRF_FIFOEN 0x0040 ; FIFO enable bit
#define MRF_FBS_MASK 0x0030 ; Mask for the band selection
#define MRF_LCS_MASK 0x000F ; Mask for the crystal load capactiance
; 10pF Crystal load capacitance
#define MRF_LCS 3 ; Crystal Load capactiance
; Frequency band settings
#define MRF_FBS_434 0x0010 ; 434 mHz band
#define MRF_FBS_868 0x0020 ; 868 mHz band
#define MRF_FBS_915 0x0030 ; 915 mHz band
; Power Management Configuration Register
#define MRF_PMCREG 0x8200 ; Power Mgmt. Config. Register address
#define MRF_RXCEN 0x0080 ; Receiver chain enable
#define MRF_BBCEN 0x0040 ; Baseband chain enable
#define MRF_TXCEN 0x0020 ; Transmitter chain enable
#define MRF_SYNEN 0x0010 ; Synthesier enable
#define MRF_OSCEN 0x0008 ; Oscillator enable
#define MRF_LBDEN 0x0004 ; Low Battery Detector Enable
#define MRF_WUTEN 0x0002 ; Wakeup timer enable
#define MRF_CLKODIS 0x0001 ; Clock output disable
#define MRF_RXCREG 0x9000 ; Receive control register address
#define MRF_FINTDIO 0x0400 ; Function interrupt/dio output
#define MRF_DIORT_MASK 0x0300 ; Data indicator response time
#define MRF_RXBW_MASK 0x00E0 ; Receiver baseband bandwidth
#define MRF_RXLNA_MASK 0x0018 ; Receiver LNA gain
#define MRF_DRSSIT_MASK 0x0007 ; Digital RSSI threshold
; Data indicator output response time
#define MRF_DIORT_CONT 0x0300 ; Continuous
#define MRF_DIORT_SLOW 0x0200 ; Slow
#define MRF_DIORT_MED 0x0100 ; Medium
#define MRF_DIORT_FAST 0x0000 ; Fast
; Receiver Baseband bandwidth
#define MRF_RXBW_67K 0x00C0 ; Receiver Bandwidth 67 khz
#define MRF_RXBW_134K 0x00A0 ; Receiver Bandwidth 134 khz
#define MRF_RXBW_200K 0x0080 ; Receiver Bandwidth 200 khz
#define MRF_RXBW_270K 0x0060 ; Receiver Bandwidth 270 khz
#define MRF_RXBW_340K 0x0040 ; Receiver Bandwidth 340 khz
#define MRF_RXBW_400K 0x0020 ; Receiver Bandwidth 400 khz
; Receiver LNA Gain
#define MRF_RXLNA_20DB 0x0018 ; LNA Gain -20dB
#define MRF_RXLNA_14DB 0x0010 ; LNA Gain -14dB
#define MRF_RXLNA_6DB 0x0008 ; LNA Gain -6dB
#define MRF_RXLNA_0DB 0x0000 ; LNA Gain 0dB
; Digital RSSI threshold
#define MRF_DRSSIT_73db 0x0005 ; -73dB Threshold
#define MRF_DRSSIT_79db 0x0004 ; -79dB Threshold
#define MRF_DRSSIT_85db 0x0003 ; -85dB Threshold
#define MRF_DRSSIT_91db 0x0002 ; -91dB Threshold
#define MRF_DRSSIT_97db 0x0001 ; -97dB Threshold
#define MRF_DRSSIT_103db 0x0000 ; -103dB Threshold
; *******************************************************************************
; * Convenience definitions for transmitter control register
; *
; * These defines are provided for use configuring the MRF49XA module.
; * Select the modulation bandwidth and output power by bit-wise oring them
; * with the register address.
; *
; * Use the MRF_TXCREG_SET for Microchip defaults
; *
; *******************************************************************************
; Transmit Configuration register
#define MRF_TXCREG 0x9800 ; Transmit configuration register address
#define MRF_MODPLY 0x0100 ; Modulation polarity
#define MRF_MODBW_MASK 0x00F0 ; Modulation bandwidth
#define MRF_OTXPWR_MASK 0x0007 ; Output transmit power
; Modulation bandwidth settings
#define MRF_MODBW_240K 0x00F0 ; 240kHz modulation bandwidth
#define MRF_MODBW_225K 0x00E0 ; 225kHz modulation bandwidth
#define MRF_MODBW_210K 0x00D0 ; 210kHz modulation bandwidth
#define MRF_MODBW_195K 0x00C0 ; 195kHz modulation bandwidth
#define MRF_MODBW_180K 0x00B0 ; 180kHz modulation bandwidth
#define MRF_MODBW_165K 0x00A0 ; 165kHz modulation bandwidth
#define MRF_MODBW_150K 0x0090 ; 150kHz modulation bandwidth
#define MRF_MODBW_135K 0x0080 ; 135kHz modulation bandwidth
#define MRF_MODBW_120K 0x0070 ; 120kHz modulation bandwidth
#define MRF_MODBW_105K 0x0060 ; 105kHz modulation bandwidth
#define MRF_MODBW_90K 0x0050 ; 90kHz modulation bandwidth
#define MRF_MODBW_75K 0x0040 ; 75kHz modulation bandwidth
#define MRF_MODBW_60K 0x0030 ; 60kHz modulation bandwidth
#define MRF_MODBW_45K 0x0020 ; 45kHz modulation bandwidth
#define MRF_MODBW_30K 0x0010 ; 30kHz modulation bandwidth
#define MRF_MODBW_15K 0x0000 ; 15kHz modulation bandwidth
; Output power settings
#define MRF_OTXPWR_17D5 0x0007 ; -17.5dB Transmit Output Power
#define MRF_OTXPWR_15D0 0x0006 ; -15.0dB Transmit Output Power
#define MRF_OTXPWR_12D5 0x0005 ; -12.5dB Transmit Output Power
#define MRF_OTXPWR_10D5 0x0004 ; -10.5dB Transmit Output Power
#define MRF_OTXPWR_7D5 0x0003 ; - 7.5dB Transmit Output Power
#define MRF_OTXPWR_5D0 0x0002 ; - 5.0dB Transmit Output Power
#define MRF_OTXPWR_2D5 0x0001 ; - 2.5dB Transmit Output Power
#define MRF_OTXPWR_0 0x0000 ; 0.0dB Transmit Output Power
#define MRF_CFSREG 0xA000 ; Center Frequency value register address
#define MRF_AFCCREG 0xC400 ; AFC configuration register address
; Automatic frequency mode selection
#define MRF_AUTOMS_INDP 0x00C0 ; Offset independent for state of DIO sig.
#define MRF_AUTOMS_RECV 0x0080 ; Offset only during receive
#define MRF_AUTOMS_ONCE 0x0040 ; Offset once after power-cycle
#define MRF_AUTOMS_OFF 0x0000 ; Auto mode off
; Allowable tuning range selection
#define MRF_ARFO_3to4 0x0030 ; +3 to -4 Fres (tuning bits)
#define MRF_ARFO_7to8 0x0020 ; +7 to -8 Fres
#define MRF_ARFO_15to16 0x0010 ; +15 to -16 Fres
#define MRF_ARFO_unlim 0x0000 ; Unlimited
; Data Rate Value set register
#define MRF_DRSREG 0xC600 ; Data rate value set register address
#define MRF_DRPE 0x0080 ; Data rate prescaler enable
#define MRF_DRPV_MASK 0x007F ; Data rate value mask
;===============================================================================
; DATA address definitions
Common_RAM equ 0x0020 ; size: 64 bytes
i equ (Common_RAM + 1)
j equ (Common_RAM + 2)
k equ (Common_RAM + 3)
timer equ (Common_RAM + 4) ; счетчик до выкл.
mrf49_word equ (Common_RAM + 5) ; регистр MRF49XA
rxbit equ (Common_RAM + 7) ; принятый бит
; принятая 32-битная посылка с пульта
rx_ident equ (Common_RAM + 8) ; идентификатор
rx_ident_crc equ (Common_RAM + 9)
rx_timer equ (Common_RAM + 10) ; время включения
rx_timer_crc equ (Common_RAM + 11)
pulse_len equ (Common_RAM + 12) ; длина импульса
;===============================================================================
; CODE area
; code
org __CODE_START ; address: 0x0000
vector_reset: ; address: 0x0000
bsf STATUS, RP0
; что это такое?
call 0x03ff
movwf T1CON
clrf ADCON0
vector_int: ; address: 0x0004
clrf GPIO
movlf 3, TMR0
bcf STATUS, RP0
movlf 0x31, T1CON
movlf 0x07, CMCON
clrf GPIO ; зачем еще раз?
call function_shortdelay
; если EEPROM пустая,
; записать в нее команды для переключения режимов MRF49XA по умолчанию
call function_eeprom_init
; короткий выход в эфир при включении питания
call function_short_on
; главный цикл
; пытаемся принять посылку, засыпаем, повторяем
forever:
clrwdt
btfsc GPIO, MRF49_DATA
call function_receive_command
btfss PIR1, T1IF
goto forever
call function_sleep
goto forever
function_decode_bit:
clrf rxbit
; ожидаем поднятия DATA в течение 200 попугаев
movlf 200, TMR0
bcf INTCON, T0IF
wait_data_high:
clrwdt
btfsc GPIO, MRF49_DATA
goto data_high
; 1 = TMR0 register has overflowed (must be cleared in software)
btfss INTCON, T0IF
goto wait_data_high
; не дождались
return
data_high:
; теперь измеряем длительность импульса
clrf TMR0
bcf INTCON, T0IF
wait_data_low:
btfss GPIO, MRF49_DATA
goto data_low
btfss INTCON, T0IF
goto wait_data_low
data_low:
; запоминаем измеренную длительность
movff TMR0, pulse_len
movlw 20
subwf pulse_len, W
btfsc STATUS, C
incf rxbit, F ; больше 20
movlw 40
subwf pulse_len, W
btfsc STATUS, C
incf rxbit, F ; больше 40
movlw 80
subwf pulse_len, W
btfsc STATUS, C
clrf rxbit ; больше 80 - ошибка
return
function_receive_command: ; address: 0x0036
; синхронизация по концу посылки
; принять 32 бита
movlf 32, Common_RAM
decode_next_bit: ; address: 0x0038
; 0 - ошибка, 1 - лог. 1, 2 - лог. 0
call function_decode_bit
; ошибка
movf rxbit, F
btfsc STATUS, Z
return
; поместить принятый бит в флаг переноса (проще - rrf rxbit)
btfsc rxbit, 0
bsf STATUS, C
btfss rxbit, 0
bcf STATUS, C
; сдвигаем 4 байта вправо, перенос становится старшим битом посылки
rrf rx_timer_crc, F
rrf rx_timer, F
rrf rx_ident_crc, F
rrf rx_ident, F
decfsz Common_RAM, F
goto decode_next_bit
; прием посылки завершен
; проверка контрольной суммы идентификатора
; (лучше бы у идентификатора было 32 бита)
movff rx_ident, (Common_RAM + 1)
movff rx_ident_crc, (Common_RAM + 2)
call function_check_crc
btfss STATUS, Z
return
; проверка контрольной суммы времени включения
movff rx_timer, (Common_RAM + 1)
movff rx_timer_crc, (Common_RAM + 2)
call function_check_crc
btfss STATUS, Z
return
; читаем из EEPROM наш идентификатор
bsf STATUS, RP0
movlf EEPROM_IDENT, EEADR
bcf STATUS, RP0
call function_eeprom_read_next
; принятый идентификатор равен нашему?
subwf rx_ident, W
btfss STATUS, Z
return
; да - включаем передатчик на rx_timer попугаев
call function_transmitter_timer
return
function_transmitter_timer: ; address: 0x005e
; включаем передатчик
call function_transmitter_on
; запускаем таймер выключения (гоняем пустые циклы, а лучше бы засыпать)
movff rx_timer, timer
call function_shortdelay228
decfsz timer, F
goto $-2
; выключаем передатчик и включаем приемник
call function_receive
clrf TMR1L
clrf TMR1H
bcf PIR1, T1IF
return
function_check_crc: ; address: 0x0069
; [3] = reverse(2)
; return [3] - ([1] ^ 0xff)
clrf (Common_RAM + 3)
btfsc (Common_RAM + 2), 0x7
bsf (Common_RAM + 3), 0x0
btfsc (Common_RAM + 2), 0x6
bsf (Common_RAM + 3), 0x1
btfsc (Common_RAM + 2), 0x5
bsf (Common_RAM + 3), 0x2
btfsc (Common_RAM + 2), 0x4
bsf (Common_RAM + 3), 0x3
btfsc (Common_RAM + 2), 0x3
bsf (Common_RAM + 3), 0x4
btfsc (Common_RAM + 2), 0x2
bsf (Common_RAM + 3), 0x5
btfsc (Common_RAM + 2), 0x1
bsf (Common_RAM + 3), 0x6
btfsc (Common_RAM + 2), 0x0
bsf (Common_RAM + 3), 0x7
comf (Common_RAM + 1), W
subwf (Common_RAM + 3), W
return
function_short_on: ; address: 0x007d
call function_mrf49_off
call function_transmitter_on
call function_shortdelay4
call function_mrf49_off
return
function_transmitter_on: ; address: 0x0082
bsf GPIO, AMP_POWER ; включить УНЧ
bsf STATUS, RP0
clrf EEADR ; EEPROM_MRF_CFG_TX
bcf STATUS, RP0
; загрузить в MRF49 конфигурацию из EEPROM
movlf MRF_CFG_ON_LEN, i
label_009: ; address: 0x0088
call function_eeprom_read_next
movwf mrf49_word + 1
call function_eeprom_read_next
movwf mrf49_word
call function_mrf49_control
decfsz i, F
goto label_009
bsf STATUS, RP0
bcf TRISIO, TRISIO0
bcf STATUS, RP0
bcf GPIO, MRF49_DATA
return
function_receive: ; address: 0x0094
bcf GPIO, AMP_POWER ; выключить УНЧ
bsf STATUS, RP0
movlf EEPROM_MRF_CFG_RX, EEADR
bcf STATUS, RP0
; загрузить в MRF49 конфигурацию из EEPROM (6 слов)
movlf MRF_CFG_OFF_LEN, i
label_010:
call function_eeprom_read_next
movwf mrf49_word + 1
call function_eeprom_read_next
movwf mrf49_word
call function_mrf49_control
decfsz i, F
goto label_010
bsf STATUS, RP0
bsf TRISIO, TRISIO0
bcf STATUS, RP0
return
function_sleep: ; address: 0x00a6
bcf GPIO, AMP_POWER ; выключить УНЧ
; режим низкого энергопотребления (отключены передатчик и приемник)
call function_mrf49_off
; периодичность включения приемника записана в EEPROM
bsf STATUS, RP0
movlf EEPROM_SLEEP, EEADR
bcf STATUS, RP0
call function_eeprom_read_next
; засыпаем
movwf k
sleep
sleep
decfsz k, F
goto $-3
; включаем приемник
call function_receive
clrf TMR1L
clrf TMR1H
bcf PIR1, T1IF
return
function_mrf49_off: ; address: 0x00b7
movlf high MRF_PMCREG, mrf49_word + 1 ; стр. 38 даташита
movlf MRF_CLKODIS, mrf49_word
call function_mrf49_control
bsf STATUS, RP0
bcf TRISIO, TRISIO0
bcf STATUS, RP0
bsf GPIO, MRF49_DATA
return
function_eeprom_init: ; address: 0x00c1
; конфиругация передатчика MRF49
bsf STATUS, RP0
clrf EEADR ; EEPROM_MRF_CFG_TX
bcf STATUS, RP0
; GENCREG: GENERAL CONFIGURATION REGISTER (page 22)
movlw high MRF_GENCREG
call function_eeprom_write_next
; bit 5-4FBS<1:0>: Frequency Band Select bits - диапазон
; These bits set the frequency band to be used in Sub-GHz range.
; 01 = 433 MHz
; bit 3-0LCS<3:0>: Load Capacitance Select bits
; These bits set and vary the internal load capacitance for the crystal reference.
; 1111 = 16.0 pF
movlw TX_BAND | MRF_LCS_MASK
call function_eeprom_write_next
; CFSREG: CENTER FREQUENCY VALUE SET REGISTER (page 28)
movlw high MRF_CFSREG | (high TX_FVAL)
call function_eeprom_write_next
; bit 11-0FREQB<11:0>: Center Frequency Set bits - частота
; These bits set the center frequency to be used during transmit or receive. The 12-bit value (FVAL) must
; be in a decimal range of 96 to 3903. The value outside this range results in the previous value being
; retained and used such that no frequency change occurs
movlw low TX_FVAL
call function_eeprom_write_next
; TXCREG: TRANSMIT CONFIGURATION REGISTER (page 25)
movlw high MRF_TXCREG
call function_eeprom_write_next
; bit 7-4MODBW<3:0>: Modulation Bandwidth bits
; These bits set the FSK frequency deviation for transmitting the logic ‘1’ and logic ‘0’.(1)
; 0000 = 15 kHz
; OTXPWR<2:0>: Output Transmit Power Range bits
; 000 = 0 dB (максимальная мощность)
movlw MRF_MODBW_15K | MRF_OTXPWR_0
call function_eeprom_write_next
; AFCCREG: AUTOMATIC FREQUENCY CONTROL CONFIGURATION REGISTER
movlw high MRF_AFCCREG
call function_eeprom_write_next
; отключить автоподстройку частоты (АПЧ)
; 00 = Auto mode off (controlled by microcontroller)
; These bits select the offset range allowable between transmitter and receiver frequencies.
; 00 = No restriction
; MFCS: Manual Frequency Control Strobe bit
; 0 = Ready for the next sample
; HAM: High-Accuracy (Fine) Mode bit
; 0 = Frequency Control mode works in regular mode
; FOREN: Frequency Offset Register Enable bit
; 0 = Denies the addition of the offset value to the frequency control word of the PLL
; FOFEN: Frequency Offset Enable bit
; 0 = Disables the frequency offset calculation using the AFC circuit
movlw MRF_AUTOMS_OFF
call function_eeprom_write_next
; PMCREG: POWER MANAGEMENT CONFIGURATION REGISTER (page 38)
movlw high MRF_PMCREG
call function_eeprom_write_next
; передатчик включен, приемник выключен, синтезатор включен
; индикатор разряда батареи выключен, таймер пробуждения отключен
movlw MRF_TXCEN | MRF_SYNEN | MRF_OSCEN | MRF_CLKODIS
call function_eeprom_write_next
bsf STATUS, RP0
; конфиругация приемника MRF49
movlw EEPROM_MRF_CFG_RX
movwf EEADR
bcf STATUS, RP0
; GENCREG: GENERAL CONFIGURATION REGISTER (page 22)
movlw high MRF_GENCREG
call function_eeprom_write_next
; см. выше
movlw RX_BAND | MRF_LCS_MASK
call function_eeprom_write_next
; CFSREG: CENTER FREQUENCY VALUE SET REGISTER
movlw high MRF_CFSREG | (high RX_FVAL)
call function_eeprom_write_next
; см. выше
movlw low RX_FVAL
call function_eeprom_write_next
; RXCREG: RECEIVE CONTROL REGISTER (page 29)
; bit 9-8DIORT<1:0>: Data Indicator Output Response Time bits
; 01 = Medium
movlw high MRF_RXCREG | high MRF_DIORT_MED
call function_eeprom_write_next
; RXBW<2:0>: Receiver Baseband Bandwidth bits
; bit 4-3RXLNA<1:0>: Receiver LNA Gain bits
; 00 = 0 dB (наибольшая чувствительность)
; DRSSIT<2:0>: Digital RSSI Threshold bits
; 000 = -103 dB (наибольшая чувствительность)
movlw SELECTED_MRF_BW | MRF_RXLNA_0DB | MRF_DRSSIT_103db
call function_eeprom_write_next
; DRSREG: DATA RATE VALUE SET REGISTER (page 37)
movlw high MRF_DRSREG
call function_eeprom_write_next
; DRPE: Date Rate Prescaler Enable bit
; 1 = Enables the prescaler to obtain smaller values of expected data rates.
; DRPV<6:0>: Data Rate Parameter Value bits
; If the prescaler is not used, the data rates range
; from 2.694 kbps to 344.828 kbps
movlw (REMOTE_CONTROL_RATE/(10000/29)/8)
call function_eeprom_write_next
; AFCCREG: AUTOMATIC FREQUENCY CONTROL CONFIGURATION REGISTER (page 23)
movlw high MRF_AFCCREG
call function_eeprom_write_next
; отключить АПЧ
movlw MRF_AUTOMS_OFF
call function_eeprom_write_next
; Power Management Configuration Register
movlw high MRF_PMCREG
call function_eeprom_write_next
movlw MRF_RXCEN | MRF_BBCEN | MRF_SYNEN | MRF_OSCEN | MRF_CLKODIS
call function_eeprom_write_next
; адрес сейчас равен EEPROM_SLEEP
movlw DUTY_CYCLE
call function_eeprom_write_next
return
function_mrf49_control: ; address: 0x00f7
bcf GPIO, MRF49_CS
movlf 16, Common_RAM
label_012:
btfsc mrf49_word + 1, 7
call function_mrf49_bit1
btfss mrf49_word + 1, 7
call function_mrf49_bit0
rlf mrf49_word, F
rlf mrf49_word + 1, F
decfsz Common_RAM, F
goto label_012
bsf GPIO, MRF49_CS
return
function_mrf49_bit0: ; address: 0x0104
bcf GPIO, MRF49_SDI
goto label_013
function_mrf49_bit1: ; address: 0x0106
bsf GPIO, MRF49_SDI
label_013:
clrwdt
bsf GPIO, MRF_SCK
clrwdt
bcf GPIO, MRF_SCK
clrwdt
return
function_shortdelay: ; address: 0x010d
clrf i
clrf j
clrwdt
decfsz j, F
goto $-2
decfsz i, F
goto $-2
return
function_shortdelay4: ; address: 0x0115
movlf 4, k
call function_shortdelay
decfsz k, F
goto $-2
return
function_shortdelay228: ; address: 0x011b
movlf 228, k
call function_shortdelay
decfsz k, F
goto $-2
return
function_eeprom_write_next: ; address: 0x0121
; "бережная" запись в EEPROM?
bsf STATUS, RP0
bsf EECON1, RD
comf EEDAT, F ; проверка на 0xff
btfss STATUS, Z ; ячейка пустая?
goto alredy_written
movwf EEDATA
bsf EECON1, WREN
call function_eeprom_write
alredy_written: ; address: 0x0129
incf EEADR, F
bcf STATUS, RP0
return
function_eeprom_write: ; address: 0x012c
; Flash programming unlock sequence
movlf 0x55, EECON2
movlf 0xaa, EECON2
bsf EECON1, WR
clrwdt
btfsc EECON1, WR
goto $-2
bcf EECON1, WREN
return
function_eeprom_read_next ; address: 0x0136
bsf STATUS, RP0
bsf EECON1, RD
movf EEDAT, W
incf EEADR, F
bcf STATUS, RP0
return
end
end© Copyright 2025 Badradio. All rights reserved.
Все права защищены. Копирование материалов сайта запрещено. При цитировании ставить ссылку на первоисточник.