| Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
Косвенная адресация
30.06.2010, 04:55
|
#31
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Re: Косвенная адресация
Ну вот, давно бы так!
Масса примеров.
Теперь попробую что-то сделать.
В функции Блинк() не простое моргание светодиодом, а длинная последовательность двоичного кода.
Первый пример от dimanka не помог, компилятору не нравится &RA1
У меня компилятор PICSSC, вроде бы так пишется-точно не помню.
Остальные примеры ещё не пробовал.
Но всё равно: всем спасибо.
: - )
|
|
|
|
30.06.2010, 10:25
|
#32
|
|
Гражданин KAZUS.RUN
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: Косвенная адресация
Только не надо путать тёплое с мягким. Косвенное обращение к биту на Си, может скомпилироваться в простое. То есть формально красивое написание превращается в обычный код. А иногда и в избыточный. Но задача программиста, не красиво написать, а эффективно.
Надо понимать, что длина программы на Си не всегда сопоставима длине результирующего кода.
Например:
uint16_t i;
i *= 4; // для AVR будет скомпилировано в п/п
i ‹‹= 2; // будет скомпилировано в 2 сдвига, а результат одинаковый.
|
|
|
|
30.06.2010, 11:13
|
#33
|
|
Временная регистрация
Регистрация: 04.08.2006
Сообщений: 67
Сказал спасибо: 2
Сказали Спасибо 20 раз(а) в 11 сообщении(ях)
|
Re: Косвенная адресация
OFFTOP
Сообщение от SasaVitebsk
|
Только не надо путать тёплое с мягким.
Например:
uint16_t i;
i *= 4; // для AVR будет скомпилировано в п/п
i ‹‹= 2; // будет скомпилировано в 2 сдвига, а результат одинаковый.
|
Все зависит от оптимизации
Вот код, avr-gcc, -0s:
|
PHP код:
|
volatile int a = 5;
int main (void)
{
a *= 4;
a ‹‹= 2;
return 0;
}
|
Вот листинг:
|
Код:
|
a *= 4;
be: 80 91 00 01 lds r24, 0x0100
c2: 90 91 01 01 lds r25, 0x0101
c6: 88 0f add r24, r24
c8: 99 1f adc r25, r25
ca: 88 0f add r24, r24
cc: 99 1f adc r25, r25
ce: 90 93 01 01 sts 0x0101, r25
d2: 80 93 00 01 sts 0x0100, r24
a ‹‹= 2;
d6: 80 91 00 01 lds r24, 0x0100
da: 90 91 01 01 lds r25, 0x0101
de: 88 0f add r24, r24
e0: 99 1f adc r25, r25
e2: 88 0f add r24, r24
e4: 99 1f adc r25, r25
e6: 90 93 01 01 sts 0x0101, r25
ea: 80 93 00 01 sts 0x0100, r24 |
Можно поэкспериментировать с другими числами (например 16 и 4)
|
|
|
|
30.06.2010, 11:45
|
#34
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,815
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Re: Косвенная адресация
Сообщение от yellow87
|
Ну вот, давно бы так!
Масса примеров.
Теперь попробую что-то сделать.
|
а что то типа этого?
|
Код:
|
_flash unsigned char table_mask_bit_set [8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80;}
_flash unsigned char table_mask_bit_clr [8]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F;}
//установить бит в порту
PORTB=PORTB | table_mask_bit_set[namber_bit];
//сбросить бит в порту
PORTB=PORTB & table_mask_bit_clr[namber_bit]; |
по идее должно компилится в 2 масива во FLASH на 16 бит и обращение к нему. Думаю не сильно обьёмно по коду. Правда такое в СИ ещё не применял, написал аналогично того что обычно в асме делал.
__________________
"picavr(ГАВ)мыло.ру" USB_Analyzer, Digital_Storage_Oscilloscope "picavr.kr1.ru" заказы в Китай компонентов/изготовление: плат/ЖКИ/мембраных клавиатур/имп трансформаторов
Последний раз редактировалось picavr; 30.06.2010 в 11:52.
|
|
|
|
01.07.2010, 05:08
|
#35
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Re: Косвенная адресация
Опять небыло времени проверить.
picavr, а если без массивов констант:
//установить бит в порту
PORTB=PORTB | namber_bit+1;
//сбросить бит в порту
PORTB=PORTB & 254-namber_bit;
|
|
|
|
01.07.2010, 07:56
|
#36
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 10.05.2005
Адрес: Саратов.ru
Сообщений: 1,550
Сказал спасибо: 384
Сказали Спасибо 735 раз(а) в 416 сообщении(ях)
|
Re: Косвенная адресация
Сообщение от yellow87
|
//установить бит в порту
PORTB=PORTB | namber_bit+1;
//сбросить бит в порту
PORTB=PORTB & 254-namber_bit;
|
//установить бит в порту
PORTB=PORTB | (1‹‹namber_bit);
//сбросить бит в порту
PORTB=PORTB & ~(1‹‹namber_bit);
|
|
|
|
01.07.2010, 08:03
|
#37
|
|
Временная регистрация
Регистрация: 04.08.2006
Сообщений: 67
Сказал спасибо: 2
Сказали Спасибо 20 раз(а) в 11 сообщении(ях)
|
Re: Косвенная адресация
Ликбез 
Если надо установить бит в порту:
|
Код:
|
PORTB |= (1 ‹‹ bit_number); |
Сбросить:
|
Код:
|
PORTB &= ~(1 ‹‹ bit_number); |
Инвертировать:
|
Код:
|
PORTB ^= (1 ‹‹ bit_number); |
И тоже сразу для нескольких бит:
|
Код:
|
PORTB |= (1 ‹‹ bit_num_a) | (1 ‹‹ bit_num_b) | (1 ‹‹ bit_num_c);
PORTB &= ~((1 ‹‹ bit_num_a) | (1 ‹‹ bit_num_b) | (1 ‹‹ bit_num_c));
PORTB ^= (1 ‹‹ bit_num_a) | (1 ‹‹ bit_num_b) | (1 ‹‹ bit_num_c); |
|
|
|
|
01.07.2010, 08:13
|
#38
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Re: Косвенная адресация
Ну вот теперь точно всё должно заработать.
Вечером проверю.
Всем спасибо!
: - )
|
|
|
|
01.07.2010, 08:42
|
#39
|
|
Прописка
Регистрация: 09.08.2006
Сообщений: 197
Сказал спасибо: 14
Сказали Спасибо 27 раз(а) в 20 сообщении(ях)
|
Re: Косвенная адресация
Позволю себе процитировать Кернигана и Ричи (из главы 6.7):
"При работе с полями имеется ряд моментов, на которые следует обратить внимание. По-видимому наиболее существенным является то, что отражая природу различных аппаратных средств, распределение полей на некоторых машинах осуществляется слева направо, а на некоторых справа налево. Это означает, что хотя поля очень полезны для работы с внутренне определенными структурами данных, при разделении внешне определяемых данных следует тщательно рассматривать вопрос о том, какой конец поступает первым.
Другие ограничения, которые следует иметь в виду: поля не имеют знака; они могут храниться только в переменных типа INT (или, что эквивалентно, типа UNSIGNED); они не являются массивами; они не имеют адресов, так что к ним не применима операция &. "
Надеюсь, что после прочтения, топикстартер прекратит поиск обращения к биту (битовому полю) через указатель. Тем не менее, допускаю, что если большинство компиляторов "С" для МК содержат расширения языка типа: PORTC.5 - для обращения к конкретному биту порта, то может отыскаться компилятор выполняющий &PORTC.5, но я в этом сомневаюсь.
|
|
|
|
01.07.2010, 11:48
|
#40
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,815
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Re: Косвенная адресация
Сообщение от yellow87
|
Опять небыло времени проверить.
picavr, а если без массивов констант
|
без массива, c косвеной адресацией битов, с SWITCH или IF скорее всего будет компилится длинее. функции для каждого порта.
|
Код:
|
_flash unsigned char table_mask_bit_set [8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80;}
_flash unsigned char table_mask_bit_clr [8]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F;}
//-----------------------------------------------------------
void set_porta_pin (unsigned char namber_bit)
{
PORTA=PORTA | table_mask_bit_set[namber_bit]//установить бит в порту
}
//-----------------------------------------------------------
void clr_porta_pin (unsigned char namber_bit)
{
PORTA=PORTA & table_mask_bit_clr[namber_bit]//сбросить бит в порту
}
//----------------------------------------------------------- |
можно попробовать адресовать и номер порта
|
Код:
|
_flash unsigned char table_mask_bit_set [8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80;}
_flash unsigned char table_mask_bit_clr [8]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F;}
_flash unsigned char table_namber_port [7]={PORTA,PORTB,PORTC,PORTD,PORTE,PORTF,PORTG;}
//-----------------------------------------------------------
void set_port_pin (unsigned char namber_port,namber_bit)
{
unsigned char temp;
temp=table_namber_port[namber_port];
temp=temp | table_mask_bit_set[namber_bit];//установить бит в порту
table_namber_port[namber_port]=temp;
}
//-----------------------------------------------------------
void clr_port_pin (unsigned char namber_port,namber_bit)
{
unsigned char temp;
temp=table_namber_port[namber_port];
temp=temp | table_mask_bit_clr[namber_bit];//сбросить бит в порту
table_namber_port[namber_port]=temp;
}
//----------------------------------------------------------- |
__________________
"picavr(ГАВ)мыло.ру" USB_Analyzer, Digital_Storage_Oscilloscope "picavr.kr1.ru" заказы в Китай компонентов/изготовление: плат/ЖКИ/мембраных клавиатур/имп трансформаторов
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 21:42.
|
|