Views: 2168
Какие задачи нам позволяют решать структуры и объединения?
Для разработчика встроенных систем эффективность и компактность кода всегда на первом месте. Если программировании на Ассемблере ты сам определяешь как и где располагаются данные, то при программировании на Си надо позаботиться, что бы объяснить компилятору как ты хочешь, что бы данные были расположены. Для чего это надо, в первую очередь, для удобства обработки и обращения к данным.
Например, мне необходимо, чтобы данные были расположены последовательно в памяти. Для этого я опишу структуру, например:
// struct { int16_t s_CLt; // данные в формате 16 байт со знаком int16_t s_tNd; // int16_t s_rEL; // uint8_t s_SEc; // данные в формате 8 байт без знака (только положит значение) uint8_t s_Nin; // unsigned Accident :2; // данные в формате 2 байта без знака (только положит значение) unsigned Freezing :1; // данные в формате 1 байта }EE; // данные подлежащие хранению в еепром //
Это будет гарантировано, что данные в памяти будут расположены последовательно и займут 9 байт (если система процессора микроконтроллера 8 битная) или 6 слов (если 16 битная). Один дополнительный байт будут занимать две переменные описанные как Accident и Freezing, они займут соответственно 0 – 1 байт (Accident ) и 2 байт (Freezing).
Обратиться т.е записывать данные и читать можно таким образом, например:
// // Для записи EE.s_CLt = 4562; EE.Accident = 2; // Для чтения temp = EE.s_CLt; temp1 = EE.s_Nin; //
Со структурами struct все довольно понятно, это расположение данных последовательно в памяти и удобный доступ к ним, особенно, если надо писать какие-то флаги управления и потом данные “скопом” передавать через какой либо интерфейс на другое устройство. Но часто возникает необходимость например иметь представление одних и тех же данных и в виде байта (или слова) и в виде бит. Как это сделать, для этого в Си есть гибкий механизм объединения union.
Например, для передачи данных через последовательный порт нам необходимо иметь доступ к данным ка к байту, а для эффективности управления флагами управления содержащимся в этом байте, и меть доступ как к биту. Вот такой фокус и позволяют делать объединения. Еще раз структуры последовательно располагать данные в памяти, объединения описывать одни и те же данные разными именами и при этом разными типа данными.
Например, мы имеем структуру данных:
// struct { int16_t s_CLt; // данные в формате 16 байт со знаком uint8_t s_SEc; // данные в формате 8 байт без знака (только положит значение) unsigned Accident :2; // данные в формате 2 байта без знака (только положит значение) unsigned Freezing :1; // данные в формате 1 байта }EE; // //
Визуально это выглядит так:
Вся структура занимает 4 байта. EE.s_CLt занимает 2 байта, EE.s_SEc занимает 1 байта, переменные Accident, Freezing (два и и один байт) будут размещены в 4 байте.
Теперь нам, например, необходимо работать с битами переменной s_CLt, можно конечно использовать операциями с битами, например, нам надо контролировать состояние бита 0 в этой переменной мы, можем вычислить так, выполняем побитовое “&” с переменной и в зависимости от состояния операции выполняет если true или falce:
// if(EE.s_CLt & 0b0000000000000001) ******; else *******; //
Но можно каждому биту присвоить свое имя, это улучшает понимание программы и не рисвоать, что нарисовано выше например писать просто так:
// if(EE.FLED1) ******; else *******; //
Где EE.FLED1 мы дали имя биту 0 переменной EE.s_CLt, как это сделать? В нашу структуру надо внедрить объединение. Структуры и объединения можно как угодно комбинировать для всевозможного описания данных в памяти для удобной последующей обработки. В нашем варианте это будет выглядеть так:
// struct { //- union { int16_t s_CLt; // данные в формате 16 байт со знаком struct { unsigned FLED1 :1;// название бита 0 unsigned FLED2 :1;// название бита 1 unsigned FLED3 :1;// название бита 2 //***** }; }; uint8_t s_SEc; // данные в формате 8 байт без знака (только положит значение) unsigned Accident :2; // данные в формате 2 байта без знака (только положит значение) unsigned Freezing :1; // данные в формате 1 байта }EE; // //
Переменную s_CLt мы помещаем, в обеднение в котором находиться эта переменная и новая внутренняя структура. Название ни объединению, ни структуре мы не даем. В этом варианте мы сможет обращаясь, например, к EE.FLED1 контролируя или изменяя состояние бита 0 переменной EE.s_CLt.
Как это выглядит визуально.
Еще раз к пониманию структур, это возможность “объяснения” компилятору, что данные надо расположить в памяти последовательно. А к пониманию объединений, что данные одни и те же могут иметь разное название. Надеюсь я смог “на пальцах” объяснить эти гибкие особенности Си.
И для окончания, например, мне необходимо обработать эти 4 байка как одно 32 битное слово, как это сделать? Это сделать просто если нашу структур поместить в объединение и добавит в ней нашу 32 битную переменную:
union { struct { //- union { int16_t s_CLt; // данные в формате 16 байт со знаком struct { unsigned FLED1 :1;// название бита 0 unsigned FLED2 :1;// название бита 1 unsigned FLED3 :1;// название бита 2 //***** }; }; uint8_t s_SEc; // данные в формате 8 байт без знака (только положит значение) unsigned Accident :2; // данные в формате 2 байта без знака (только положит значение) unsigned Freezing :1; // данные в формате 1 байта }; uint16_t s_32bit; // в ней все наши биты }EE; //
Теперь при необходимости можно обратиться к переменной EE.s_32bit и получить все данные или изменить одной операцией.
Визуально это можно представить так:
Файлы для загрузки
Просто о структурах и объединениях в Си 343.32 KB 165 downloads
Проект с примером организации данных ...Это может быть интересно
- Гаджеты для домашней автоматики – Датчик приближенияViews: 1972 Управление светодиодным освещением – Датчик приближения. Данный гаджет предназначен для управления внутренним освещением мебели. Датчик позволяет определить закрытие или открытие дверцы или ящика и при этом включать или …
- Бегущие огни (ch-bo-36)Views: 2432 Проект на PIC-микроконтроллере PIC16F648A. Количество каналов 36. Для индикации используется подключение по матрице 6х6. Расположение светодиодов в одну линию. Все эффекты написаны для возможности увеличения количества светодиодов. Рекомендуется …
- Счетчики посетителейViews: 1268 Вас сосчитали!? или счетчики посетителей. Для чего нужны счетчики посетителей? Какие они бывают? ТОРГОВЛЯ. Подсчитайте, сколько ваш магазин посещает человек за день. Кок много человек приходит утром, какое …
- Просто о внешних переменныхViews: 788 Часто возникает задача когда необходимо предавать данные между модулями программы. Например, передать данные между файлами, или управлять работой модулей. Для этого создаем заголовочный файл и описываем наши переменные как …
- Проект с использованием MCC часть 15Views: 1516 EUSART – Универсальный асинхронный приёмопередатчик (УАПП, англ. Universal Asynchronous Receiver-Transmitter, UART) — узел вычислительных устройств, предназначенный для организации связи с другими цифровыми устройствами. … читать на вики. Внесем изменения в нашу схему, …
- Проект с использованием MCC часть 14Views: 828 С выводом данных на дисплей мы справились (но могу сразу сказать библиотеку графики к этой статьи пришлось доработать, поэтому в этом проекте она обновлена). У нас на текущем …
- 12-BIT A/D CONVERTER WITH THRESHOLD DETECT на примере PIC24FJ128GA204Views: 825 Введение. 12-битный модуль A/D Converter является усовершенствованной версией 10-битного модуля, предлагаемого на некоторых устройствах PIC24. Оба модуля являются преобразователями, в своих ядрах, с последовательным приближением (SAR), в окружении …
- Мультизоновый индикатор-терморегулятор ch-c3010Views: 1167 Часто возникает необходимость получить информацию по температуре с множества точек контроля. Вам необходимо знать температуру в комнате, в коридоре, температуру на улице, а в погребе (или на балконе) …
- Дисплей KD035C-3A подключение и управлениеViews: 701 Дисплей KD035C-3A производиться компанией SHENZHEN STARTEK ELECTRONIC TECHNOLOGY CO.,LTD Характеристики Параметр Спецификация Единицы измерения Размер дисплея 70.08(H)*52.56(V) (3.5inch) mm Тип дисплея TFT active matrix Цветовая гамма 65K/262K colors Разрешение …
- Development board based on MCU PIC18F47Q84Views: 1014 PIC18F47Q84 Microcontroller Family with CAN Flexible Data Status: In Production.