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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

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

Сообщение IfoR »

Ну и зачем для этого нужно выполнять одновременно две команды? И при чём здесь ШИМ? Просто выкидываете данные на порт и всё.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

Подскажите а как разбить попроще тот же float или long int на байты.

Т.е. вижу два варианта через union и пошаговый сдвиг на 8. По идее же можно и указателями это сделать?

Просто использовал объединение. А с long int чот не правильно работает... А со сдвижкой правильно...

union LI2Byte
{
unsigned long int I;
unsigned char c[4];
} I32;
I32.I=x// в общем какое то число
Выводишь с[i] , а там несоответсвие. Хотя со сдвигом -(unsgined char) x>>24&0xFF и так далее работает...
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

Сообщение Мастер Ломастер »

demiurg301 писал(а):Просто использовал объединение. А с long int чот не правильно работает... А со сдвижкой правильно...
а вы порядок байтов не путаете? в AVR байты многобайтного числа размещены от младшего к старшему, т.е. c[0] будет младшим байтом, c[3] - старшим для long int
битва с дураками проиграна, победители торжествуют. слава победителям!
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

ДЫк я б тогда это увидел. Я разлагал на байты, и высылал в порт. А на компе для проверки вручную переводил.

Т.е. если бы было 0x01 0x02 0x03 0x04 , а получилось 0x04 0x03 0x02 0x01 - я бы заметил :wink:

Но в частности меня больше интересует , а нельзя ил указателями разлагать, как бы взять указатель unsigned char от формата unsigned int - т.е. представить вручную, чтобы не использовать переходную переменную в виде 4х байтов. Часто нужно просто для вывода и записи в ПЗУ. А использовать конструкции вида

unsigned long int crcEEP
..............
crcEEP=*PtE++;
crcEEP|=(unsigned long int)*PtE++<<8;
crcEEP|=(unsigned long int)*PtE++<<16;
crcEEP|=(unsigned long int)*PtE++<<24;

Слишком много кода(одной строчкой вылазит за экран ) ... вот если б напрямую обращаться к байтам в памяти...
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

Сообщение Мастер Ломастер »

не подойдет?

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

#define b0(x) ((x) & 0xFF)
#define b1(x) (((x) >> 8) & 0xFF)
#define b2(x) (((x) >> 16) & 0xFF)
#define b2(x) (((x) >> 24) & 0xFF)
кстати, по вашему коду создалось впечатление, что вы пытаетесь подсчитать побайтную контрольную сумму области памяти, занятой многобайтными переменным - так? так ведь зная общее число байт в этой области можно объявить указатель на байт, присвоить ему адрес начала области и перебрать все байты без каких-либо преобразований типов...
битва с дураками проиграна, победители торжествуют. слава победителям!
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

Мастер Ломастер писал(а):не подойдет?

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

#define b0(x) ((x) & 0xFF)
#define b1(x) (((x) >> 8) & 0xFF)
#define b2(x) (((x) >> 16) & 0xFF)
#define b2(x) (((x) >> 24) & 0xFF)
кстати, по вашему коду создалось впечатление, что вы пытаетесь подсчитать побайтную контрольную сумму области памяти, занятой многобайтными переменным - так? так ведь зная общее число байт в этой области можно объявить указатель на байт, присвоить ему адрес начала области и перебрать все байты без каких-либо преобразований типов...


ДА, чот не подумал. Просто не люблю дефайны :)))

Не, это я считывал 32 битный CRC настроек модема из ПЗУ. Потом сравниваю с полученным из функции, для проверки подлинности, если не совпало - ещё 3 копии сохранено тамже... НУ и так 3 штуки подряд. А вот чо делать если все накроется :)))

ЗЫ Дето я читал или может это так ложные мысли..
ЧТо например

unsigned int I;
unsigned char *PtS;

PtS=(unsigned char*)I - не вернёт ли такая запись указательна 1( ну или 4) байт инта?
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

Сообщение Мастер Ломастер »

demiurg301 писал(а):unsigned int I;
unsigned char *PtS;

PtS=(unsigned char*)I - не вернёт ли такая запись указательна 1( ну или 4) байт инта?
не вернет. а вот так - вернет:

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

PtS = (void*)&I;
после этого (для AVR) PtS[0] - это будет младший байт инта I, а PtS[1] - старший.
битва с дураками проиграна, победители торжествуют. слава победителям!
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

PtS = (void*)&I;


Это мы типа приводим тип указателя к указателю на структуру соответствующу разрядности контроллера? ( 8 битам)
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

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

Сообщение alexey6522 »

Блииин, помогите! Спаял схему, до этого тестил на протеусе все работало, а в действительности вообще не принимаются не передаются данные, даже признаков жизни не подается, что делать, где капать, может кроме двух проводков еще нужно что-нибудь, куда-нибудь припоять, задействовано только 2 и 3 контакты Atmega8, на COM1 тоже 2 и 3.
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

Сообщение Мастер Ломастер »

demiurg301 писал(а):
PtS = (void*)&I;
Это мы типа приводим тип указателя к указателю на структуру соответствующу разрядности контроллера? ( 8 битам)
говорил я товарищу avreal: стандарт хоть и велик, но не всем понятен, проще надо быть, на вещи смотреть ширше, а к людям - помякше... вот и результат: он вам на моем скорбном примере доказал-рассказал, что такое указатель и с чем его едят... извините, это лирическое отступление...
PtS = (void*)&I;
это указателю PtS присваивается значение адреса переменной I - не более, не менее. а приведение типа этого самого адреса к void* нужно лишь для того, чтобы компилятор не матюкался - отлично сработает и без этого, но с варнингом.
битва с дураками проиграна, победители торжествуют. слава победителям!
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

Да понял , я понял :)))
Не встречал просто конструкцию такую с void...

Он кстати и вот так не ругается

PtS=(unsigned char *)&I; - или это просто масло масленное?

А стандарт на английском, поди разбери чо они там пишут... Даже со знанием инглиша...
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

Сообщение Мастер Ломастер »

demiurg301 писал(а):Он кстати и вот так не ругается
PtS=(unsigned char *)&I; - или это просто масло масленное?
если компилятор видит, что вы переменной типа char* присваиваете значение типа int* - он чувствует здесь подвох: вы ведь имеете указатель на байт, а задаете адрес двух байт. поэтому он делает warning. принудительное приведение к типу char* снимает проблему - теперь компилятор видит два одинаковых типа. а тип void* является универсальным - он СОВМЕСТИМ с любым типом указателя и компилятор никогда не будет на него ругаться, поэтому к void* можно приводить любой указатель.
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
Necroteeth
Потрогал лапой паяльник
Сообщения: 362
Зарегистрирован: Вс окт 10, 2010 17:43:48
Откуда: Воронеж

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

Сообщение Necroteeth »

добрый день!
подскажите, пожалуйста, почему у меня какая-то хрень происходит:

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

#define F_CPU 1000000UL  // óêàçûâàåì ÷àñòîòó â ãåðöàõ
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
volatile int state=0;
volatile int decimal, entier;
int main()
{
   init();
   while(1)
   {
      for (int i=0;i<=20;i++)
      {
         decimal=i/10;
         entier=i%10;
         switch(state)
         {
            case 0:   PORTD=0b00100000;   PORTA=convert(entier);   break;
            case 1:   PORTD=0b01000000;   PORTA=convert(decimal);   break;
         }
         _delay_ms(250);
      }
   
   }
}

//***********************************************************************************
 
ISR(TIMER0_COMP)                     //îáðàáîò÷èê ïðåðûâàíèÿ òàéìåðà0
{
   state=~(state);
}

//***********************************************************************************

int Timer0_prepare()                  //ïðîöåäóðà èíèöèàëèçàöèè òàéìåðà0
{
   TIMSK|=(1<<OCIE0);                  //ðàçðåøèòü ïðåðûâàíèÿ ïî êîìïàðàòîðó òàéìåðà0

   TCCR0|=(1<<WGM00)|(1<<WGM01)|(1<<CS00)|(1<<CS02);//CTC mode, prescaler 1/1024
   TCCR0&=~(1<<CS01);

   OCR0=0b00001010;                  //êîìïàðàòîð íàñòðîåí ñðàáàòûâàòü ðàç â 10ms
   TCNT0=0b00000000;
}


//***********************************************************************************

int convert(int digit)                   //ïðîöåäóðà ïðåîáðàçîâàíèÿ ÷èñëà â ñèãíàë
{                                 //7-ñåãìåòíîãî èíäèêàòîðà
   int result;
   switch (digit)
      {
      case 0:   result=0b11000000; break;

      case 1: result=0b11111001; break;

      case 2: result=0b10100100; break;

      case 3: result=0b10110000; break;

      case 4: result=0b10011001; break;

      case 5: result=0b10010010; break;

      case 6: result=0b10000010; break;

      case 7: result=0b11111000; break;

      case 8: result=0b10000000; break;

      case 9: result=0b10010000; break;
      
      case 10: result=0b01111111; break;
      }
   return result;
}


int init()
{
   DDRA=0b11111111;
   DDRD=0b01100000;
   PORTD=0b00000000;
   Timer0_prepare();
   sei();
}


после входа в функцию convert программа переходит опять в начало функции main и в итоге ничего полезного не делает. где я допустил ошибку?
суть программы в том, чтобы на два индикатора АЛС321Б1 выводить число от 0 до 20. каунтер i должен перебирать число, а переменные decimal и entier хранить значения второго и первого разряда соответственно. текущий включенный индикатор должен определяться состоянием переменной state, которая изменяется (должна изменяться) по прерыванию таймера0.
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

Мастер Ломастер
А можете ещё подсказать по такому вопросу ? :

такой кусок кода :

void func(flash unsigned char *PtF)
{
.......
}

flash unsigned char fstr[]="flash string";

func(fstr);

А нельзя ли сделать как то так :

func("flash string"); - типа как в С++ ?
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

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

Сообщение Мастер Ломастер »

до сего момента все написанные вами куски кода воспринимались, как написанные для WinAVR. так вот, у WinAVR нет ключевого слова flash и вообще, для работы со строками из памяти программ используются совсем другие подходы. Однако, сделать так, как вы написали в конце своего поста, все-таки можно:

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

#include <avr/pgmspace.h>
...
func(PSTR("эта строка будет лежать во flash"));
как поступать для других компиляторов - я не знаю.
битва с дураками проиграна, победители торжествуют. слава победителям!
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

НЕ, я СV сижу, хотя С в нём говорят кривоватый... Но пока устраивает...

Жалко, но СV я таких механизмов не нашёл.
Т.к. эти "простыни" из кучи строковых констант (AT команды и другие протоколы) напрягают. Код не особо читабелен, т.к. команду не задашь явно рядом с её выводом...

Почему в С нет типа string ... :dont_know: :))) Могли б уж изловчится... :))

----------
Только что проверил

Функция вида
unsigned char* B1FIND(flash unsigned char *str,unsigned char time)

B1FIND("PIN: READY",1)
Работает :shock: - У мну когнитивный диссонанс - раньше выдавало ошибку. Правда я версию сменил с 25.5 на 25.9
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Кстати, о константах. «А знаетели вы, что»™
В языке С (но не С++ !) символьная константа вида 'A' имеет тип int, а не char.
И допускаются многосимвольные константы, лишь бы лезло в int.
Например, так

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

 // проверить, являются ли первые два символа str 'A' и 'T' соответственно
unsigned char is_AT(char *str)
{
   // Внимание! Работает только при sizeof(int) == 2
   // задом наперёд, так как левый символ идёт в старший байт, как в числах
   return ((int*)str)[0] == 'TA';
}

Не скажу, что такое нужно часто :-)
Но иногда может заменить отсутствующую в С возможность указывать строки в case

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

   ...
   // Внимание! Работает только при sizeof(int) == 2
   switch( *(int*)str ) {
   case '1H':
      // начало str -> "H1"
   case '0H':
      // начало str -> "H0"
   case '1M':
      // начало str -> "M1"
   }

Чтобы уйти от непереносимости по длине int-а, достаточно

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

   int cmd = (unsigned char)str[0];
   cmd += (unsigned char)str[1] << 8;
   // старшие биты у 32-битного int будут нулевые и тут, и в двухсимвольных константах
   swicth (cmd) {
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
demiurg301
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

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

Сообщение demiurg301 »

avreal писал(а):Кстати, о константах. «А знаетели вы, что»™
В языке С (но не С++ !) символьная константа вида 'A' имеет тип int, а не char.
И допускаются многосимвольные константы, лишь бы лезло в int.
Например, так

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

 // проверить, являются ли первые два символа str 'A' и 'T' соответственно
unsigned char is_AT(char *str)
{
   // Внимание! Работает только при sizeof(int) == 2
   // задом наперёд, так как левый символ идёт в старший байт, как в числах
   return ((int*)str)[0] == 'TA';
}

Не скажу, что такое нужно часто :-)
Но иногда может заменить отсутствующую в С возможность указывать строки в case

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

   ...
   // Внимание! Работает только при sizeof(int) == 2
   switch( *(int*)str ) {
   case '1H':
      // начало str -> "H1"
   case '0H':
      // начало str -> "H0"
   case '1M':
      // начало str -> "M1"
   }

Чтобы уйти от непереносимости по длине int-а, достаточно

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

   int cmd = (unsigned char)str[0];
   cmd += (unsigned char)str[1] << 8;
   // старшие биты у 32-битного int будут нулевые и тут, и в двухсимвольных константах
   swicth (cmd) {


Интересная инфа, вот если бы только не надо было по 10-20 символов обрабатывать, а не по 2 :(

Так вот такая запись func("abcdfk"); (объявление func(flash unsigned char PtF) ; ) - стандартна или это "происки компилятора" и при переходе придётся переделывать?
А в С можно реализовать конкатенацию вида
unsigned char A[]="abcdef"
unsigned char str[100];
str=0x0A+A+'a'+"abv" - или это фантастика? :)))
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Только врукопашную.
Смотрите string.h, функции strcpy, strcat и компанию.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Леонид Иванович
Друг Кота
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск
Контактная информация:

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

Сообщение Леонид Иванович »

avreal писал(а):Кстати, о константах. «А знаетели вы, что»™


Какой ужас!
Всегда с открытым ртом смотрю на людей, которые виртуозно владеют Си. Не понимаю, как им это удаётся. Но ещё больше не понимаю, зачем это нужно. Пользуюсь очень ограниченным подмножеством языка Си, благодаря чему удалось свести на нет такой минус этого языка, как плохая читаемость исходника. Например, места, где я использовал указатели, можно пересчитать по пальцам. И ничего, все задачи решаются.
Ответить

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