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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

[uquote="ARV",url="/forum/viewtopic.php?p=3342565#p3342565"]не понял, какие типы переменных у вас.[/uquote]

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

typedef uint8_t typ8;
typedef struct 
{
	typ8 secund;
	typ8 minut;
	typ8 hour;
	typ8 den_nedeli;
	typ8 chislo;
	typ8 mecyac;
	typ8 yahr;
	typ8 status_registr;
}rtc;
rtc *PtrRTC_struct;
rtc RTC_struct={0};
rtc *PtrRTC_struct=&RTC_struct;
typ8 TWI_buffer[8]={0};

[uquote="ARV",url="/forum/viewtopic.php?p=3342565#p3342565"]не увидел доступа к полю структуры...[/uquote] вот таким образом решил получить доступ

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

*(PtrRTC_struct+i);
беру адрес структуры перемещаюсь на нужный адрес поля (типы полей учитываю,так как у нас все поля одного типа они должны располагаться равномерно) и разименовываю полученный адрес. или такое только с массивами прокатывает?

!!!с кодом выше предидущая ошибка пропала. указатель на структуру было не правильно использовал
ща только вот эта Ошибка incompatible types when assigning to type 'typ8' from type 'rtc'
ругается вот на это

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

TWI_buffer[i]=*(PtrRTC_struct+i);
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

я вам не рекомендовал бы пока что использовать арифметику указателей, т.к. она, мягко говоря, не совсем очевидна.
PtrRTC_struct+1 это совсем не переход на 1-е поле структуры... а переход на первый байт ЗА этой структурой...

для обращения ПОБАЙТНО к памяти, выделенной под структуру, надо использовать указатель на БАЙТ, а не указатель на структуру

для "занесения" структуры в массив байтов используйте функцию memcpy, а не самодельные циклы
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

[uquote="ARV",url="/forum/viewtopic.php?p=3342583#p3342583"]я вам не рекомендовал бы[/uquote]
понял :write:
[uquote="ARV",url="/forum/viewtopic.php?p=3342583#p3342583"]надо использовать указатель на БАЙТ[/uquote] как получить этот указатель можно?или сначала в массив , а потом работать с эти массивом?

Добавлено after 6 minutes 27 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3342583#p3342583"]memcpy[/uquote]это же то, что мне и нужно!!! :beer: :music:

хотя пишут memmove "безопаснее" :roll:

Добавлено after 14 minutes 43 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3342583#p3342583"]для "занесения" структуры в массив[/uquote] а мне нужно нуе всю структуру заносить, а только допустим 2,3,5 поле, то как быть? пока предполагаю два раза использовать функцию?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

ROMan2947 писал(а):как получить этот указатель можно?

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

uint8_t *u8_ptr = (void*)&RTC_struct;
ROMan2947 писал(а):хотя пишут memmove "безопаснее"
memmove может копировать без проблем данные между "пересекающимися" областями. в вашем случае такого пересечения нет и не может быть, поэтому лучше memcpy - она быстрее.
ROMan2947 писал(а):а мне нужно нуе всю структуру заносить, а только допустим 2,3,5 поле, то как быть?

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

TWI_bufferх[0] = RTC_struct.minut;
TWI_bufferх[1] = RTC_struct.chislo;
TWI_bufferх[2] = RTC_struct.yahr;
P.S. ужас-то какой у вас в идентификаторах творится... там и английский, там и транслит... там и помесь заглавных с прописными... нечитаемый код будет
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

[uquote="ARV",url="/forum/viewtopic.php?p=3342604#p3342604"]....[/uquote]огромное спасибо!!!! :)
[uquote="ARV",url="/forum/viewtopic.php?p=3342604#p3342604"]ужас-то какой[/uquote] :oops:

Добавлено after 7 minutes 22 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3342604#p3342604"]

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

TWI_bufferх[0] = RTC_struct.minut;
TWI_bufferх[1] = RTC_struct.chislo;
TWI_bufferх[2] = RTC_struct.yahr;
[/uquote]

по-вашему запись понятна!это круто,но по-мне это банально.
а если так:

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


 memcpy(TWI_buffer,&(PtrRTC_struct->minut),1);
 memcpy(TWI_buffer,&(PtrRTC_struct->chislo),1);
 memcpy(TWI_buffer,&(PtrRTC_struct->yahr),1);

:tea:

Добавлено after 1 minute 47 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3342604#p3342604"]

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

uint8_t *u8_ptr = (void*)&RTC_struct;
[/uquote]
это что-то новое :shock:

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

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

Сообщение ARV »

ROMan2947 писал(а):это круто,но по-мне это банально.
вам шашечки, или ехать?

вызов функции трижды для копирования 3 байт - это настолько не банально, что даже и не знаю, что сказать... наверное, это как если вы купите два бревна для того, чтобы выстрогать 2 палочки для суши...

Добавлено after 2 minutes 12 seconds:
тем более что в вашем примере вы все три байта из структуры пишите на одно и то же место в массиве. на самом деле все будет куда круче

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

memcpy(&TWI_buffer[0],&(PtrRTC_struct->minut),1);
 memcpy(&TWI_buffer[1],&(PtrRTC_struct->chislo),1);
 memcpy(&TWI_buffer[2],&(PtrRTC_struct->yahr),1);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

[uquote="ARV",url="/forum/viewtopic.php?p=3342616#p3342616"]купите два бревна для ...[/uquote] конкретно для этого
случая сравнение у Вас точное :)))

[uquote="ARV",url="/forum/viewtopic.php?p=3342616#p3342616"]в вашем примере вы...[/uquote]мне вот любопытно сколько Гб или Тб кода нужно написать, чтоб не делать такие детские ошибки :oops: :facepalm:
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Ещё можно было бы union использовать:

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

typedef union
{
    struct {
        typ8 secund;
        typ8 minut;
        typ8 hour;
        typ8 den_nedeli;
        typ8 chislo;
        typ8 mecyac;
        typ8 yahr;
        typ8 status_registr;
    };
    typ8 buf[8];
}rtc;
Тогда обращение RTC_struct.minut и RTC_struc.buf[1] будет, по сути, одним и тем же. Памяти эта структура занимать больше не будет, естественно.
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3342626#p3342626"]Ещё можно было бы union использовать:[/uquote] Благодарю,но пока ни разу не пользовал union, туманное представление как с ним работать. будем разбираться как это штука работает. :tea:
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Так же как и обычный struct, только все перечисленные элементы лежат в одной области памяти. Запись в одну из переменных, соответственно, затрагивает все их.

Кстати, это ещё часто бывает удобно для перевода двухбайтовых переменных в однобайтовые.

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

typedef union {
    struct {
        uint8_t a;
        uint8_t b
    };
    uint16_t w;
} Test;

Test t;

t.a = 0x23;
t.b = 0x5A;
Теперь в test.w лежит число 0x5A23;

