нам нужно управлять генерацией импульсов при помощи Т1
в принципе, как уже обсуждали, все управление это заливка нужной длительности в OCR1A - дальше контроллер сделает все сам.
остался вопрос: каким образом определять эти длительности? я тут накидал один код для прерывания, но боюсь что им запросто отобью у тебя желание писать программы на асме
поэтому пойдем проще: мы после того как зарегистрировали нажатие любой кнопки на клаве подготовим в ОЗУ еще один буфер который будет содержать в себе длительности фаз передаваемых импульсов
то есть примерно так: нужно отправить байт 01001001
импульс у нас стандартной длины ImpLen для нуля мы передаем длину Nullen для единицы Onelen (эти константы мы определим через .define в начале программы, чтобы потом если придется править не лазить и не искать где мы их использовали)
в буфере на передачу должно быть (это схематично):
Код:
ImpLen ; 0 Nullen
ImpLen ; 1 Onelen
ImpLen ; 0 Nullen
ImpLen ; 0 Nullen
ImpLen ; 1 Onelen
ImpLen ; 0 Nullen
ImpLen ; 0 Nullen
ImpLen ; 1 Onelen
теперь программа, следи за мыслью:
Код:
ldi zl, low(transmit_buff) ; зададим адрес начала буфера передачи в ОЗУ ldi zh, high(transmit_buff)
ldi yl, low(key_buff) ; зададим адрес начала буфера прочитанных кнопок (не помню как метка называлась) ldi yh, high(key_buff)
ldi R17, 5 ; количество байт для передачи
keybuffer_loop: ld temp , y+ ; прочитаем байт для передачи
ldi r18, 8 ; количество бит в байте для передачи
byte_loop: ; здесь кодируем импульс для бита ldi r19,high(ImpLen) ; зададим фиксированную длительность импульса st z+, r19 ldi r19,low(ImpLen) st z+, r19
ldi xl, low(Nullen) ; длительность для передачи нуля ldi xh, high(Nullen)
ROL temp ; команда сюрприз! прочитай как работает brnc send_nullen
ldi xl, low(onelen) ; длительность для передачи единицы ldi xh, high(onelen)
send_nullen: st z+, xh ; сохраним в буфере на передачу st z+, xl
dec R18 ; уменьшим счетчик бит на передачу brne byte_loop
dec R17 ; уменьшим счетчик байт для передачи brne keybuffer_loop
попробуй разобраться что у нас получиться в буфере на передачу и как это получилось. особенно как работает ROL.
ДОПОЛНИТЕЛЬНО: модифицируй код чтобы генерить бит четности (в нашем случае ситуацию когда в передаваемых байтах общее число бит=1 четное, нам нужен один бит четности на всю посылку)
угу, думать полезно... может что интереснее придумаешь
uwrtey писал(а):
а не проще будет объединить ImpLen и Onelen - ведь они равны ??? (или тут задумка другая...)
нет, объединять не стоит, мы же не знаем к чему приведут наши эксперименты, вдруг у нас ImpLen потом будет отличаться от Onelen? - придется по коду лазить и менять... хорошо если код в одном файле.. а если нет? так что лучше написать отдельно, тем более это же константы, размер кода не меняется будь одна константа или две
прочитал тут про константы, должно получиться следующее .EQU ImpLen=0xCE4 ; длина импульса .EQU OneLen=0xCE4 ; длина паузы для единицы .EQU NulLen=0x19C8 ; длина паузы для нуля
_________________ не зная броду не лезь к вольтмоду
Сдвиг всех битов Rd на одно место влево. Флаг переноса (С) регистра состояния (SREG) смещается на место бита "0" регистра Rd. Бит "7" смещается во флаг переноса (C).
Флаг переноса (C) устанавливается в "1" , если в результате выполнения операции произошел выход за границы байта
*** тут есть небольшое замечание к первой цитате ... лучше будет если поменять предложения местами - вот так "Сдвиг всех битов Rd на одно место влево. Бит "7" смещается во флаг переноса (C).Флаг переноса (С) регистра состояния (SREG) смещается на место бита "0" регистра Rd." А то можно неправильно понять смысл... (что я сначала и сделал) *** Получается, что команда ROL смещает байт целиком на 1 шаг, зацикливая его или другими словами старший бит занимает место младшего бита - пример 01001001 01001001 10010010 00100101 01001010
Теперь не понятно что такое brnc ! (яндекс то же не знает!)
Цитата:
Код:
ROL temp ; команда сюрприз! прочитай как работает brnc send_nullen
в общих чертах, как работает этот код, я понял. Спойлер
Код:
В ОЗУ появился новый массив - "transmit_buff" в этом массиве будут хранится длительности массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
про бит четности можно поподробней? и как связать этот код с режимом CTC - я не догоняю..........
_________________ не зная броду не лезь к вольтмоду
бит четности это фактически признак четности, нужно посчитать сколько было закодировано бит равных единице, и потом если это число четное - то установить бит четности, если число закодированных единиц не четное - то сбросить бит четности
потом конечно же прибавить в нашу последовательность для передачи значение для передачи полученного бита четности
например, для передачи подготовили следующую последовательность 010101010111 - в ней 7 бит =1, значит бит четности равен 0 а вот если для передачи подготовили 110011001100 - 6 бит=1, значит бит четности равен 1
uwrtey писал(а):
и как связать этот код с режимом CTC - я не догоняю..........
ты об этом пока не думай, делай подсчет бита четности и его добавление в последовательность для передачи (соответственно она у тебя должна увеличиться на 4 байта (2 байта на задание времени импульса+2 байта на задание времени паузы)
В ОЗУ появился новый массив - "transmit_buff" в этом массиве будут хранится длительности массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
оперативки то не хватит что бы записать всю информацию...
_________________ не зная броду не лезь к вольтмоду
В ОЗУ появился новый массив - "transmit_buff" в этом массиве будут хранится длительности массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
оперативки то не хватит что бы записать всю информацию...
угу, не хватит.. потом перепишем на передачу 5 бит каждого байта (по числу кнопок) потом сделаем предделитель для Т1 и перейдем к заданию интервала одним байтом а не двумя
но пока усложнять алгоритм рано.. нужно разобраться в том что есть
количество единиц я смогу подсчитать и куда-нибудь запишу результат (в Temp1, например) но как проверить этот результат на четность? поделить его на 2 и проверить будет ли остаток? (если так - то я не могу допереть как это сделать)
_________________ не зная броду не лезь к вольтмоду
ldi zl,low(transmit_buff) ; зададим в "Z" адрес начала буфера передачи в ОЗУ ldi zh,high(transmit_buff)
ldi yl, low(key_buff) ; зададим в "Y" адрес начала буфера прочитанных кнопок ldi yh, high(key_buff)
ldi R17,5 ; количество байт для передачи
keybuffer_loop:
ld temp,y+ ; прочитаем байт для передачи, увеличим адрес "y" на единицу.
ldi r18,8 ; количество бит в байте для передачи
byte_loop: ; здесь кодируем импульс для бита
ldi r19,high(ImpLen) ; зададим фиксированную длительность импульса st z+,r19 ; запишем данные в ОЗУ по адресу из "Z" ldi r19,low(ImpLen) st z+,r19
ldi xl,low(Nullen) ; длительность для передачи нуля ldi xh,high(Nullen)
ROL temp ; сдвигаем байт влево BRCC send_nullen ; если старши бит = "0" то переходим на метку
ldi xl,low(onelen) ; длительность для передачи единицы ldi xh,high(onelen)
cpi Temp1,1 ; если в прошлый раз была единица, то идем на метку/////////// breq chetnost
inc Temp1 ; увеличение на 1 (нечетное)////////////////////////////////// rjmp send_nullen
chetnost:
dec Temp1 ; уменьшение на 1 (четное)////////////////////////////////////
send_nullen:
st z+,xh ; запишем данные в ОЗУ по адресу из "Z" st z+,xl
dec R18 ; уменьшим счетчик бит на передачу brne byte_loop
dec R17 ; уменьшим счетчик байт для передачи brne keybuffer_loop
;*******************************
если Temp1=0 значит-четное, если Temp1=1 значит-НЕчетное .......... только потом увидел, что ты просишь один бит на всю посылку. ...............домой приду переделаю.
_________________ не зная броду не лезь к вольтмоду
Последний раз редактировалось uwrtey Сб сен 15, 2012 20:22:56, всего редактировалось 2 раз(а).
send_nullen: st z+, xh ; сохраним в буфере на передачу st z+, xl
dec R18 ; уменьшим счетчик бит на передачу brne byte_loop
dec R17 ; уменьшим счетчик байт для передачи brne keybuffer_loop
; ---------- ; ; здесь формируем посылку для бита четности ; ; здесь фактически код для формирования одного бита ; ; здесь кодируем импульс для бита ldi r19,high(ImpLen) ; зададим фиксированную длительность импульса st z+, r19 ldi r19,low(ImpLen) st z+, r19 ; здесь в R21 число единичек ldi xl, low(Nullen) ; длительность для передачи нуля ldi xh, high(Nullen)
ROR R21 ; команда сюрприз! прочитай как работает brcs send_bitchetn ; если С установлен значит нечетное число единиц у нас
ldi xl, low(onelen) ; длительность для передачи единицы ldi xh, high(onelen)
send_bitchetn: st z+, xh ; сохраним в буфере на передачу st z+, xl
вот и весь бит четности
p.s. главное не крылья и не хвост, главное алгоритм !
p.p.s. кстати сможешь из двух кусков передачи бита сделать подпрограмму ? - за это я люблю ассемблер, иногда оптимизацию можно сделать даже для блоков в 3-4 команды
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения