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

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

Сообщение ROMan2947 »

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

Сообщение 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
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

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

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

Сообщение WiseLord »

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

Сообщение 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 так остальные начинают выполнять свои обязанности.что за чудное явление? как практически независимые функции взаимосвязаны?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

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

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

Сообщение ROMan2947 »

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

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

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

Сообщение 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! ;-)
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

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

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

Сообщение ROMan2947 »

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

Сообщение 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 - служебные переменные (указатель адреса возврата и счетчик задержки)
уже красивее чем было, но до идеала далеко, может, у кого есть варианты поизящней? с удовольствием приму на вооружение :)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

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

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

PS: Если Вы уже дошли до подобных алгоритмов - самое время начать юзать ОСРВ. Потом, как говорится - "за уши не оттащишь" :)
Друг Кота
Аватара пользователя
Сообщения: 7083
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

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

Чувствую необходимость качественного шага - пошел изучать этот ОСРВ...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Аlex писал(а):Потом, как говорится - "за уши не оттащишь"
я несколько раз честно пытался... но никак не мог убедить себя, что мои усилия действительно принесут мне какие-то бонусы. серьёзного и спокойного обсуждения на форуме по этому вопросу вести невозможно, а личной мотивации не хватает. но, конечно, и до такого, как Ivanoff-iv натворил, я тоже не доходил.

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

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

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

Все мы когда то обходились без крутейших автоматов состояния и ОСей. Но стоит её попробовать и немного с ней поработать, начинаешь ощущать все её прелести.
Сложно всё плюсы описать словами, это нужно испытать на собственной шкуре.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Аlex писал(а):Сложно всё плюсы описать словами, это нужно испытать на собственной шкуре
ну примерно я это и имел ввиду... собственная шкура, почему-то, никак не хочет ничего испытывать.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 7083
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

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

мне уже доводилось работать с диспетчером задач в ассемблере (точнее в АлгоритмБилдере) - согласен изящная штучка, вот и подумал что в С должно быть чтото ещё интереснее. застрял пока на приведенном выше уровне - сам диспетчер подзадач вызывается таймером обычно это всё это связано с дин. индикацией семисегментника - от неё и тактируется, и делитель берётся тоже зависимый от номера включенного в данный момент разряда. удобно сканировать привязанную к анодам (катодам) клавиатуру, или производить другие не сильно критичные ко времени подзадачи - время сна процессора при таком "раскладе" часто доходит до 80% и более и при этом не наблюдается никаких тормозов интерфейсов.

Добавлено after 1 minute 11 seconds:
ARV писал(а):собственная шкура, почему-то, никак не хочет ничего испытывать.
это точно, шкура - она такая...

Добавлено after 4 minutes 38 seconds:
Аlex, а не подскажете, может есть какая не слишком замудреная чтобы начать...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Ivanoff-iv писал(а):время сна процессора при таком "раскладе" часто доходит до 80% и более и при этом не наблюдается никаких тормозов интерфейсов.
если цель заключается в облегчении тяжкой жизни микроконтроллерного ядра, то да, это важно. а если цель облегчить себе жизнь, то я так и не понял для себя, как это сделать без усложнения своей жизни...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 7083
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

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

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

Добавлено after 3 minutes 50 seconds:
ARV писал(а):почему-то у меня почти всегда все получается гораздо проще
у меня тоже обычно проще, но, каждый раз приходится чегото придумывать... хочу стройный и универсальный шаблон, чтобы таскать его из задачи в задачу как Ваш настройщик семисегментника...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

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

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3345260#p3345260"]Аlex, а не подскажете, может есть какая не слишком замудреная чтобы начать...[/uquote]
Я сам начинал с OSA и всегда начинающим её советую. Но всё зависит от компилятора, она не все поддерживает.
Ответить

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