За макросы - опять спасибо! Дельная идея, воспользуюсь.
Вопросы по С/С++ (СИ)
- Сообщения: 768
- Зарегистрирован: Вс янв 19, 2014 00:55:09
Оппа! А я полагал, что "sizeof(data_t.b)" выдаст мне размер массива, а "sizeof(data_t.c[0])" - размер элемента массива?
За макросы - опять спасибо! Дельная идея, воспользуюсь.
За макросы - опять спасибо! Дельная идея, воспользуюсь.
- Реклама
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
[uquote="MOHCTEP",url="/forum/viewtopic.php?p=3885789#p3885789"]Оппа! А я полагал, что "sizeof(data_t.b)" выдаст мне размер массива, а "sizeof(data_t.c[0])" - размер элемента массива?[/uquote]
Брр... нет, это я уже загнался на вечер выходного дня. Конечно же умножать не нужно, т.к. sizeof(array) вернет размер целиком массива в байтах. Это я почему-то решил, что берется от одного элемента массива тоже. Вы правы в данном случае.
Брр... нет, это я уже загнался на вечер выходного дня. Конечно же умножать не нужно, т.к. sizeof(array) вернет размер целиком массива в байтах. Это я почему-то решил, что берется от одного элемента массива тоже. Вы правы в данном случае.
- Сообщения: 768
- Зарегистрирован: Вс янв 19, 2014 00:55:09
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Доброго времени суток. Имеется код выбора slave через 4-to-16 bit decoder
который покрывает все возможные варианты. Но он явно избыточный, если я например использую в конкретном проекте только 9 slave-ов. Возможно ли с помощью дефайна и макроса/ов, создать конструкцию, которая сгенерирует за меня только 9 case-ов, не создавая ненужные. Не прошу готового варианта, подскажите хотя бы, что гуглить ?
Up: Вроде Х-макросы то что нужно.
Спойлер
Код: Выделить всё
switch(peripheral){
case SPI_PERIPHERAL_0:
REG_SPI_MR |= SPI_MR_PCS(0b0000);
break;
case SPI_PERIPHERAL_1:
REG_SPI_MR |= SPI_MR_PCS(0b0001);
break;
case SPI_PERIPHERAL_2:
REG_SPI_MR |= SPI_MR_PCS(0b0010);
break;
case SPI_PERIPHERAL_3:
REG_SPI_MR |= SPI_MR_PCS(0b0011);
break;
case SPI_PERIPHERAL_4:
REG_SPI_MR |= SPI_MR_PCS(0b0100);
break;
case SPI_PERIPHERAL_5:
REG_SPI_MR |= SPI_MR_PCS(0b0101);
break;
case SPI_PERIPHERAL_6:
REG_SPI_MR |= SPI_MR_PCS(0b0110);
break;
case SPI_PERIPHERAL_7:
REG_SPI_MR |= SPI_MR_PCS(0b0111);
break;
case SPI_PERIPHERAL_8:
REG_SPI_MR |= SPI_MR_PCS(0b1000);
break;
case SPI_PERIPHERAL_9:
REG_SPI_MR |= SPI_MR_PCS(0b1001);
break;
case SPI_PERIPHERAL_10:
REG_SPI_MR |= SPI_MR_PCS(0b1010);
break;
case SPI_PERIPHERAL_11:
REG_SPI_MR |= SPI_MR_PCS(0b1011);
break;
case SPI_PERIPHERAL_12:
REG_SPI_MR |= SPI_MR_PCS(0b1100);
break;
case SPI_PERIPHERAL_13:
REG_SPI_MR |= SPI_MR_PCS(0b1101);
break;
case SPI_PERIPHERAL_14:
REG_SPI_MR |= SPI_MR_PCS(0b1110);
break;
case SPI_PERIPHERAL_15:
REG_SPI_MR |= SPI_MR_PCS(0b1111);
break;
}
Up: Вроде Х-макросы то что нужно.
Последний раз редактировалось Пока_без_кота Вс сен 20, 2020 16:25:40, всего редактировалось 1 раз.
Пока_без_кота, а что мешает изначально сделать значение peripheral равным значению требуемой маски?
Тогда весь развесистый case сведется к одной строке
REG_SPI_MR |= SPI_MR_PCS(peripheral);
Тогда весь развесистый case сведется к одной строке
REG_SPI_MR |= SPI_MR_PCS(peripheral);
- Реклама
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3895214#p3895214"]а что мешает ...[/uquote]
Мне помешала зашоренность сознания. Спасибо за умную мысль.
Мне помешала зашоренность сознания. Спасибо за умную мысль.
Как на 51-м ядре максимально быстро и компактно (не табличным способом) отзеркалить байт?
Пока приходит в голову только 8 строк подряд
Пока приходит в голову только 8 строк подряд
Код: Выделить всё
if (in&0x01) out |= 0x80;
...
if (in&0x80) out |= 0x01;[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Gudd-Head,
Взял отсюда: https://stackoverflow.com/questions/260 ... -in-a-byte
Код: Выделить всё
unsigned char reverse(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
- Сообщения: 1378
- Зарегистрирован: Вт ноя 19, 2019 06:10:18
[uquote="NStorm",url="/forum/viewtopic.php?p=3901934#p3901934"]Gudd-Head,
Взял отсюда: https://stackoverflow.com/questions/260 ... -in-a-byte[/uquote]
Решение универсальное.
Если же конкретно под 51-ый, то у него есть куча команд обработки битов. Всё эти биты доступны на Си. В Кейле были макросы для команд ротации и сдвига через перенос. Получается очень просто: сдвиг А через перенос, загрузка С в нужный бит В. И так 8 раз. В конце загрузка В в А.
Код: Выделить всё
unsigned char reverse(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
Решение универсальное.
Если же конкретно под 51-ый, то у него есть куча команд обработки битов. Всё эти биты доступны на Си. В Кейле были макросы для команд ротации и сдвига через перенос. Получается очень просто: сдвиг А через перенос, загрузка С в нужный бит В. И так 8 раз. В конце загрузка В в А.
[uquote="NStorm",url="/forum/viewtopic.php?p=3901934#p3901934"]Gudd-Head,
[/uquote]
Видел я это, в "алгоритмических трюках для программистов". Но есть у меня подозрение, что это только на Сях красиво выглядит. А по факту на 51-м ядре развернётся в огромную простыню. Хотя если компилятор догадается SWAPнуть... Надо проверить.
[uquote="tonyk",url="/forum/viewtopic.php?p=3901963#p3901963"]Всё эти биты доступны на Си. В Кейле были макросы для команд ротации и сдвига через перенос.[/uquote]
А вот здесь можно подробней? Среда Keil uVision 4.
Код: Выделить всё
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;Видел я это, в "алгоритмических трюках для программистов". Но есть у меня подозрение, что это только на Сях красиво выглядит. А по факту на 51-м ядре развернётся в огромную простыню. Хотя если компилятор догадается SWAPнуть... Надо проверить.
[uquote="tonyk",url="/forum/viewtopic.php?p=3901963#p3901963"]Всё эти биты доступны на Си. В Кейле были макросы для команд ротации и сдвига через перенос.[/uquote]
А вот здесь можно подробней? Среда Keil uVision 4.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Добрый день. Нужно в функции использовать элементы массива. Но не всегда все. И не всегда с начала массива.
Вот, например:
f(int arr[]) {...}
int a[10];
int n;
Варианты вызова функции в программе:
f(a); или f(&a[0]); // если массив обрабатывается с нулевого элемента
f(a+3); или f(&a[3]); // если начинаем с третьего элемента
f(a+n); или f(&a[n]); // если начальный элемент заранее неизвестен
Все ли я правильно написал?
Вот, например:
f(int arr[]) {...}
int a[10];
int n;
Варианты вызова функции в программе:
f(a); или f(&a[0]); // если массив обрабатывается с нулевого элемента
f(a+3); или f(&a[3]); // если начинаем с третьего элемента
f(a+n); или f(&a[n]); // если начальный элемент заранее неизвестен
Все ли я правильно написал?
учиться никогда не поздно...
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
waddds, да, только учтите, что так легко выйти за границы массива внутри функции. Поэтому по хорошему еще размерность массива в функцию передавать (до конца сколько осталось). Ну и учитывать, что в функцию передается не копия массива, а указатель на текущий массив. И изменив значения в функции, поменяется и исходный массив.
Спасибо. Про размерность массива я уже думал, можно же просто контроллировать корректность передаваемых параметров. Хотя, можно и добавить контроль внутри функции. Для надежности. Хочу более-менее унивирсальную библиотеку для аппаратного I2C сделать для dspic30. Что то более общее и удобное, чем встроенная в компилятор.
В данном случае функция для передачи данных,массив будет только читаться, так что внутри функции не изменится.
А в функции для чтения из устройства возможность изменить массив из функции очень даже пригодится.
Тема указателей, в общем, то понятна, но пока на практике как то обходился без них. А здесь и не обойтись ...
В данном случае функция для передачи данных,массив будет только читаться, так что внутри функции не изменится.
А в функции для чтения из устройства возможность изменить массив из функции очень даже пригодится.
Тема указателей, в общем, то понятна, но пока на практике как то обходился без них. А здесь и не обойтись ...
учиться никогда не поздно...
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
Ну когда массив передается в кач-ве аргумента функции, он всегда передается как указатель на первый или указанный элемент. Когда передается указатель на данные динамического размера, принято обычно следующим аргументом передавать их длину, если их нельзя терминировать чем-то, как строку \0, к примеру.
использую Onewire библиотеку
положительная температура правильно, просто замечательно отображается, а отрицательная- абракадабра
float readDS18B20(){
oneWire.reset(); // сброс шины
oneWire.write(0xCC); //обращение ко всем датчикам (если всего один DS18B20)
//oneWire.select(sensorAddress); // выбор конкретного адреса - если несколько DS18B20
oneWire.write(0x44); // начать преобразование (без паразитного питания)
oneWire.reset(); // сброс шины
oneWire.write(0xCC); //обращение ко всем датчикам (если всего один DS18B20)
//oneWire.select(sensorAddress); // выбор конкретного адреса - если несколько DS18B20
oneWire.write(0xBE); // Read Scratchpad (чтение регистров)
temp = (oneWire.read() | oneWire.read() << 8 ) / 16.0; //прочитаны 2 байта
}
// ---------------------------------------------------------------------- ВЫВОД ТЕМПЕРАТУРЫ НА ДИСПЛЕЕ
void showTemp(){ //
if(secFr==0) temp=readDS18B20(); // читаем датчик DS18B20. Для DS18S20 не подходит!
if(temp<0) showDigit(11, 0, dig5x8rn); // Если температура отрицательная печатаем в начале "-"
else showDigit(10, 0, dig5x8rn); // Иначе печатаем "+"
int t1=(int)temp/10; // число десятков
int t0=(int)temp%10; // число едениц
int tf=(temp-int(temp))*10.0; // число десятых
if(t1) showDigit(t1, 4, dig4x8); // если десяки = "0" то не печатаем
showDigit(t0, 9, dig4x8); // печатаем еденицы
showDigit(tf, 16, dig4x8); // печатаем десятые
setCol(14, 0xC0); // выводим запятую между целыми и десятыми градусов
showDigit(7, 22, dweek_ru); // Выводим значек градусов и "С"
} //
помогите как сделать преобразование отрицательного числа
положительная температура правильно, просто замечательно отображается, а отрицательная- абракадабра
Спойлер
// ---------------------------------------------------------------------- обращаемся к функцииfloat readDS18B20(){
oneWire.reset(); // сброс шины
oneWire.write(0xCC); //обращение ко всем датчикам (если всего один DS18B20)
//oneWire.select(sensorAddress); // выбор конкретного адреса - если несколько DS18B20
oneWire.write(0x44); // начать преобразование (без паразитного питания)
oneWire.reset(); // сброс шины
oneWire.write(0xCC); //обращение ко всем датчикам (если всего один DS18B20)
//oneWire.select(sensorAddress); // выбор конкретного адреса - если несколько DS18B20
oneWire.write(0xBE); // Read Scratchpad (чтение регистров)
temp = (oneWire.read() | oneWire.read() << 8 ) / 16.0; //прочитаны 2 байта
}
// ---------------------------------------------------------------------- ВЫВОД ТЕМПЕРАТУРЫ НА ДИСПЛЕЕ
void showTemp(){ //
if(secFr==0) temp=readDS18B20(); // читаем датчик DS18B20. Для DS18S20 не подходит!
if(temp<0) showDigit(11, 0, dig5x8rn); // Если температура отрицательная печатаем в начале "-"
else showDigit(10, 0, dig5x8rn); // Иначе печатаем "+"
int t1=(int)temp/10; // число десятков
int t0=(int)temp%10; // число едениц
int tf=(temp-int(temp))*10.0; // число десятых
if(t1) showDigit(t1, 4, dig4x8); // если десяки = "0" то не печатаем
showDigit(t0, 9, dig4x8); // печатаем еденицы
showDigit(tf, 16, dig4x8); // печатаем десятые
setCol(14, 0xC0); // выводим запятую между целыми и десятыми градусов
showDigit(7, 22, dweek_ru); // Выводим значек градусов и "С"
} //
- Вложения
-
- chasy_matrica.zip
- (168.5 КБ) 299 скачиваний
- Сообщения: 768
- Зарегистрирован: Вс янв 19, 2014 00:55:09
Может так?
Код: Выделить всё
if(temp<0){
showDigit(11, 0, dig5x8rn);
temp *= -1;
}Да, если температура отрицательная, нужно не только минус распечатать, но и сделать её затем для дальнейших расчетов положительной, инвертировав значение.
Пытаюсь сделать копирование массивов с использованием ПДП. Пока есть вариант для копирования побайтно. Но, хочется, при определенных условиях копировать 16-битными словами или 32-битными. Полагал, что если адреса массивов и число копируемых данных делится на 4, то можно использовать 32-битный обмен. Но вот как это узнать?
Этот код не компилируется:
"../dma.c", line 41: error #31: expression must have integral type
"../dma.c", line 41: error #31: expression must have integral type
"../dma.c", line 46: error #31: expression must have integral type
"../dma.c", line 46: error #31: expression must have integral type
Как эту проверку сделать правильно?
Код: Выделить всё
void copy_data_dma (uint8_t * src, uint8_t * dst, uint16_t count) {
if (((src | dst | count) & 0x03UL) == 0) {
...
} else if (((src | dst | count) & 0x01UL) == 0) {
...
} else {....}"../dma.c", line 41: error #31: expression must have integral type
"../dma.c", line 41: error #31: expression must have integral type
"../dma.c", line 46: error #31: expression must have integral type
"../dma.c", line 46: error #31: expression must have integral type
Как эту проверку сделать правильно?
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Побитовое ИЛИ - не для указателей. Приводите к uint32_t:
((uint32_t)src | (uint32_t)dst | count)
((uint32_t)src | (uint32_t)dst | count)


