как придумаешь, пиши...теперь бы придумать как его тебе попроще объяснить
Пропорциональное управление на МК (Знание=Сила)
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
не зная броду не лезь к вольтмоду
- Реклама
Re: Пропорциональное управление на МК (Знание=Сила)
смотри что придумал:
нам нужно управлять генерацией импульсов при помощи Т1
в принципе, как уже обсуждали, все управление это заливка нужной длительности в OCR1A - дальше контроллер сделает все сам.
остался вопрос: каким образом определять эти длительности?
я тут накидал один код для прерывания, но боюсь что им запросто отобью у тебя желание писать программы на асме
поэтому пойдем проще:
мы после того как зарегистрировали нажатие любой кнопки на клаве подготовим в ОЗУ еще один буфер который будет содержать в себе длительности фаз передаваемых импульсов
то есть примерно так:
нужно отправить байт 01001001
импульс у нас стандартной длины ImpLen
для нуля мы передаем длину Nullen
для единицы Onelen
(эти константы мы определим через .define в начале программы, чтобы потом если придется править не лазить и не искать где мы их использовали)
в буфере на передачу должно быть (это схематично):
теперь программа, следи за мыслью:
попробуй разобраться что у нас получиться в буфере на передачу и как это получилось.
особенно как работает ROL.
ДОПОЛНИТЕЛЬНО: модифицируй код чтобы генерить бит четности (в нашем случае ситуацию когда в передаваемых байтах общее число бит=1 четное, нам нужен один бит четности на всю посылку)
нам нужно управлять генерацией импульсов при помощи Т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
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
пища для ума, вечером будет над чем помыслить

а не проще будет объединить ImpLen и Onelen - ведь они равны ??? (или тут задумка другая...)
а не проще будет объединить ImpLen и Onelen - ведь они равны ??? (или тут задумка другая...)
не зная броду не лезь к вольтмоду
Re: Пропорциональное управление на МК (Знание=Сила)
угу, думать полезно... может что интереснее придумаешьuwrtey писал(а):пища для ума, вечером будет над чем помыслить![]()
нет, объединять не стоит, мы же не знаем к чему приведут наши эксперименты, вдруг у нас ImpLen потом будет отличаться от Onelen? - придется по коду лазить и менять... хорошо если код в одном файле.. а если нет?uwrtey писал(а):а не проще будет объединить ImpLen и Onelen - ведь они равны ??? (или тут задумка другая...)
так что лучше написать отдельно, тем более это же константы, размер кода не меняется будь одна константа или две
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
я не згаю что такое .define
яндекс говорит что это СИ
яндекс говорит что это СИ
не зная броду не лезь к вольтмоду
- Реклама
Re: Пропорциональное управление на МК (Знание=Сила)
ой.. ну тогда .equuwrtey писал(а):я не згаю что такое .define
яндекс говорит что это СИ
я тут с Verilog разбираюсь
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
прочитал тут про константы, должно получиться следующее
.EQU ImpLen=0xCE4 ; длина импульса
.EQU OneLen=0xCE4 ; длина паузы для единицы
.EQU NulLen=0x19C8 ; длина паузы для нуля
.EQU ImpLen=0xCE4 ; длина импульса
.EQU OneLen=0xCE4 ; длина паузы для единицы
.EQU NulLen=0x19C8 ; длина паузы для нуля
не зная броду не лезь к вольтмоду
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
почитал про ROL http://www.gaw.ru/html.cgi/txt/doc/micr ... sm/rol.htm
лучше будет если поменять предложения местами - вот так "Сдвиг всех битов Rd на одно место влево. Бит "7" смещается во флаг переноса (C).Флаг переноса (С) регистра состояния (SREG) смещается на место бита "0" регистра Rd." А то можно неправильно понять смысл... (что я сначала и сделал)
***
Получается, что команда ROL смещает байт целиком на 1 шаг, зацикливая его
или другими словами старший бит занимает место младшего бита
- пример 01001001
01001001
10010010
00100101
01001010
Теперь не понятно что такое brnc !
(яндекс то же не знает!)
BRCC (Перейти если перенос очищен)??? http://www.gaw.ru/html.cgi/txt/doc/micr ... m/brcc.htm
или BRHC (Перейти если флаг внутреннего переноса очищен) ??? http://www.gaw.ru/html.cgi/txt/doc/micr ... m/brhc.htm

