так норм.
Вопросы по С/С++ (СИ)
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
- Реклама
- Сообщения: 275
- Зарегистрирован: Вс окт 20, 2019 13:03:56
В общем, это сделать невозможно. Как только не пробовал, засыпает ошибками. Потому, буду использовать первоначальный рабочий вариант.
Простых понятных примеров рабочего прогмема класса хеллворлд найти не могу, везде либо простынки где непонятно что к чему, либо еще менее понятные какие-то двухкоординатные char[j]
Хочу допилить и сделать покрасивше подпрограммы для индикатора. В связи с тем вопрос: а как ставить и снимать биты в unsigned char в одной строке одновременно?
Простых понятных примеров рабочего прогмема класса хеллворлд найти не могу, везде либо простынки где непонятно что к чему, либо еще менее понятные какие-то двухкоординатные char[j]
Хочу допилить и сделать покрасивше подпрограммы для индикатора. В связи с тем вопрос: а как ставить и снимать биты в unsigned char в одной строке одновременно?
Код: Выделить всё
a |= (1<3); // установить бит 3 переменной a
a &= ~(1<<3); // очистить бит 3 переменной a- Сообщения: 275
- Зарегистрирован: Вс окт 20, 2019 13:03:56
А чем это не в одну строку? Или нужно и то и другое сразу? Если так, то можно тое накрутить каким-нибудь макросом, но стандартного простого способа вроде как нет.
Код: Выделить всё
a = (a | ((1<<2) | (1<<0))) & ~((1<<4) | (1<<1));- Реклама
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Нуу.... проще и нагляднее в 2 строки написать, если не все биты меняются. А то получается хрень, вроде такой:
Добавлено after 4 minutes 39 seconds:
А, ну да, WiseLord правильнее написал, у меня лишний шаг И.
Код: Выделить всё
a = (a | (1 << 0)) & (a & ~(1 << 1));А, ну да, WiseLord правильнее написал, у меня лишний шаг И.
- Сообщения: 3386
- Зарегистрирован: Пн окт 11, 2010 19:00:08
NStorm писал(а):Нуу.... проще и нагляднее в 2 строки написать
Код: Выделить всё
a = (a | (1 << 0))
& (a & ~(1 << 1));[uquote="Shuspano",url="/forum/viewtopic.php?p=3841172#p3841172"]Но вроде как можно в одну строку...[/uquote]