(тут, конечно нужно учитывать архитектуру - LittleEndian (AVR/ARM(обычно)) и BigEndian (x86). Во втором случае в test.w будет лежать 0x235A

Иногда так проще, чем делать что-то вроде a = (w & 0xFF00) >> 8; b = (w & 0x00FF);
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

WiseLord писал(а):LittleEndian (AVR/ARM(обычно)) и BigEndian (x86)
так никогда и не мог понять, что кроется за этими индейцами, но уверен на 100500%, что размещение данных в x86 точно такое же, как в AVR - первым идет самый младший байт, затем по старшинству... поэтому у вас явная ошибка в разделении

мотороловские процы отличались порядком размещения байтов, 68ххх кажется, и были нюансы в древнейших ЭВМ, о которых, наверное, и вспоминать не стоит...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Да, с x86 я, похоже, ошибся.
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

И снова непонятки :write: вызываю три функции для чтения данных с ds1307 по очереди.
1-функция считывает время.
2-функция считывает дату.
3-регистр настроек.
функция READ_TWR во всех функциях чтения отрабатывает великолепно.считанные данные сохраняются в буфер TWI_buffer
затем функцией memcpy нужно данные перенести в структуру PtrRTC_struct.

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

read_Time_RTC();  // 1		
read_Data_RTC();  // 2		
read_status_RTC();// 3
при таком раскладе все ништяг. все данные по порядку переносятся в структуру.

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

void read_Time_RTC(void)
{
	READ_TWR(ADDRESS_RTC,0x00,3);
	memcpy(PtrRTC_struct,TWI_buffer,3);
}
void read_Data_RTC(void)
{
	READ_TWR(ADDRESS_RTC,0x03,4);
	memcpy(&(PtrRTC_struct->den_nedeli),TWI_buffer,4);
}
void read_status_RTC(void)
{
    READ_TWR(ADDRESS_RTC,0x07,1);
	memcpy(&(PtrRTC_struct->status_registr),TWI_buffer,1);
}
но я изначально автоматом указатель на структуру в в функции read_Time_RTC для emcpy указал вот так
memcpy(&PtrRTC_struct,TWI_buffer,3);
в общем картина выглядела:

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

void read_Time_RTC(void)
{
	READ_TWR(ADDRESS_RTC,0x00,3);
	memcpy(&PtrRTC_struct,TWI_buffer,3);
}
void read_Data_RTC(void)
{
	READ_TWR(ADDRESS_RTC,0x03,4);
	memcpy(&(PtrRTC_struct->den_nedeli),TWI_buffer,4);
}
void read_status_RTC(void)
{
    READ_TWR(ADDRESS_RTC,0x07,1);
	memcpy(&(PtrRTC_struct->status_registr),TWI_buffer,1);
}
при такой записи ни одна функция не переносит данные в структуру, стоит только ликвидировать //read_Time_RTC(); // 1 так остальные начинают выполнять свои обязанности.что за чудное явление? как практически независимые функции взаимосвязаны?
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Судя по "->", PtrRTC_struct - это указатель. на структуру, поэтому в memcpy его нужно без & передавать. Всё нормально.

P.S. А status_registr, например, это уже поле структуры, поэтому его адрес - уже нужно с амперсандом.
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3343080#p3343080"]это указатель.[/uquote]
да это указатель

[uquote="WiseLord",url="/forum/viewtopic.php?p=3343080#p3343080"]уже поле структуры[/uquote]надо это зарубить.... :write: а то вечно сомнения появляются как нужно делать..

Но вопрос меня интересует вот какой, почему если я в одной функции неправильно написал, то и остальные перестают работать, хоть в них все верно написано? где их зависимость?
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

[uquote="ARV",url="/forum/viewtopic.php?p=3342760#p3342760"]так никогда и не мог понять, что кроется за этими индейцами[/uquote]
Не англосаксы мы - бэкграунд не тот. То не индейцы, а "тупоконечники" и "остроконечники" из известного у них литературного произведения. ;-)

Добавлено after 13 minutes 58 seconds:
[uquote="ROMan2947",url="/forum/viewtopic.php?p=3343099#p3343099"]Но вопрос меня интересует вот какой, почему если я в одной функции неправильно написал, то и остальные перестают работать, хоть в них все верно написано? где их зависимость?[/uquote]
Нужно не "зарублять" - а понимать физический смысл происходящих операций над данными. Если функции зависят друг от друга - то известно: мусор на входе -> мусор на выходе. Если в конкретном случае "перестать работать" - несобираемость компилятором из-за того, что типы вдруг перестали совпадать - dura compiler, но это его работа - целостность продукта поддерживать.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Аватара пользователя
da-nie
Говорящий с текстолитом
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.
Контактная информация:

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

Сообщение da-nie »

из известного у них литературного произведения.
Которое знаем и мы. "Путешествия Гулливера". :)
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

[uquote="Siarzhuk",url="/forum/viewtopic.php?p=3343204#p3343204"]Нужно не "зарублять" - а понимать физический смысл происходящих операций над данными.[/uquote]это точно!!!
:beer:
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

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

Сообщение Ivanoff-iv »

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

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

void GetTemp(void)
 {
 static   unsigned int StepGetTemp = 0;     
 static   unsigned char TermH, TermL;
 switch (StepGetTemp) 
  {    /*DelyGetTemp=750*Speed_temp;*/   case 0:              //это разделители, чтобы подпрограмма не выполнялась слишком долго, а перезапускалась и при перезапуске продолжалась с места остановки
   DS18B20_init();                                            // Инициализация DS18B20    
  StepGetTemp=1; DelyGetTemp=0;   break; case 1:                                              
   write_18b20(0xCC);                                         // Проверка кода датчика
  StepGetTemp=2; DelyGetTemp=0;   break; case 2: 
   write_18b20(0x44);                                         // Запуск температурного преобразования
  StepGetTemp=3; DelyGetTemp=850*Speed_temp; break; case 3:   // Пауза >750 мс
   DS18B20_init();                                            // Инициализация DS18B20
  StepGetTemp=4; DelyGetTemp=0;   break; case 4:                                           
   write_18b20(0xCC);                                         // Проверка кода датчика
  StepGetTemp=5; DelyGetTemp=0;   break; case 5: 
   write_18b20(0xBE);                                         // Считываем содержимое ОЗУ
  StepGetTemp=6; DelyGetTemp=0;   break; case 6: 
   TermL = read_18b20();                                      // Читаем младший байт блокнота
  StepGetTemp=7; DelyGetTemp=0;   break; case 7: 
   TermH = read_18b20();                                      // Читаем старший байт блокнота      
  StepGetTemp=8; DelyGetTemp=0;   break; case 8:
   //if (Term<0) Term=(-Term)|0x80;                             //Выворачиваем температуру для вывода на экран.
    Temperature=(((TermH<<8)+TermL)*10)>>4; 
    if (OK_Flag != 0) {Temperature = -2000; Count=0;};   
    Count+=(~Count)? 1:0;                                    //это моё- счет правильныхъ измерений - для исключения ложных переключений компрессора
  default: StepGetTemp=0;
 DelyGetTemp=1000*Speed_temp;                                //задержка перед следующим измерением 1сек
  };                                                           
 }

//и в коде циклично выполняется
if (DelyGetTemp){DelyGetTemp--;}else{GetTemp();};
если нужна задержка - выходим и пропустив нужное количество запусков заходим и продолжаем с точки, на которой вышли. Получается не очень наглядно,
вот я и пытаюсь сделать этот алгоритм нагляднее: пока вышло так
Спойлер

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

#define DelayCoeff 4.096   //количество вызовов за миллисекунду
#define StartDelay(x,t)  if (t) {(t)--;} else {switch (x){case 0: 
#define Delay(num,te,x,t)  (x)=(num); (t)=(te)*DelayCoeff; break; case(num):
#define EndDelay(te,x,t) (t)=(te)*DelayCoeff; default: (x)=0;};};


void GetTemp(void)
 {
 static   unsigned int StepGetTemp = 0;     
 static   unsigned char TermH, TermL;
 StartDelay(StepGetTemp,DelyGetTemp)                          //это разделители, чтобы подпрограмма не выполнялась слишком долго, а перезапускалась и при перезапуске продолжалась с места остановки
   DS18B20_init();                                            // Инициализация DS18B20    
  Delay(1,0,StepGetTemp,DelyGetTemp)                                              
   write_18b20(0xCC);                                         // Проверка кода датчика
  Delay(2,0,StepGetTemp,DelyGetTemp)
   write_18b20(0x44);                                         // Запуск температурного преобразования                                         
  Delay(3,850,StepGetTemp,DelyGetTemp)                        // Пауза >750 мс
   DS18B20_init();                                            // Инициализация DS18B20
  Delay(4,0,StepGetTemp,DelyGetTemp)                                           
   write_18b20(0xCC);                                         // Проверка кода датчика
  Delay(5,0,StepGetTemp,DelyGetTemp) 
   write_18b20(0xBE);                                         // Считываем содержимое ОЗУ
  Delay(6,0,StepGetTemp,DelyGetTemp)
   TermL = read_18b20();                                      // Читаем младший байт блокнота
  Delay(7,0,StepGetTemp,DelyGetTemp)
   TermH = read_18b20();                                      // Читаем старший байт блокнота      
  Delay(8,0,StepGetTemp,DelyGetTemp)
   //if (Term<0) Term=(-Term)|0x80;                             //Выворачиваем температуру для вывода на экран.    
    Temperature=(((TermH<<8)+TermL)*10)>>4; 
    if (OK_Flag != 0) {Temperature = -2000; Count=0;};   
    Count+=(~Count)? 1:0;                                    //это моё- счет правильныхъ измерений - для исключения ложных переключений компрессора
  EndDelay(1000,StepGetTemp,DelyGetTemp)                     //задержка перед следующим измерением 1сек
  };                                                           
 }
 
 //и в коде циклично выполняется
GetTemp();
в дефайнах подстановка:
num- номер задержки по порядку (числовая константа)
te- время задержки (числовая константа)
x и t - служебные переменные (указатель адреса возврата и счетчик задержки)
уже красивее чем было, но до идеала далеко, может, у кого есть варианты поизящней? с удовольствием приму на вооружение :)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Ivanoff-iv писал(а):если нужна задержка - выходим и пропустив нужное количество запусков заходим и продолжаем с точки, на которой вышли.
Вы изобретаете велосипед. Возьмите ОСРВ, она сама всё за Вас сделает.

PS: Если Вы уже дошли до подобных алгоритмов - самое время начать юзать ОСРВ. Потом, как говорится - "за уши не оттащишь" :)
Ответить

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