регистр состояния (SREG) http://controllersystems.com/books/prak ... -sreg.htmlСдвиг всех битов 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
BRCC (Перейти если перенос очищен)??? http://www.gaw.ru/html.cgi/txt/doc/micr ... m/brcc.htm
или BRHC (Перейти если флаг внутреннего переноса очищен) ??? http://www.gaw.ru/html.cgi/txt/doc/micr ... m/brhc.htm
не зная броду не лезь к вольтмоду
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
в общих чертах, как работает этот код, я понял.
про бит четности можно поподробней?
и как связать этот код с режимом CTC - я не догоняю..........
Спойлер
Код: Выделить всё
В ОЗУ появился новый массив - "transmit_buff"
в этом массиве будут хранится длительности
массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
и как связать этот код с режимом CTC - я не догоняю..........
не зная броду не лезь к вольтмоду
Re: Пропорциональное управление на МК (Знание=Сила)
бит четности это фактически признак четности, нужно посчитать сколько было закодировано бит равных единице, и потом если это число четное - то установить бит четности, если число закодированных единиц не четное - то сбросить бит четностиuwrtey писал(а): про бит четности можно поподробней?
потом конечно же прибавить в нашу последовательность для передачи значение для передачи полученного бита четности
например, для передачи подготовили следующую последовательность 010101010111 - в ней 7 бит =1, значит бит четности равен 0
а вот если для передачи подготовили 110011001100 - 6 бит=1, значит бит четности равен 1
ты об этом пока не думай, делай подсчет бита четности и его добавление в последовательность для передачи (соответственно она у тебя должна увеличиться на 4 байта (2 байта на задание времени импульса+2 байта на задание времени паузы)uwrtey писал(а):и как связать этот код с режимом CTC - я не догоняю..........
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
оперативки то не хватит что бы записать всю информацию...В ОЗУ появился новый массив - "transmit_buff"
в этом массиве будут хранится длительности
массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
не зная броду не лезь к вольтмоду
Re: Пропорциональное управление на МК (Знание=Сила)
угу, не хватит..uwrtey писал(а):оперативки то не хватит что бы записать всю информацию...В ОЗУ появился новый массив - "transmit_buff"
в этом массиве будут хранится длительности
массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
потом перепишем на передачу 5 бит каждого байта (по числу кнопок)
потом сделаем предделитель для Т1 и перейдем к заданию интервала одним байтом а не двумя
но пока усложнять алгоритм рано.. нужно разобраться в том что есть
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
количество единиц я смогу подсчитать и куда-нибудь запишу результат (в Temp1, например)
но как проверить этот результат на четность? поделить его на 2 и проверить будет ли остаток? (если так - то я не могу допереть как это сделать)
но как проверить этот результат на четность? поделить его на 2 и проверить будет ли остаток? (если так - то я не могу допереть как это сделать)
не зная броду не лезь к вольтмоду
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
... ой .... //редактирую//
не зная броду не лезь к вольтмоду
Re: Пропорциональное управление на МК (Знание=Сила)
проверить на четность проще паренной репы.. достаточно вспомнить
128 64 32 16 8 4 2 1 - последний бит отвечает за четность..
следовательно либо проверка установки бита либо сдвиг вправо через флаг переноса и переход по установленному\сброшенному флагу переноса
128 64 32 16 8 4 2 1 - последний бит отвечает за четность..
следовательно либо проверка установки бита либо сдвиг вправо через флаг переноса и переход по установленному\сброшенному флагу переноса
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
я сначала тупанул и сделал один бит четности на каждый прочитанный байтнам нужен один бит четности на всю посылку)
вот так
Спойлер
Код: Выделить всё
.EQU ImpLen=0xCE4 ; длина импульса
.EQU OneLen=0xCE4 ; длина паузы для единицы
.EQU NulLen=0x19C8 ; длина паузы для нуля
;******************************************************************************************************
Ldi Temp1,0 ; счетчик четности///////////////////////////////////////////
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
;*******************************
..........
только потом увидел, что ты просишь один бит на всю посылку.
...............домой приду переделаю.
Последний раз редактировалось uwrtey Сб сен 15, 2012 20:22:56, всего редактировалось 2 раза.
не зная броду не лезь к вольтмоду
Re: Пропорциональное управление на МК (Знание=Сила)
как то ты мудрено подошел к решению задачки
первая часть кода отличается всего 2мя строчками !! (с регистром R21) - и мы уже считаем биты=1 при передаче !
добавленные команды в первой части я выделил в коде (относительно первоначального)
вот и весь бит четности
p.s. главное не крылья и не хвост, главное алгоритм !
p.p.s. кстати сможешь из двух кусков передачи бита сделать подпрограмму ? - за это я люблю ассемблер, иногда оптимизацию можно сделать даже для блоков в 3-4 команды
первая часть кода отличается всего 2мя строчками !! (с регистром R21) - и мы уже считаем биты=1 при передаче !
добавленные команды в первой части я выделил в коде (относительно первоначального)
Спойлер
Код: Выделить всё
ldi R21, 0 ; это будет счетчик единичек в передаче @@@ ДОБАВЛЕНО @@@
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 ; команда сюрприз! прочитай как работает
brcc send_nullen ; если С=0 то записываем нулевую длительность
ldi xl, low(onelen) ; длительность для передачи единицы
ldi xh, high(onelen)
inc R21 ; передаем единицу - увеличим счетчик @@@ ДОБАВЛЕНО @@@
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 команды
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
а вот что у меня получилось
Спойлер
Код: Выделить всё
.EQU ImpLen=0xCE4 ; длина импульса
.EQU OneLen=0xCE4 ; длина паузы для единицы
.EQU NulLen=0x19C8 ; длина паузы для нуля
;******************************************************************************************************
Ldi Temp1,0 ; счетчик четности///////////////////////////////////////////
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
;*******************************
ldi r19,high(ImpLen) ; зададим фиксированную длительность импульса
st z+, r19
ldi r19,low(ImpLen)
st z+, r19
ldi xl, low(Nullen) ; длительность для передачи нуля (нечетное)
ldi xh, high(Nullen)
cpi Temp1,1 ; проверка на нечетность
breq send_bitchetn ; "0"=четное, "1"=нечетное
ldi xl, low(onelen) ; длительность для передачи единицы (четное)
ldi xh, high(onelen)
send_bitchetn:
st z+, xh ; сохраним в буфере на передачу
st z+, xl
не зная броду не лезь к вольтмоду
- uwrtey
- Поставщик валерьянки для Кота
- Сообщения: 2309
- Зарегистрирован: Пт июл 17, 2009 07:34:07
- Откуда: Свердловская обл.
Re: Пропорциональное управление на МК (Знание=Сила)
ROR это тот же ROL, только в другую сторону...Код: Выделить всё
ROR R21 ; команда сюрприз! прочитай как работает brcs send_bitchetn ; если С установлен значит нечетное число единиц у нас
что то я Тебя не понял... каких двух кусков ?ВитГо писал(а):кстати сможешь из двух кусков передачи бита сделать подпрограмму
не зная броду не лезь к вольтмоду
Re: Пропорциональное управление на МК (Знание=Сила)
Посмотри внимательно программу которую я привел во второй раз..uwrtey писал(а):что то я Тебя не понял... каких двух кусков ?ВитГо писал(а):кстати сможешь из двух кусков передачи бита сделать подпрограмму
разве там не повторяющегося кода ?
и разве руки не чешутся засунуть код в подпрограмму и сделать его вызов через RCALL ?


