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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

baghear, если вы не понимаете как оно должно работать, то как вы разберётесь в том что вам могут написать? К тому же процедура будет зависеть от схемы (от подключения АЦП к МК). Ну напишут вам код - будете просить объяснить как он работает? Можете не отвечать. Это, практически, риторический вопрос. :)
Если хотите, чтобы написали код за вас - это в другую тему.

А если по делу, то вам надо ознакомиться с битовыми операциями и сдвигами в Си.
Можете поискать программную реализацию SPI. Думаю, это то что вы ищите. Если разберётесь как она работает, то и со считыванием с вашего АЦП разберётесь.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

baghear писал(а):Приведите пожалуйста пример кода на си.
Принип приблизительно такой, тонкости по ситуации:
Спойлер

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

#define DDR_ADC  DDRD
#define PIN_ADC  PIND
#define PORT_ADC PORTD

#define ADC_PIN  (1<<PD2) // Последовательный выход АЦП
#define ADC_CLK  (1<<PD1) // Вывод тактирования АЦП

int main() {
...
	DDR_ADC |= ADC_CLK;  // Этот пин МК будет выходом (организовывать тактирование с периодом, например, 10 мкс)
	DDR_ADC &= ~ADC_PIN; // Этот пин МК будет входом (принимать данные с выхода АЦП)
...
}


uint32_t adcResult()
{
	uint8_t i;
	uint32_t adcValue = 0;

	for (i = 0; i < 24; i++) {
		_delay_us(5);
		PORT_ADC |= ADC_CLK;
		
		if (PIN_ADC & ADC_PIN) {
			adcValue |= 0x01;
		}

		if (i != 23)
			adcValue <<= 1;

		_delay_us(5);
		PORT_ADC &= ~ADC_CLK;
	}

	return adcResult;
}
Последний раз редактировалось WiseLord Чт сен 11, 2014 08:47:50, всего редактировалось 1 раз.
Реклама
Аватара пользователя
baghear
Опытный кот
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

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

Сообщение baghear »

Спасибо большое!!!
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Недавно опять у меня ступор был с этими странными стандартами Си...


Долго не мог понять почему не работает одна функция, вроде перепроверял, все должно быть ОК...
Потом разобрался, оказывается следующий вариант -

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

uint32_t var = 0x12345678;
UartTransmitHexLong (var & (0x0000ffff << 16));
Дает в результате 0x00000000... хотя логично было получить 0x12340000...


А вот такой вариант -

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

uint32_t var = 0x12345678;
UartTransmitHexLong (var & (0xffffUL << 16));
Дает нормальные 0x12340000...


Почему в первом случае компиль не понимает 0x0000ffff как UL ?.... я же ему явно задаю количество знаков.....
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18671
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

в первом случае у вас не со сдвигом была проблема, а с начальным присваиванием константы 0x12345678.

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

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

ARV писал(а):в первом случае у вас не со сдвигом была проблема, а с начальным присваиванием константы 0x12345678.
А точнее - константы 0x0000FFFF...
ARV писал(а):все числовые константы, если явно не указан их тип, имеют размерность int. поэтому даже число 0x23498579834759823476982347982347 все равно будет типа int.
Интересно, а чем продиктован такой подход?
Логично же что если константа разрядностью больше 16 бит, то компиль мог бы сформировать 32-х битное число...
Реклама
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

ARV писал(а):в первом случае у вас не со сдвигом была проблема, а с начальным присваиванием константы 0x12345678.
Ан нет... именно в случае со сдвигом проблема проявляется...

Вот так делаю - нормально получается - 0x12340000...

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

uint32_t temp = 0x12345678;
UartTransmitHexLong (temp & 0xffff0000);
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18671
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

берем константу 0x0000FFFF, которая воспринимается как 0xFFFF (int - мы же о таком int говорим?) и пробуем сдвинуть ее на 16 разрядов... получаем 0. это проблема в первом образце кода. AND с 0 даст 0, и плевать на первую константу (в присваивании), хотя и там она int.

во втором примере суффиксом UL вы указали, что константа 32-битная, поэтому проблемы и нет
Последний раз редактировалось ARV Пн сен 15, 2014 17:38:36, всего редактировалось 1 раз.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

ARV писал(а):в первом случае у вас не со сдвигом была проблема, а с начальным присваиванием константы 0x12345678
ARV, Вы, видимо, поторопились с ответом. Необдуманно... :)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18671
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Аlex писал(а):
ARV писал(а):в первом случае у вас не со сдвигом была проблема, а с начальным присваиванием константы 0x12345678
ARV, Вы, видимо, поторопились с ответом. Необдуманно... :)
частично - согласен, но лишь частично - см. корректировку предыдущего моего поста :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

:))
Да я ж не в упрёк :)
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

КажиСЯ я понял логику компиля... вернее - компилерописателей...


В этом случае -

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

uint32_t temp = 0x12345678;
UartTransmitHexLong (temp & 0xffff0000);
раз переменная temp - 32-х разрядная, то и константа подтягивается автоматом к 32-м разрядам (та скать - автоматическое приведение типа) и результат нормальный...


В этом случае -

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

uint32_t var = 0x12345678;
UartTransmitHexLong (var & (0x0000ffff << 16));
сначала вычисление происходит со сдвигом константы, а она как выяснилось по умолчанию 16-ти разрядная... указатель сдвига тоже обычный, следовательно никакого приведения к 32-м разрядам не происходит... и мы благополучно теряем FFFF... остается чистый 16-ти разрядный нолик...
Потом уже вычисляется &, и естественно правый 16-ти разрядный нолик приводится к 32-м разрядам... но вот незадача, сколько нолик не приводи, он так и остается ноликом )))
В итоге - то что имеем...


PS.
Ой... пока писал, ARV уже практически все объяснил...

PPS.
Хотя... внимательнее ваше объяснение почитал, помоему у меня более правдоподобно :)...
Аватара пользователя
ua1arn
Встал на лапы
Сообщения: 81
Зарегистрирован: Вт май 08, 2012 23:15:45
Откуда: Санкт - Петербург

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

Сообщение ua1arn »

ARV писал(а): все числовые константы, если явно не указан их тип, имеют размерность int. поэтому даже число 0x23498579834759823476982347982347 все равно будет типа int.
Пункт стандарта 3.1.3.2 (кусочек):

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

   Значение  десятичной константы вычисляется по основанию 10,
значение  восьмеричной константы вычисляется по основанию 8, а
шестнадцатеричной константы - по основанию 16. Лексически пер-
вая цифра является старшей цифрой значения.
   Типом целой константы будет первый  из  перечисленных  ниже
типов,  в котором может быть представлено ее значение. Бессуф-
фиксные десятичные: int, long int, unsigned long int;  бессуф-
фиксные восьмеричные или шестнадцатеричные: int, unsigned int,
long  int,  unsigned long int; константы с беззнаковым суффик-
сом: unsigned int, unsigned long int;  константы  с  суффиксом
размера: long int, unsigned long int; константы с разными суф-
фиксами: unsigned long int.
ARV
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

ua1arn, это Вы к чему ? Как эта вырезка относится к типу констант по-умолчанию ?
Аватара пользователя
ua1arn
Встал на лапы
Сообщения: 81
Зарегистрирован: Вт май 08, 2012 23:15:45
Откуда: Санкт - Петербург

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

Сообщение ua1arn »

Так относится, что ARV утверждает не совсем правду. Тип констант не всегда int, а зависит от значения (ну и суффиксов, разумеется).

Вот цитата из другой версии перевода стандарта на русский язык:
СпойлерИзображение
Вложения
constants.png
(117.98 КБ) 514 скачиваний
Последний раз редактировалось ua1arn Пн сен 15, 2014 18:39:52, всего редактировалось 1 раз.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18671
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

ua1arn писал(а):Тип констант не всегда int, а зависит от значения (ну и суффиксов, разумеется).
:oops: :?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Так я не понял... и шо... все чет намеками какими то изъясняются...

Вы мне по русски скажите... 0x12345678 - это 16-ти разрядная или 32-х разрядная константа?.....

Если все так как утверждал ARV, то вроде у меня в голове все прояснилось...

Если все так как утверждает ua1arn, то у меня опять "разрыв шаблона" .....
Аватара пользователя
ua1arn
Встал на лапы
Сообщения: 81
Зарегистрирован: Вт май 08, 2012 23:15:45
Откуда: Санкт - Петербург

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

Сообщение ua1arn »

0x12345678 - это 32-х разрядная константа. Для avr-gcc её тип signed long. Если написать 0xdeadbeaf - то unsigned long на этом же компиляторе. На arm-none-eabi-gcc её тип signed int, для второй unsigned int.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Почему тогда этот пример:

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

uint32_t var = 0x12345678;
UartTransmitHexLong (var & (0x0000ffff << 16));
дает результат 0x00000000 ?
Т.е. константа 0x0000ffff трактуется как 16-ти разрядная... (о... чет подумалось... может не представление числа а его значение играет роль, скольки разрядным оно будет... т.е. в данном случае 0x0000ffff помещается в 16 разрядов, поэтому и назначается 16-ти разрядным... не?)

Компилирую в AVRSTUDIO4...
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Да... ua1arn прав...


этот вариант не работает

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

uint32_t temp = 0x12345678;
UartTransmitHexLong (temp & (0x0000ffff << 16));
т.к. тут константа 0x0000ffff не превышает 16 разрядов, соответственно константе и отводится 16 разрядов.....


а этот вариант работает

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

uint32_t temp = 0x12345678;
UartTransmitHexLong (temp & (0x000fffff << 16));
т.к. тут константа 0x000fffff превышает 16 разрядов, соответственно константе назначается 32 разряда...


Вроде разобрались, всем спасибо :) ...
В общем, если нужно гарантированно обеспечить 32 разряда константе, лучше это указать явно или так UL или так (uint32_t)...
Ответить

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