_________________ Когда уже ничего не помогает - прочтите, наконец, инструкцию. Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII) Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Не, компилятор не принимает операторы типа "&=" и подобные, но по отдельности запросто. Я так понял что "~3" это тупо выравнивание на 4 байта; и фишка не в точке с запятой(просто я руками набирал по памяти ) ;
Все, до меня само доперло. Отвечаю себе надо сбросить 3 младших бита, тем самым получим выравнивание адреса на 32 бита. получается: addr = ((addr ~3 )& addr).
Я так понял что "~3" это тупо выравнивание на 4 байта; ..... надо сбросить 3 младших бита, тем самым получим выравнивание адреса на 32 бита.
почему 3 бита? причем здесь выравнивание? "~3" - это константа равная 0xFFFFFFFC (с учетом приведения к типу int для ARM7 переменной addr) при выполнении операции
и какой же результат у этого выражения? может все таки вот так?
Код:
addr =(~3)&addr;
Ага именно так в итоге и сделал.
ibiza11 писал(а):
почему 3 бита? причем здесь выравнивание?
Очепятался. Просто запутался три два два три, и в итоге в голове получилась каша.
Cheba писал(а):
Всё правильно, это выравнивание на границу 32-битного слова. Некоторые операции требуют такого выравнивания.
Операция чтения\записи памяти. Т.е addr по любому будет кратен 4-ём. Вообще это какая-то заказная ПЛИСка которая опрашивает другие 32шт ПЛИС. У этих других ПЛИСок по мегабайту RAM и ROM, в общем 32-ух битном адресном пространстве, и все "общение" друг с другом происходит через RAM. Сколково блин
1. В младшем байте переменной trisa 4 старших бита остаются неизменными, 4 младших бита сбрасываются в 0. Если разрядность trisa > 8, старшие биты обнуляются.
2. В младшем байте переменной porta 4 старших бита остаются неизменными, 4 младших бита копируют инвертированные 4 младших бита FCV_SHOW_DIGIT. Если разрядность porta > 8, старшие биты обнуляются.
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
это правильно с точки зрения программы, а с точки зрения действий Мк это значит 1. устанавливаем младшие четыре бита порта А на выход, старшие на вход.(если разрядность больше 8 остальные тоже на выход.) 2. выводим в младшие 4 разряда порта А нужную информацию.Старшие оставляем нетронутыми.(если больше 8 то остальные стбрасываем в 0)
Спасибо всем кто ответил.И еще маленький вопрос , если позволите. DDRD = DDRD | 0x30; PORTD = (PORTD & 0xCF) | (255); Этим кодом управляю катодом семисегментника напрямую с порта , а мне необходимо его инвертировать , т.е. в порт посылать не "0" а "1" .Что необходимо изменить? Извините за тупые вопросы , самому стыдно.Может посоветуете книжечку почитать по "СИ" для микроконтроллеров (читаю книгу Керниган.Ричи.Но не то пальто ,ориентируется для другого , учится на ней трудновато)
В этой строке переменной PORTDвсегда будет присваиваться значение 255 (двоичное 11111111) независимо от того, каким было прежнее значение переменной и с какой константой перед этим выполнялась операция "побитовое И". Результат операции "ИЛИ", когда один из операндов равен 1, всегда 1, независимо от значения второго операнда. Вряд ли это именно то, что Вам нужно в данном случае.
Поэтому на вопрос
igorka писал(а):
Этим кодом управляю катодом семисегментника напрямую с порта , а мне необходимо его инвертировать , т.е. в порт посылать не "0" а "1" .Что необходимо изменить?
ответ: всё. Опишите словами, что именно нужно сделать, и я покажу, как это сделать.
Если я вдруг угадал и Вы намеревались вывести инвертированную константу 0xCF в порт, то это делается так:
Код:
PORTD = ~ 0xCF;
Если не угадал, тогда напишите подробнее, что имелось в виду.
igorka писал(а):
Может посоветуете книжечку почитать по "СИ" для микроконтроллеров (читаю книгу Керниган.Ричи.Но не то пальто ,ориентируется для другого , учится на ней трудновато)
Именно эти вопросы очень хорошо описаны у Кернигана-Ритчи (хоть книга и не ориентирована на специфику микроконтроллеров, но в данном случае этой специфики нет, обычная побитовая логика). Может, есть буквари и попроще, но первоисточник все равно предпочтительнее.
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
Приветствую, господа. Начал ковыряться в AVR и ихнем С, появились глупые вопросы. Ниже код, выдающий 0 на случайные выхода со случайной задержкой на МК attiny13a. Спойлер
значение переменной в двоичном виде будет 31 ноль и единица в младшем разряде. Значением этого
Код:
lfsr >> 1
будет 32 нуля в двоичном виде. Это
Код:
lfsr & 1u
приводится к виду (31 ноль и единица в младшем разряде) & (31 ноль и единица в младшем разряде), а результатом будет те же 31 ноль и единица в младшем разряде. Дальше делается это
Код:
-(lfsr & 1u)
, т.е. беззнаковое 32-х битное число меняет знак. При этом просто инвертируется старший бит, а тип полученного числа остается unsigned long? 2. Что является аргументом для _delay_loop_2()? Это задержка в каких то долях от тактовой частоты?
Сори за побитовое разжевывание и общий уровень вопросов, только начал вникать, хочу знать правильно ли понимаю логику работы этого дела.
_________________ We do what we must because we can (c) GLaDOS
Не все так просто (уже сама фраза "беззнаковое число меняет знак" должна насторожить).
Знаковое 32-битное число имеет диапазон значений от -2^31 до (2^31) - 1. Беззнаковое 32-битное число имеет диапазон значений от 0 до (2^32) - 1. Очевидно, что значения >= 2^31 не могут быть представлены знаковым 32-битным числом, поэтому при попытке такой смены знака компилятор должен выдать как минимум предупреждение.
baron_P писал(а):
При этом просто инвертируется старший бит, а тип полученного числа остается unsigned long?
Зависит от реализации. Например, стандарт ISO/IEC 9899:1999 в п. 6.2.6.2 Integer types предлагает следующие варианты представления отрицательных величин:
Цитата:
2. For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; there shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M <= N). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the following ways: — the corresponding value with sign bit 0 is negated (sign and magnitude); — the sign bit has the value -(2N) (two’s complement); — the sign bit has the value -(2N - 1) (one’s complement). Which of these applies is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), or with sign bit and all value bits 1 (for one’s complement), is a trap representation or a normal value. In the case of sign and magnitude and one’s complement, if this representation is a normal value it is called a negative zero.
В данном случае сам кристалл (и соответственно "ихний C" (C), предположительно WinAVR) поддерживает "дополнение до двух", но лучше все-таки не закладываться на особенности реализации вроде поразрядного представления чисел и/или endianness. Для этой задачи найдется способ решения гораздо корректнее, если сформулирете, что именно хотели получить (инверсию старшего бита?).
baron_P писал(а):
2. Что является аргументом для _delay_loop_2()? Это задержка в каких то долях от тактовой частоты?
А это уже называется лень-матушка:
Цитата:
22.28.2.2 void _delay_loop_2 (uint16_t __count) Delay loop using a 16-bit counter __count, so up to 65536 iterations are possible. (The value 65536 would have to be passed as 0.) The loop executes four CPU cycles per iteration, not including the overhead the compiler requires to setup the counter register pair.
Thus, at a CPU speed of 1 MHz, delays of up to about 262.1 milliseconds can be achieved.
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
Спасибо. 1. Тут задача обратная. Я не хочу что-то получить с помощью этой программы, хочу понять как оно работает. Так что инвертирующее действие этого выражения в программе - мое предположение. Вообще, там реализован генератор псевдослучайных чисел со сдвиговым регистром и несколькими отводами, но как конкретно он работает уж хз. Попробую заменить на другой способ инверсии. Если будет работать, значить автор то и имел в виду. Радует, что такое выражение нестандартно для С - попытка поменять знак беззнаковому числу мне логичной не казалась сразу) 2. Это описание я читал, но надеялся на что-то более равернутое. Я это понял так. В аргументе стоит число, обозначающее количество итераций 16ти битного счетчика (при значении 0 - максимальная задержка, при 65536 минимальная, т.е. ее нет). При 1 МГц цпу и 65536 итерациях, задержка будет 262,1 мс. Смущают какие-то не слишком привязанные к двоичным порядкам числа (кроме 65536), потому и хотел уточнить.
_________________ We do what we must because we can (c) GLaDOS
При 1 МГц цпу и 65536 итерациях, задержка будет 262,1 мс. Смущают какие-то не слишком привязанные к двоичным порядкам числа (кроме 65536), потому и хотел уточнить.
Арифметика тут простая:
Цитата:
The loop executes four CPU cycles per iteration
4 цикла * 65536 итераций дают те самые 262144, что при длительности цикла 1 мкс равно 262 с копейками миллисекундам.
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
Спасибо. Десяток раз перечитал, а four'а и не приметил) Пока доступа к программатору нет, в понедельник посмотрю, как оно инвертироваться будет. Но появился еще вопрос.
Код:
-(lfsr & 1u) & 0xd0000001u
Левая часть в итоге будет типа unsigned long. Справа, исходно, unsigned char, которое, перед проведением операции "И", превращается в unsigned long. Т.е. 0xd0000001u превратится в 31 ноль и единицу в младшем разряде. И раницы между таким 0xd0000001u (7 бит) и таким 0xd00000001u (8 бит) значением в данном случае, как я думаю, нет. Но самом деле есть, с 8-ми битным числом программа черти что начинает на выхода давать. Где в моей логике ошибка?
PS: Программы собираю gcc-avr из консоли в линуксе.
_________________ We do what we must because we can (c) GLaDOS
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения