Views: 2392
Какие задачи нам позволяют решать структуры и объединения?
Для разработчика встроенных систем эффективность и компактность кода всегда на первом месте. Если программировании на Ассемблере ты сам определяешь как и где располагаются данные, то при программировании на Си надо позаботиться, что бы объяснить компилятору как ты хочешь, что бы данные были расположены. Для чего это надо, в первую очередь, для удобства обработки и обращения к данным.
Например, мне необходимо, чтобы данные были расположены последовательно в памяти. Для этого я опишу структуру, например:
//
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: 951 Часто возникает задача когда необходимо предавать данные между модулями программы. Например, передать данные между файлами, или управлять работой модулей. Для этого создаем заголовочный файл и описываем наши переменные как …
VU Meter Tower ART – part 2Views: 1241 Проект – VU Meter Tower ART получил продолжение в своем развитии. Теперь можно заказать набор деталей из акрила для самостоятельной сборки. В проект корпуса внесено целый ряд доработок, …
Простой сенсорный регулятор светаViews: 2518 Простой сенсорный регулятор. Проект – 2007 года. Регулятор выполнена на микроконтроллере PIC12F683 и имеет минимальное количество элементов. Выполняет стандартные функции, включение выключение света, изменение яркости, запоминание последнего установленного уровня …
Стабилизатор тока для светодиодов SN3350Views: 2819 SN3350 ближайший аналог ZXLD1350 Как собрать готовый вариант, читайте во второй части – http://catcatcat.d-lan.dp.ua/stabilizator-toka-na-sn3350-chast-2/ 40V драйвер светодиодов с внутренним ключом SN3350 – импульсный понижающий преобразователь, разработанный для того, чтобы эффективно управлять одним или …
Проект с использованием MCC часть 11Views: 1034 Можно несколько облагородить программу вынести наши процедуры обработки нажатия кнопок в отдельные функции. Но вы должны понимать, что это хоть и не значительно, но будет тормозить общую скорость …
Ссылки на интересные источникиViews: 994 Сбор 3D моделей от André L’Hérault конденсаторы, резисторы, индуктивности dropbox IPC-SM-782 Surface Mount Design and Land Pattern Standard Видео уроки по Altium designer Alexey Sabunin https://www.youtube.com/channel/UCG7N5CqXpyK8nQjr1EmMgng Сергей Булавинов https://www.youtube.com/channel/UCISAMXRnN_Qw9UTjUwZI1Jw Robert Feranec https://www.youtube.com/user/matarofe …
Стабилизатор тока на SN3350, часть 2Views: 1367 Если вам необходимо разработать устройство с применением мощных светодиодов, то никак не обойтись без применения стабилизатора тока. На настоящий момент стабилизаторы тока являются самым эффективным механизмом, для питания светодиода в течение всего …
Стробоскоп для автомобиляViews: 2255 Одним из популярных решений светового тюнинга автомобиля, мотоцикла или скутера стал эффект – “полицейский стробоскоп“. На база платы ch-c0050 реализовано несколько проектов. В этой статье приводятся две версии …
Проблемы классической светомузыкиViews: 2200 Светомузыка – что это такое? Определение: Светомузыка (жаргонное: цветомузыка) — вид искусства, основанный на способности человека ассоциировать звуковые ощущения со световыми восприятиями. Такое явление в неврологии получило название …
AD9833 – Programmable Waveform Generator – part twoViews: 1973 Прошло время и появилась тема, что-бы закончить проект AD9833 – Programmable Waveform Generator. Приехали печатные платы. В этот раз я печатные платы заказывал в https://jlcpcb.com/ делал это в …


