Котуинко

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

ИГРЫ С ВЕКТОРАМИ
(по мотивам https://radiokot.ru/forum/viewtopic.php ... 9#p4561359)
Весьма обычный прием...
Допустим есть в начальном месте размеченное изготовителем поле для команд переходов...
тут вектор сброса на своем месте по умолчанию:
Код:
;
; "irq_pavr.txt" файл описания поля векторов прерываний
;
.cseg
.org 0x000
irq_res:
rjmp init ; переход к началу программы инициализации системы
; - - - - - - - - - - - - - - - - - - - - - - - - - - -
; блок размещения векторов активных прерываний
; .org OC0Aaddr
; irq_t0:
; rjmp timers_bum ; steps
; - - - - - - - - - - - - - - - - - - - - - - - - - - -


Теперь где-то в удобном месте ставим второй вектор сброса. Полнейшая "творческая отсебятина" в вопросе где те вектора ставить. Допустим так:
Код:
.cseg
.org 0x200
init:
rjmp real_init

а далее собственно у нас или тот real_init будет выполняться или в той же ячейке расположенная новая команда перехода на иную точку входа в программу (перепрошитая "обманщиком" при помощи SPM (или еще попакостнее с использованием возможностей IJMPов :facepalm: :o ))...
Даже если исходная таблица закрыта для перезаписи локами, то "самодельная вторичная" может располагаться как нам нравится (где удобнее).
Собственно при прерывании (аппаратном сбросе) у нас срабатывает тандем из двух команд :
первый переход по команде, размещенной в классической ячейке таблицы векторов
rjmp init
и затем уже второй - на нужную в данный момент программу (из нашей "полной отсебятинки"):
rjmp real_init
или
IJMP ; по адресу, находящемуся в Z
хотя... никто не запрещал ставить IJMP и в "стандартную" таблицу векторов... УПС... это я точно прозевал... (В MCS51 такой приятненькой команды к сожалению нету) :oops:
Я брал пример на скору руку с шаблона асма тинек - но там в принципе любые команды переходов вместо rjmp name сгодятся.
Что JMP по фиксированному адресу, что еще поизворотливее (у АВРок) IJMP по содержимому Z регистра.
Понятно что это потеря быстродействия - лишняя команда - зато возможности достаточно заморочливые.
Второе - сама SPM не знает где чего лежит - но автор такого приема прекрасно знает разметку памяти своего творения посему параметры то уж задаст и для бутлоадера (при начальной прошивке) и для прикладной программы.
8)
Реклама
Аватара пользователя
Starichok51
Модератор
Сообщения: 19046
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Котуинко

Сообщение Starichok51 »

я говорил о совсем другом.
меня интересуют не те переходы, как

.org 0x200
init:
rjmp real_init

а интересует, чтобы прерывание, например, по таймеру

.org OC0Aaddr
rjmp irq_t0

работало в области загрузчика.
а конкретно я говорил про приемо-передатчик, и соответственно, мне нужно, чтобы работал такой код

.org URXCaddr ; адрес прерывания USART, Rx Complete
rjmp USART_Rx_Complete ; прием готов
nop
rjmp USART_Tx_Complete ; передача готова

в области загрузчика.
и как я уже там сказал, по установленному биту IVSEL у меня не происходит перенос таблицы векторов в загрузочную область, а продолжает работать таблица на своем прежнем месте, начиная с нулевого адрема.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

А что мешает сделать простой переход в область адресов загрузчика из "стандартной"?
Привязка к аппаратной поддержке совсем не обязательна.
Просто делаем свой раздел в защищенной области к которому обращаются команды указателей адреса перехода из основного раздела " по умолчанию"...
Исходная таблица "по умолчанию" будет обслуживать переходы на вновь созданную, но не средствами аппаратной поддержки, а средствами программной поддержки автором программы.
Мы же вторичные (целевые) указатели можем размещать где угодно. Другое дело, что при написании целевой программы нужно учитывать параметры разметки бутлоадера - знать адреса размещения векторов по листингу бутлоадера и задавать их затем вручную при написании целевой программы.
Но это уже стандартная специфика для комплекта базового бутлоадера с набором минимальных общих функций и целевой программы, которая может как пользоваться подпрограммами бутлоадера (прием/передача, типовые преобразования и т.п.) так и своими аналогами таких же подпрограмм.
Это привычнее с оперативно подгружаемыми программами на самоделке с единой общей базой. Меняем модуль аппаратного расширения и загружаем соответствующую этому аппаратному модулю прикладную часть программы. А в самой "мамке" сидит только базовый загрузчик и утилиты управления аппаратным ядром устройства.
Некоторая аналогия ПК - сначала запускается биос аппаратной части, затем программа пользователя, которая также использует и ресурсы биос и ресурсы собственные, которые можно модифицировать при необходимости.
Отличие только в режиме модификации ячеек памяти программ - для ОЗУ мгновенная запись, по флеш ПЗУ требуется некоторое время и спецпроцедуры для перезаписи.
8)
По конкретике...
Допустим я взял мегу8а...
Оставил исходную таблицу векторов на своем месте...
А прикладные вектора хочу разместить в области бутлоадера (на всякий случай беру бутлоадер максимального размера)...
Т.е. у меня область бутлоадера от 0хС00 и далее...
ставлю вот такой добавок в дефайне (m8adef.inc):
Спойлер

