беру адрес структуры перемещаюсь на нужный адрес поля (типы полей учитываю,так как у нас все поля одного типа они должны располагаться равномерно) и разименовываю полученный адрес. или такое только с массивами прокатывает?
!!!с кодом выше предидущая ошибка пропала. указатель на структуру было не правильно использовал ща только вот эта Ошибка incompatible types when assigning to type 'typ8' from type 'rtc' ругается вот на это
я вам не рекомендовал бы пока что использовать арифметику указателей, т.к. она, мягко говоря, не совсем очевидна. PtrRTC_struct+1 это совсем не переход на 1-е поле структуры... а переход на первый байт ЗА этой структурой...
для обращения ПОБАЙТНО к памяти, выделенной под структуру, надо использовать указатель на БАЙТ, а не указатель на структуру
для "занесения" структуры в массив байтов используйте функцию memcpy, а не самодельные циклы
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
memmove может копировать без проблем данные между "пересекающимися" областями. в вашем случае такого пересечения нет и не может быть, поэтому лучше memcpy - она быстрее.
ROMan2947 писал(а):
а мне нужно нуе всю структуру заносить, а только допустим 2,3,5 поле, то как быть?
вызов функции трижды для копирования 3 байт - это настолько не банально, что даже и не знаю, что сказать... наверное, это как если вы купите два бревна для того, чтобы выстрогать 2 палочки для суши...
Добавлено after 2 minutes 12 seconds: тем более что в вашем примере вы все три байта из структуры пишите на одно и то же место в массиве. на самом деле все будет куда круче
Так же как и обычный 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);
так никогда и не мог понять, что кроется за этими индейцами, но уверен на 100500%, что размещение данных в x86 точно такое же, как в AVR - первым идет самый младший байт, затем по старшинству... поэтому у вас явная ошибка в разделении
мотороловские процы отличались порядком размещения байтов, 68ххх кажется, и были нюансы в древнейших ЭВМ, о которых, наверное, и вспоминать не стоит...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
И снова непонятки вызываю три функции для чтения данных с ds1307 по очереди. 1-функция считывает время. 2-функция считывает дату. 3-регистр настроек. функция READ_TWR во всех функциях чтения отрабатывает великолепно.считанные данные сохраняются в буфер TWI_buffer затем функцией memcpy нужно данные перенести в структуру PtrRTC_struct.
но я изначально автоматом указатель на структуру в в функции read_Time_RTC для emcpy указал вот так memcpy(&PtrRTC_struct,TWI_buffer,3); в общем картина выглядела:
при такой записи ни одна функция не переносит данные в структуру, стоит только ликвидировать //read_Time_RTC(); // 1 так остальные начинают выполнять свои обязанности.что за чудное явление? как практически независимые функции взаимосвязаны?
надо это зарубить.... а то вечно сомнения появляются как нужно делать..
Но вопрос меня интересует вот какой, почему если я в одной функции неправильно написал, то и остальные перестают работать, хоть в них все верно написано? где их зависимость?
Но вопрос меня интересует вот какой, почему если я в одной функции неправильно написал, то и остальные перестают работать, хоть в них все верно написано? где их зависимость?
Нужно не "зарублять" - а понимать физический смысл происходящих операций над данными. Если функции зависят друг от друга - то известно: мусор на входе -> мусор на выходе. Если в конкретном случае "перестать работать" - несобираемость компилятором из-за того, что типы вдруг перестали совпадать - dura compiler, но это его работа - целостность продукта поддерживать.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
хочу увеличить наглядность алгоритма конечных автоматов. - т.е. весь код запускается циклично по таймеру, и в зависимости от его внутренних флагов выполняются его различные ветви, чтобы код успел выполниться до следующего запуска из него исключаются циклы и задержки, но задержки нужны, их я изначально делал так Спойлер
Код:
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();};
если нужна задержка - выходим и пропустив нужное количество запусков заходим и продолжаем с точки, на которой вышли. Получается не очень наглядно, вот я и пытаюсь сделать этот алгоритм нагляднее: пока вышло такСпойлер
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 - служебные переменные (указатель адреса возврата и счетчик задержки) уже красивее чем было, но до идеала далеко, может, у кого есть варианты поизящней? с удовольствием приму на вооружение
_________________ Для тех, кто не учил магию мир полон физики Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения