Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
-Valerius-
Встал на лапы
Сообщения: 99
Зарегистрирован: Сб янв 12, 2013 22:43:10
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение -Valerius- »

Прошу помощи- "ваяю" программу на Си, изначально задача стоит такая:
к контроллеру AVR необходимо подключить блок переключателей
(каждый разряд на своем выходе выдает код в формате 1-2-4-8).
Изображение
Сопряжение с контроллером выполнил с помощью двух CD4051, тут как-бы проблем нет.
С помощью switch я сканирую разряды и в результате получаю биты! разряда- раздельно. То есть -
считал биты первого разряда и получил переменные с этими битами.
Вопрос- как грамотно " склеить " биты в один полубайт?
Чтобы уже этот полубайт дальше отправить в дешифратор.
Спасибо.
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Вопросы по С/С++ (СИ)

Сообщение arkhnchul »

а во что вы биты складываете? в uint8? и какие значения у переменных?
так навскидку - логические битовые операции и, возможно, сдвиг
Аватара пользователя
-Valerius-
Встал на лапы
Сообщения: 99
Зарегистрирован: Сб янв 12, 2013 22:43:10
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение -Valerius- »

Пока тренируюсь- биты (unsigned int) биты имеют значение 0 . К примеру: считал я первый разряд, мои переменные (a,b,c,d = 0) приняли значения 1-0-0-1 (a = 1, b = 0, c = 0, d = 1). Мое нужно "как-то склеить" биты чтобы получилось одно число 1001 , которое я передам в дешифратор.
PS Сорри , если невнятно объясняю суть проблемы
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Вопросы по С/С++ (СИ)

Сообщение arkhnchul »

т.е. у вас переменные со значениями:

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

a == 0b00000001 //0x01
b == 0b00000000 //0x00
c == 0b00000000 //0x00
d == 0b00000001 //0x01

если так, то

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

uint8_t res = (a<<3) | (b<<2) | (c<<1) | d ; //0b00001001 == 0x09 
Аватара пользователя
-Valerius-
Встал на лапы
Сообщения: 99
Зарегистрирован: Сб янв 12, 2013 22:43:10
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение -Valerius- »

Спасибо за помощь. Вечером буду "тренироваться".
Удачи! :beer:
PS Если я правильно понимаю- первый бит это переменная d ?
Получается с помощью сдвига и логического И - "формируем" полубайт?
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Вопросы по С/С++ (СИ)

Сообщение arkhnchul »

-Valerius- писал(а):PS Если я правильно понимаю- первый бит это переменная d ?

если "первый бит" это нулевой разряд (2^0), то да.
-Valerius- писал(а):Получается с помощью сдвига и логического И - "формируем" полубайт?

строго говоря, формируем целый байт, и все abcd - тоже целые байты. А так - да.
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

Re: Вопросы по С/С++ (СИ)

Сообщение Pnjom-Penb »

-Valerius- писал(а):С помощью switch я сканирую разряды и в результате получаю биты!
Не очень понял, как это выглядит в схеме и в алгоритме. Если выход каждого разряда этого "кодонабирателя" представлен четырьмя сигналами {0,1}, то чтение этого через порт должно дать готовое число, без всяких-яких. Валериус, Вы ничего не напутали? :)
MOHCTEP
Опытный кот
Сообщения: 768
Зарегистрирован: Вс янв 19, 2014 00:55:09

Re: Вопросы по С/С++ (СИ)

Сообщение MOHCTEP »

-Valerius- писал(а): Получается с помощью сдвига и логического И - "формируем" полубайт?
логического ИЛИ
Можно и арифметикой пособирать для понимания :)

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

uint8_t res = a*8+b*4+c*2+ d ; //0b00001001 == 0x09

Но, предложенный arkhnchul вариант, более кошерный, имхо.
Аватара пользователя
-Valerius-
Встал на лапы
Сообщения: 99
Зарегистрирован: Сб янв 12, 2013 22:43:10
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение -Valerius- »

To Pnjom-Penb
Схемы как таковой и нет (пока что..), есть желание отработать только отдельные блоки программы, чтобы в дальнейшем уже из них собрать всю программу.
Вывод каждого разряда номеронабирателя представлен в виде 1-2-4-8 , итого четыре разряда = 16 "пинов" контроллера. И еще шесть дешифраторов (тоже в коде 1-2-4-8) = 24 "пин" AVR, получается что уже на этой стадии у меня задействовано 40 выводов контроллера. А еще нужно 2..3 кнопки, 3..4 вывода- "технологические". Поэтому- задействовал ATMega32 (у меня макет на ней), для обработки разрядов номеронабирателя- использовал два мультиплексора CD4051, выходы с контроллера на дешифраторы по ТЗ (техзаданию)- только с контроллера, 74HC595 использовать- нельзя. (Можно, но не нужно :) ) Поэтому, остановился на 32 меге, для всех "хотелок" - выводов хватает, единственное с входными сигналами непонятки были.
PS С каждого разряда номеронабирателя выходит пять выводов- питание и собственно код 1-2-4-8. Конечно, можно было бы напрямую соединить номеронабиратели с дешифраторами, но тогда кто вычислениями займется, как не AVR?
Изображение

To arkhnchul
если "первый бит" это нулевой разряд (2^0), то да.

Все верно 2^0, не верно выразил свою мысль :)

Всем спасибо за помощь, буду пробовать! :beer:
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Вопросы по С/С++ (СИ)

Сообщение arkhnchul »

MOHCTEP писал(а):Можно и арифметикой пособирать для понимания :)

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

uint8_t res = a*8+b*4+c*2+ d ; //0b00001001 == 0x09

арифметическое умножение в общем может дать лучший результат - если выполняется за меньшее количество тактов, чем последовательность сдвигов. Тут я ну совсем не знаток, но по беглому просмотру справочника для avr умножение - такт на запись множителя в регистр, два такта на умножение, такт на чтение результата; сдвиг - один такт для сдвига на одну позицию. Т.е. вроде как (???) вариант с умножением должен получаться предпочтительнее начиная со сдвига на 6 позиций.
MOHCTEP
Опытный кот
Сообщения: 768
Зарегистрирован: Вс янв 19, 2014 00:55:09

Re: Вопросы по С/С++ (СИ)

Сообщение MOHCTEP »

arkhnchul :) Так я ж отметил, что предложенный Вами код с битовыми сдвигами, предпочтительней. Просто -Valerius- чуть подзапутался в логике, вот я и предложил "альтернативу", исключительно для понимания сути и без претензии на ее использование. К моему стыду, я не владею информацией о тактовой продолжительности операций, однако статистика(личная) потребления ресурсов указывает на лучший кпд логики сравнительно с арифметикой посложнее "а+в".
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

Re: Вопросы по С/С++ (СИ)

Сообщение Pnjom-Penb »

-Valerius- писал(а):Вывод каждого разряда номеронабирателя представлен в виде 1-2-4-8 ...
Так я и думал. Не нужны Вам никакие сдвиги и лог.сложение по ИЛИ - заводите четыре выхода каждого разряда (через мультиплексор или к.л. иначе) на порт м/к и читаете этот порт - все дела. Если будут использованы четыре младших пина, то, например, так:

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

    value = PORTx & 0x0F;


Принцип такой:Изображение

Add-n
Как-то неясно Вы про использование вв/выв меги32 написали...
1. 40 вводов/выводов у нее нету - четыре порта по 8 = 32 вывода
2. Если "номеронабиратели" видны меге32 через 4051, то почему Вы пишете "итого четыре разряда = 16 "пинов" контроллера"? Там получается 8+3+1+1 = 13.
3. Про дешифраторы ничего не сказано, но возможно, требование "выходы на дешифраторы по ТЗ только с контроллера" также допускает мультиплексирование. Например, если у них есть вывод CS, или вывод Common, как у "номеронабирателей" на фото.
4. Логика вычислений не изложена ("Конечно, можно было бы напрямую соединить номеронабиратели с дешифраторами, но тогда кто вычислениями займется, как не AVR?"), однако, не исключено, что эта логика м.б. реализована без контроллера - смотря какая логика.

В общем, все, что связано с чтением номеронабирателей можно уложить в 6 или 7 выводов - в один порт, да еще и останется 1-2 вв/выв под кнопки. Если дешифраторы таковы, как я предположил выше, то их можно обрабатывать вторым портом. При отсутствии дешифратора "N -> 1_из_M", придется взять еще пару I/O из другого порта. Итого, на всякие "2..3 кнопки, 3..4 "технологические" вывода" останется два или почти два порта.

Опишите дешифраторы, м.б. спланировать точнее.
Вложения
sch_keyread.gif
(3.79 КБ) 675 скачиваний
Аватара пользователя
slavokhire5
Прорезались зубы
Сообщения: 202
Зарегистрирован: Пн сен 26, 2011 13:48:25
Откуда: Харьков

Re: Вопросы по С/С++ (СИ)

Сообщение slavokhire5 »

Привет всем котам. Имеется нубский вопрос по СИ и моим любимым указателям. помогите разобраться

Имеется внешняя ЕЕПРОМ. в ней лежит куча настроек в виде упакованных структур. Прочитать всю структуру проблем нет:

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

M95_read(SET_PAGE_START, (void *)(&settings), sizeof(settings));
скармливаем ф-ции чтения адрес начала читаемой структуры в ЕЕПРОМ(SET_PAGE_START), указатель на нужную структуру в ОЗУ (&settings), и размер структуры (sizeof(settings)).

Но если мне понадобится записать один из элементов (допустим, его зовут value) структуры в ЕЕПРОМ, как это короче сделать? (это вопрос №1)
Приходит в голову чтение по адресу структуры + адрес элемента ВНУТРИ структуры (или его смещение от начала структуры, не знаю как это правильно сказать). получается жутко длинная и не читаемая колбаса такого вида:

M95_write(SET_PAGE_START + смещение_внутри_структуры , (void *)(&settings.value), sizeof(settings.value));[/code]

вопрос №2: как правильно это смещение рассчитывать? я делаю так: смещение_внутри_структуры = *(settings.value) - *settings;
но кокос говорит мне, что я неправ - invalid operands to binary - (have 'uint8_t *' and 'struct settings)
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Re: Вопросы по С/С++ (СИ)

Сообщение arkhnchul »

slavokhire5 писал(а):Приходит в голову чтение по адресу структуры + адрес элемента ВНУТРИ структуры (или его смещение от начала структуры, не знаю как это правильно сказать). получается жутко длинная и не читаемая колбаса такого вида

смещение и зовется это.
Нечитаемая колбаса - да, адресная арифметика она такая :dont_know:
slavokhire5 писал(а):я делаю так: смещение_внутри_структуры = *(settings.value) - *settings;

если правильно помню, то так:
смещение_внутри_структуры = &(settings->value) - settings;
значение_внутри_структуры = *(settings + смещение_внутри_структуры)
могу ошибаться, птичий язык адресной арифметики никогда не давался(
BorisSPB
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Re: Вопросы по С/С++ (СИ)

Сообщение BorisSPB »

Есть такой макрос offsetof.
Все потроха спрятаны в нем, а в коде имеем читаемый и понятный текст...
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Chip115 »

Всем привет!
Ломаю голову, а что делает вот эта команда?

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

*((volatile unsigned char *) (0x77200480)) = 0x00;
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

Обнуляет ячейку в памяти по этому адресу.
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Вопросы по С/С++ (СИ)

Сообщение Jack_A »

Интересно, откуда выцарапана эта хрень с почти 2-гигабайтным адресом ? Мне бы МК со столько памяти :)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

Jack_A писал(а):откуда выцарапана эта хрень с почти 2-гигабайтным адресом ?
ARM же наверняка, виртуальные адреса...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
kalobyte
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Re: Вопросы по С/С++ (СИ)

Сообщение kalobyte »

вопрос у кого есть студия 2013
внезапно надо модифицировать прогу http://winapi32.narod.ru/#3 ruslat
индикатор раскладки клавиатуры

я его сбираю на своей системе 8.1 64бит
запускаю на 8.1 64, но на ней не установлены длл от мс, а на моей идут вместе со студией

прога автора же работает без запроса длл, а моя собранная просит msvcr120.dll

я загуглил и там пишут, что надо в разделе с++ выбрать ключ /MT
однако любая комбинация тамошних ключей ничего не дает
прога простая, винапи

вопрос 2
там есть некие магические цифры
case 1049:
tnid.hIcon = hIconRus;
я загуглил, но так и не понял этих цифр
https://msdn.microsoft.com/en-us/librar ... 85%29.aspx
Russian (ru) 0x19 LANG_RUSSIAN Russia (RU) 0x01 SUBLANG_RUSSIAN_RUSSIA
1049 это 0х0419
где взять магическое число для казахской раскладки?
тематические ответы только в форуме, в приват не пишите
Ответить

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