Код: Выделить всё

; ***** my INTERRUPT VECTORS ************************************************

; причем софтовая таблица может иметь и другие адреса начального размещения внутри области бутлоадера
; а не только самые первые (от FOURTHBOOTSTART)

.equ	INT0addr_r = FOURTHBOOTSTART + 0x0001	; External Interrupt Request 0
.equ	INT1addr_r = FOURTHBOOTSTART + 0x0002	; External Interrupt Request 1
.equ	OC2addr_r	= FOURTHBOOTSTART + 0x0003	; Timer/Counter2 Compare Match
.equ	OVF2addr_r = FOURTHBOOTSTART + 0x0004	; Timer/Counter2 Overflow
.equ	ICP1addr_r = FOURTHBOOTSTART + 0x0005	; Timer/Counter1 Capture Event
.equ	OC1Aaddr_r = FOURTHBOOTSTART + 0x0006	; Timer/Counter1 Compare Match A
.equ	OC1Baddr_r = FOURTHBOOTSTART + 0x0007	; Timer/Counter1 Compare Match B
.equ	OVF1addr_r = FOURTHBOOTSTART + 0x0008	; Timer/Counter1 Overflow
.equ	OVF0addr_r = FOURTHBOOTSTART + 0x0009	; Timer/Counter0 Overflow
.equ	SPIaddr_r	= FOURTHBOOTSTART + 0x000a	; Serial Transfer Complete
.equ	URXCaddr_r = FOURTHBOOTSTART + 0x000b	; USART, Rx Complete
.equ	UDREaddr_r = FOURTHBOOTSTART + 0x000c	; USART Data Register Empty
.equ	UTXCaddr_r = FOURTHBOOTSTART + 0x000d	; USART, Tx Complete
.equ	ADCCaddr_r = FOURTHBOOTSTART + 0x000e	; ADC Conversion Complete
.equ	ERDYaddr_r = FOURTHBOOTSTART + 0x000f	; EEPROM Ready
.equ	ACIaddr_r	= FOURTHBOOTSTART + 0x0010	; Analog Comparator
.equ	TWIaddr_r	= FOURTHBOOTSTART + 0x0011	; 2-wire Serial Interface
.equ	SPMRaddr_r = FOURTHBOOTSTART + 0x0012	; Store Program Memory Ready

; .equ	INT_VECTORS_SIZE	= 19	; size in words
А в своей программе ставлю сначала

Код: Выделить всё

   .org 0x0000
 INT0addr: jmp INT0addr_r	; External Interrupt Request 0
 INT1addr: jmp INT1addr_r	; External Interrupt Request 1
 OC2addr:	jmp OC2addr_r	; Timer/Counter2 Compare Match
 OVF2addr: jmp OVF2addr_r	; Timer/Counter2 Overflow
 ICP1addr: jmp ICP1addr_r	; Timer/Counter1 Capture Event
 OC1Aaddr: jmp OC1Aaddr_r	; Timer/Counter1 Compare Match A
 OC1Baddr: jmp OC1Baddr_r	; Timer/Counter1 Compare Match B
 OVF1addr: jmp OVF1addr_r	; Timer/Counter1 Overflow
 OVF0addr: jmp OVF0addr_r	; Timer/Counter0 Overflow
 SPIaddr:	jmp SPIaddr_r	; Serial Transfer Complete
 URXCaddr: jmp URXCaddr_r	; USART, Rx Complete
 UDREaddr: jmp UDREaddr_r	; USART Data Register Empty
 UTXCaddr: jmp UTXCaddr_r	; USART, Tx Complete
 ADCCaddr: jmp ADCCaddr_r	; ADC Conversion Complete
 ERDYaddr: jmp ERDYaddr_r	; EEPROM Ready
 ACIaddr: jmp ACIaddr_r	; Analog Comparator
 TWIaddr: jmp TWIaddr_r	; 2-wire Serial Interface
 SPMRaddr: jmp SPMRaddr_r	; Store Program Memory Ready