Код: Выделить всё
a |= (1<3); a &= ~(1<<3);- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Господа, не забыаайте, что вы с AVR имеете дело. При работе с портами такие директивы компилятор в CBI и SBI транслирует. Одним выражением (не строкой конечно же, тут вас Аlex круто подколол) будет "чтение - модификация - запись".
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Только если будет меняться всего 1 бит. Если больше 1го, всё-равно будет R-M-W с OR/AND.При работе с портами такие директивы компилятор в CBI и SBI транслирует
[uquote="Shuspano",url="/forum/viewtopic.php?p=3841172#p3841172"]Так я знаю. Но вроде как можно в одну строку... или нет?[/uquote]
В Си нет прямой связи между количеством строк и чем-то ещё, размером кода, например, или скоростью его исполнения. Зато часто прослеживается связь "меньше строк - менее понятно - больше вероятность ошибки".
Добавлено after 2 minutes 14 seconds:
[uquote="NStorm",url="/forum/viewtopic.php?p=3841259#p3841259"]Только если будет меняться всего 1 бит. Если больше 1го, всё-равно будет R-M-W с OR/AND.[/uquote]так вроде и SBI тоже RMW... Или я путаю?
В Си нет прямой связи между количеством строк и чем-то ещё, размером кода, например, или скоростью его исполнения. Зато часто прослеживается связь "меньше строк - менее понятно - больше вероятность ошибки".
Добавлено after 2 minutes 14 seconds:
[uquote="NStorm",url="/forum/viewtopic.php?p=3841259#p3841259"]Только если будет меняться всего 1 бит. Если больше 1го, всё-равно будет R-M-W с OR/AND.[/uquote]так вроде и SBI тоже RMW... Или я путаю?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Не, SBI/CBI - одна инструкция на асме.
Ну это имеет смысл, если по какой-то причине установку и снятие бита надо проводить атомарно, при этом не весь регистр писать. За всё время в реальности ни разу такой необходимости не встречал...Зато часто прослеживается связь "меньше строк - менее понятно - больше вероятность ошибки".
Имхо, с атомарностью многострочность никак не связана.
А SBI, если я не ошибаюсь (давно асм в руки брал), инструкция одна, но работает именно в три этапа со всеми побочными эффектами.
А SBI, если я не ошибаюсь (давно асм в руки брал), инструкция одна, но работает именно в три этапа со всеми побочными эффектами.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
ARV, связана. Если a объявлена volatile, то для этих примеров компилятор сформирует разный код.
А если не volatile, то, скоре всего, код сфорируется одинаковый.
Код: Выделить всё
a = (a | ((1<<2) | (1<<0))) & ~((1<<4) | (1<<1));Код: Выделить всё
a |= ((1<<2) | (1<<0));
a &= ~((1<<4) | (1<<1));- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Нет там никаких 3х этапов, путаете что-то.
И конечно не совсем атомарно, будет всё-равно RMW, при этом M в 2 операции - AND, OR. Но запись будет именно в 1 операцию уже.
И конечно не совсем атомарно, будет всё-равно RMW, при этом M в 2 операции - AND, OR. Но запись будет именно в 1 операцию уже.
- Сообщения: 275
- Зарегистрирован: Вс окт 20, 2019 13:03:56
А вот такой вопросик. Как узнать длину строки в такой конструкции, не считая это вручную:
В ассемблере, транслятор может посчитать расстояние между метками, которыми ограничена строка, и так можно узнать ее длину. А тут как это делается?
Код: Выделить всё
const __flash char lcd_data[] = "строка";Shuspano,
Код: Выделить всё
#define MY_STRING "строка"
#define MY_STRING_LEN sizeof(MY_STRING)
const __flash char lcd_data[] = MY_STRING;
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Shuspano, просто sizeof(lcd_data) тоже будет работать.
Добавлено after 2 minutes 13 seconds:
Только ес-но реальный размер, с учетом терминирующего \0 в конца:
Возвращает 7 байт (stroka + \0). Если надо именно длину текста посчитать - sizeof() - 1 
Добавлено after 1 minute 8 seconds:
Ну и кодировку учитывайте при кириллице. Если вдруг в utf-8 запишите, будет 13 байт соотв, по 2 байта на символ.
Добавлено after 2 minutes 13 seconds:
Только ес-но реальный размер, с учетом терминирующего \0 в конца:
Код: Выделить всё
volatile uint8_t a = 1;
const __flash char lcd_data[] = "stroka";
int main() {
a = sizeof(lcd_data);
56: 87 e0 ldi r24, 0x07 ; 7
58: 80 93 60 00 sts 0x0060, r24 ; 0x800060 <__data_start>
Добавлено after 1 minute 8 seconds:
Ну и кодировку учитывайте при кириллице. Если вдруг в utf-8 запишите, будет 13 байт соотв, по 2 байта на символ.
я сказал "напрямую", т.е. невозможно заранее предсказать, какой именно код получится от 1, 2 или 3 строчной записи одного и того же действия. например, в случае не-volatile может и 100500 строк превратиться в одну командуПростоНуб писал(а):связана
не поленился, поднял документы... ошибаетесь вы:NStorm писал(а):Нет там никаких 3х этапов, путаете что-то.
в конкретно вашем примере, как вам посоветовали, через sizeof. но вообще-то для этого есть в модуле avr/pgmspace.h специальная функция strlen_P, которая вычислит длину любой строки в памяти программ.Shuspano писал(а):Как узнать длину строки в такой конструкции, не считая это вручную:
- Вложения
-
- screenshot-file2.dzsc.com-2020.05.png
- (64.35 КБ) 484 скачивания
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
ARV, это не о том. Полностью же написано всё. Речь идет о том, что в Status Flags нельзя с помощью инструкций CBI/SBI записать, т.к. они работают только с регистрами с 0х00 по 0х1F. Поэтому чтобы записать в Status Flags будет операция RMW - считается Status в один из этих регистров, затем он меняется с помощью CBI/SBI и записывается назад. Если будете менять регистр с 0x00 по 0x1F - он поменяется напрямую SBI/CBI атомарно и в одну операцию (которая 2 такта Fclk выполняется).
EDIT: Тут выше я уже сам запутался и не так перевел. Действительно, в некоторых старых AVR возможно эти инструкции так криво работали. В новых - неактуально, ниже в комментарии описал.
EDIT: Тут выше я уже сам запутался и не так перевел. Действительно, в некоторых старых AVR возможно эти инструкции так криво работали. В новых - неактуально, ниже в комментарии описал.
Последний раз редактировалось NStorm Чт май 14, 2020 18:33:14, всего редактировалось 1 раз.