; далее текст программы при необходимости
...............
; теперь область бутлоадера:

  .org FOURTHBOOTSTART ; или иная область внутри области ПЗУ бутлоадера - это софт, а не аппаратная разметка***
INT0addr_r: jmp my_INT0	; External Interrupt Request 0
INT1addr_r: jmp my_INT1	; External Interrupt Request 1
OC2addr_r: jmp my_OC2	; Timer/Counter2 Compare Match
OVF2addr_r: jmp my_OVF2	; Timer/Counter2 Overflow
ICP1addr_r: jmp my_ICP1	; Timer/Counter1 Capture Event
OC1Aaddr_r: jmp my_OC1A	; Timer/Counter1 Compare Match A
OC1Baddr_r: jmp my_OC1B	; Timer/Counter1 Compare Match B
OVF1addr_r: jmp my_OVF1	; Timer/Counter1 Overflow
OVF0addr_r: jmp my_OVF0	; Timer/Counter0 Overflow
SPIaddr_r: jmp my_SPI	; Serial Transfer Complete
URXCaddr_r: jmp my_URXC	; USART, Rx Complete
UDREaddr_r: jmp my_UDRE	; USART Data Register Empty
UTXCaddr_r: jmp my_UTXC	; USART, Tx Complete
ADCCaddr_r: jmp my_ADCC	;	; ADC Conversion Complete
ERDYaddr_r: jmp my_ERDY	;	; EEPROM Ready
ACIaddr_r: jmp my_ACI	; Analog Comparator
TWIaddr_r: jmp my_TWI	; 2-wire Serial Interface
SPMRaddr_r: jmp my_SPMR	; Store Program Memory Ready

; далее сам бутлоадер с соответствующими подпрограммами:
...................


my_INT0: reti	; External Interrupt Request 0
my_INT1: reti	; External Interrupt Request 1
my_OC2: reti	; Timer/Counter2 Compare Match
my_OVF2: reti	; Timer/Counter2 Overflow
my_ICP1: reti	; Timer/Counter1 Capture Event
my_OC1A: reti	; Timer/Counter1 Compare Match A
my_OC1B: reti	; Timer/Counter1 Compare Match B
my_OVF1: reti	; Timer/Counter1 Overflow
my_OVF0: reti	; Timer/Counter0 Overflow
my_SPI: reti	; Serial Transfer Complete
my_URXC: reti	; USART, Rx Complete
my_UDRE: reti	; USART Data Register Empty
my_UTXC: reti	; USART, Tx Complete
my_ADCC: reti	;	; ADC Conversion Complete
my_ERDY: reti	;	; EEPROM Ready
my_ACI: reti	; Analog Comparator
my_TWI: reti	; 2-wire Serial Interface
my_SPMR: reti	; Store Program Memory Ready
В принципе... если у меня есть несколько вариантов на один вектор
обработки и несколько подпрограмм требующих быстрого переключения...
Тогда где-нибудь храню адреса тех подпрограмм а по точке вектора
ставлю:

Код: Выделить всё

URXCaddr_r: ijmp	; USART, Rx Complete
UDREaddr_r: ijmp	; USART Data Register Empty
UTXCaddr_r: ijmp	; USART, Tx Complete
при этом надо позаботиться о предварительной загрузке прикладных адресов
в Z регистр, что обеспечит возможность запуска нескольких вариантов
подпрограмм для каждого из прерываний.

для аппаратной поддержки возможны и "обратные" варианты - когда основная
таблица в бутлоадере, а "софтовая" в любом месте прикладной программы.
:tea:
Аватара пользователя
Starichok51
Модератор
Сообщения: 19046
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Котуинко

Сообщение Starichok51 »

а мне нужен, как раз, аппаратный перенос таблицы векторов.
ну вот смотри.
записываем в МК бутлоадер. вся остальная память, начиная с нулевого адреса, до бутлоадера чистая.
а мне нужно, чтобы работали прерывания, когда с нулевого адреса таблица не заполнена.
к примеру, я пишу:

.org SECONDBOOTSTART
rjmp nachalo

.org URXCaddr + SECONDBOOTSTART ; адрес прерывания USART, Rx Complete
rjmp USART_Rx_Complete ; прием готов
nop
rjmp USART_Tx_Complete ; передача готова

nachalo:
ldi R26, 1<<IVCE
out GICR, R26
ldi R26, 1<<IVSEL
out GICR, R26

таким образом, я прописываю нужные вектора со смещением на начало и делаю перенос таблицы в область бутлоадера.
ранее, когда я это пробовал сделать, видимо, я допустил какую-то ошибку и у меня не происходил перенос таблицы векторов.
вчера вечером сделал тестовый текст, и тоже допустил, видимо, эту же ошибку, и у меня перенос не работал.
а сейчас с утра нашел ошибку и исправил. и теперь у меня прекрасно работают прием и передача по новым векторам в области загрузчика.
проверил - связь с компом теперь работает замечательно.
правда, мне уже это не надо, так как я уже в загрузчике обошелся без прерываний и сделал программный анализ флага RXC на приеме и анализ флага UDRE при передаче.
получилось, что я сам был виноват и зря тебя напрягал с вопросами. но все равно спасибо за потраченное на меня время.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
Эиком - электронные компоненты и радиодетали
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Котуинко

Сообщение akl »

А почему не как обычно?

Код: Выделить всё

nachalo:
	ldi R26, 1<<IVCE
	out GICR, R26

	SBR	R26,1<<IVSEL
;  ldi R26, 1<<IVSEL
	out GICR, R26
Реклама
Аватара пользователя
Starichok51
Модератор
Сообщения: 19046
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Котуинко

Сообщение Starichok51 »

а потому, что в даташите сказано, что при записи IVSEL нужно установить IVCE в ноль.
и даже там есть такой пример.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

К сожалению я на АВРках с бутом и самопрограммированием пока не практиковался...
Посему еще один нюанс упустил...

Касается он бит BLB02:01 и BLB12:11...
Судя по документации той же меги8А с их помощью проводится защита от исполнения подпрограмм обслуживания прерываний, расположенных в "чужой" относительно основной таблицы прерываний области.
Таблица векторов в области памяти целевой программы.
Защита от доступа к целевой программе со стороны подпрограмм обработчиков прерываний, расположенных в области бутлоадера выполняют BLB12:11
Если защита включена, то адрес перехода, размещенный в таблице векторов которая находится в области адресов целевой программы, и указывающий на область бутлоадера будет игнорироваться т. е. подпрограмма - обработчик, размещенная в области бутлоадера и рассчитанная на исполнение как часть вызова из целевой программы не запустится.

Аналогично действуют и биты BLB02:01 — только по отношению бутлоадера.
Если основная таблица в области бутлоадера и в ней адресован обработчик из области целевой программы то такой обработчик будет блокирован.

Однако... предполагаю что...
Аппаратные средства отслеживают только адрес в основной таблице векторов... и то при его явном указании в команде (требует проверки вариант с IJMP вместо JMP addr).

Теоретически если в той же области, где расположена основная таблица сделать дополнительную таблицу-обманку и уже из нее вызывать «чужеродный» обработчик вполне вероятен вариант исполнения. "Подставной вектор" то уже будет "в своей" для защит области...
Однако это предположение надо практическим тестом проверить...
Пока в планах у меня такая проверка не стоит, но интересненько...
:roll:
Аватара пользователя
Starichok51
Модератор
Сообщения: 19046
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Котуинко

Сообщение Starichok51 »

я про все локи уже давно прочитал в даташите.
все твои дополнительные таблицы не являются аппаратными. все равно переходы на обработчики прерываний будут делаться из основной аппаратной таблицы.
я вот что подумал, что при переходе из загрузчика в приложение сначала перемещенную таблицу нужно вернуть на свое место с нулевого адреса, а уж потом сделать переход на нулевой адрес.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Вопрос как опознается блокировка.
Т. Е. Какой базовый принцип.
Ведь запрета на обращение к простым подпрограммами из "чужой области" блокировка не ставит.
Иначе были бы блокированы и подпрограммы с вызывающим CALL/JMP ADR а в даташитах про то ни слова.
Посему запрет блокировки касается только фиксированных ячеек области векторов прерываний.
В других ячейках контроль адреса не проводится.
Предположим, что при установленной защите в ячейке с вектором стоит адрес передачи управления в свою же область адресного пространства. Для системы защиты это разрешенный переход (и начало обработки прерывания)... А уже там стоит вторая переадресация "в запретную зону". Вот такой вариант в принципе вполне возможен.
Проверку и без бутлоадера можно попробовать сделать... Чисто из " спортивна интересу"...
:roll:
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Прикупил жирну адуринку...
mega2560 pro... Вроде бы и неплохая базовая платка -относительно малогабаритная...
Только вот пригляделся -
а на всего этого монстра с количеством под 70 линий
ВСЕГО ТРИ КОНТАКТА "ОБЩИЙ"(GND)!!!
https://img.radiokot.ru/files/20529/3eugnlk41u.jpg
Как-то уж совсем неудобственно, особо при заявленном выходном токе стабилизаторов до 800мА...
Для сигналов и силовых обратный проводок один (максимум два) на всю платку...
ПЕЧАЛЬКА однако...
:(
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Котуинко

Сообщение ARV »

а сигналы, тем более, силовые и должны в одну точку сходиться, так что все нормально.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Так не факт, что на платке общий слой...
Силовые и сигнальные что от источника питания, что от нагрузок/источников сигнала и все в один контакть...
хотя бы еще парочку поставили... Силовые то можно и через "общий +" затянуть. Мне больше интерес был для подключения параллельного ОЗУ (23я серия похоже таки из области фантастики по местным условиям).
Ну да и на том... сойдет... Все равно пока "на отлежку" в кащеев сундук.
:sleep:
Аватара пользователя
главный колбасист
Это не хвост, это антенна
Сообщения: 1325
Зарегистрирован: Чт авг 21, 2014 11:11:48
Откуда: краснодарский край
Контактная информация:

Re: Котуинко

Сообщение главный колбасист »

А вот посмотрите,какая шняга интересная.
https://forum.cxem.net/index.php?/topic ... nt=3938993
Можно же перенести прошивку (дизассемблировать,т.к исходника не дал) на другой МК ?
например мега8 ? их у меня полно,а тини44 нет.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

При наличии документации на те RW1990 можно под любой МК программу сделать...
Да и в сети полно всяких самоделок на разных АВРкахи адуринах...
:roll:
Кстати... Для программирования далласов можно использовать аппаратную начинку DS2480...
"...
Supports 12V EPROM Programming and
Stiff 5V Pullup for Crypto iButton, Sensors
and EEPROM
..."
DS2480b_new.pdf
(409.69 КБ) 55 скачиваний
8)
Последний раз редактировалось BOB51 Вс апр 07, 2024 08:52:00, всего редактировалось 1 раз.
Аватара пользователя
electroget
Друг Кота
Сообщения: 4651
Зарегистрирован: Ср сен 30, 2020 16:51:47
Откуда: РФ

Re: Котуинко

Сообщение electroget »

Доброго времени суток.

Накропал вот такой код для Ардуины:

#include <EEPROM.h>

int address = 0; // Переменная для хранения адреса
byte value1 = B00001111; // Переменная для хранения значения 1
byte value2 = B10101010; // Переменная для хранения значения 2

void setup() {
Serial.begin(115200);

EEPROM.put(address, value1); // Записать значение value1 в ячейку с адресом 0

address += 1; // Корректируем адрес

EEPROM.put(address, value2); // Записать значение value2 в ячейку с адресом 1

// Обнуляем переменные
address = 0;
byte value1 = 0;
byte value2 = 0;

// Получаем данные из EEPROM
EEPROM.get(address, value1);
address += 1; // Корректируем адрес
EEPROM.get(address, value2);
Serial.println( value1, BIN); // Вывести полученное значение 1
Serial.println( value2, BIN); // Вывести полученное значение 2
}
void loop() {}

В результате выполнения кода:
Монитор СОМ порта выдаёт:

07:40:53.677 -> 1111
07:40:53.677 -> 10101010

Почему вместо положенного байта 00001111 монитор показывает 1111?
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15553
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Так что положили, то и получили.
Значения переменных как были так и остались
Относительно "пропавших лидирующих нулей" - это особенности вывода на печать (функции обработчика перекодировки опции BIN, HEX в print) - аналогия гашения старших незначащих нулей на разнообразных индикаторах.
Для контроля можете выставить HEX - хотя и там "лидирующий нуль" может не воспроизводиться если формат отличается от 0xNN.
8)
Аватара пользователя
electroget
Друг Кота
Сообщения: 4651
Зарегистрирован: Ср сен 30, 2020 16:51:47
Откуда: РФ

Re: Котуинко

Сообщение electroget »

[uquote="BOB51",url="/forum/viewtopic.php?p=4565027#p4565027"]Относительно "пропавших лидирующих нулей" - это особенности вывода на печать[/uquote]
Так это что, это он всегда будет и справа и слева в байте нули обрезать как ему вздумается?
Но тогда ещё вопрос. Реальный код будет чтение из массива и запись байт в порты (У Ардуины 2560 можно байты сразу целиком в порты выводить) Я собираюсь потом этот прочитанный байт 00001111 в порт выводить, он мне его в порт как выведет? Где окажется младший бит если нулей нет?
veso74
Поставщик валерьянки для Кота
Сообщения: 1906
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Котуинко

Сообщение veso74 »

Нет проблем, он отправится туда, где ему место по весу битов.
Аватара пользователя
electroget
Друг Кота
Сообщения: 4651
Зарегистрирован: Ср сен 30, 2020 16:51:47
Откуда: РФ

Re: Котуинко

Сообщение electroget »

Вот код при чтении байт из массива:

#include <avr/io.h>
#include <EEPROM.h>

byte EEMEM dataArray_addr[16];
void setup() {
Serial.begin(115200);

// объявляем массив
byte dataArray[16] = {B00000001, B00000010, B00000100, B00001000,
B00010000, B00100000, B01000000, B10000000,
B01111111, B10111111, B11011111, B11101111,
B11110111, B11111011, B11111101, B11111110};
//
EEPROM.put((byte)&dataArray_addr, dataArray);
// объявляем откуда будем читать
byte dataArray_read[16];
// читаем точно так же, как писали
EEPROM.get((byte)&dataArray_addr, dataArray_read);
EEPROM[0] += 1;
// проверяем данные
Serial.println(dataArray_read[0], BIN);
Serial.println(dataArray_read[1], BIN);
Serial.println(dataArray_read[2], BIN);
Serial.println(dataArray_read[3], BIN);
Serial.println(dataArray_read[4], BIN);
Serial.println(dataArray_read[5], BIN);
Serial.println(dataArray_read[6], BIN);
Serial.println(dataArray_read[7], BIN);
Serial.println(dataArray_read[8]), BIN;
Serial.println(dataArray_read[9]), BIN;
Serial.println(dataArray_read[10], BIN);
Serial.println(dataArray_read[11], BIN);
Serial.println(dataArray_read[12], BIN);
Serial.println(dataArray_read[13], BIN);
Serial.println(dataArray_read[14], BIN);
Serial.println(dataArray_read[15], BIN);
}
void loop() {}

Здесь монитор СОМ порта показывает дичь вообще полную:

09:04:58.892 -> 1
09:04:58.892 -> 10
09:04:58.892 -> 100
09:04:58.892 -> 1000
09:04:58.892 -> 10000
09:04:58.892 -> 100000
09:04:58.892 -> 1000000
09:04:58.892 -> 10000000
09:04:58.892 -> 127
09:04:58.892 -> 191
09:04:58.892 -> 11011111
09:04:58.892 -> 11101111
09:04:58.892 -> 11110111
09:04:58.892 -> 11111011
09:04:58.892 -> 11111101
09:04:58.892 -> 11111110

Откуда взялись значения 127 и 191?
Я ни разу не программист, но дело и не в программировании вовсе, я просто не понимаю как он всё это интерпретирует при выводе данных.
veso74
Поставщик валерьянки для Кота
Сообщения: 1906
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Котуинко

Сообщение veso74 »

При печать старшие биты, равные 0, не отображаются.
СпойлерМожете организовать собственный "правильной" печать. Код немного длинный, но все для теста.
Напр.:

Код: Выделить всё

  value1 = EEPROM.get(address, value1);

  Serial.print("0b");
  
  if (value1 < 128)
    Serial.print('0');
    
  if (value1 < 64)
    Serial.print('0');
    
  if (value1 < 32)
    Serial.print('0');
    
  if (value1 < 16)
    Serial.print('0');
    
  if (value1 < 8)
    Serial.print('0');
    
  if (value1 < 4)
    Serial.print('0');
    
  if (value1 < 2)
    Serial.print('0');
    
  if (value1 < 1)
    Serial.print('0');

  Serial.println(value1, BIN);
---
[uquote="electroget",url="/forum/viewtopic.php?p=4565045#p4565045"]...
Откуда взялись значения 127 и 191?[/uquote]
Перепутали две строки выше. Поместите BIN в скобки.
Последний раз редактировалось veso74 Вс апр 07, 2024 09:15:26, всего редактировалось 2 раза.
Ответить

Вернуться в «Разные вопросы по МК»