Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Битовые области в WinAVR
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
MaxiMuz
Обычно для управления отдельными битами и их проверкой используют конcтрукции:
Код
...
#define bOne 0x01;

uint8_t Bfield;

int main (void)
{
...
Bfield |= (1<<bOne); // установка в 1 бита
...
Bfield &= ~(1<<bOne); // установка в 0 бита
...
if ( Bfield & bOne ) // проверка на 1
{ ... }
}

Есть ли возможность с помощью определения структуры и задания полей задавать битовые области ?
Сейчас к сожалению нет возможности попробывать работоспособность этого в железе поэтому привожу пример:
Код
...
struct Bfield
{
  bit bOne:1;
  bit bTwo:1;
  bit bFree:1;
};

int main (void)
{
...
Bfield.bOne=1; // установка в 1 бита
...
Bfield.bTwo=0; // установка в 0 бита
...
if ( Bfield.bFree==1 ) // проверка на 1
{ ... }

Палыч
Цитата(MaxiMuz @ Nov 3 2011, 12:15) *
Есть ли возможность с помощью определения структуры и задания полей задавать битовые области ?

Такая возможность есть (только с типом bit Вы погорячились).
MaxiMuz
Цитата(Палыч @ Nov 3 2011, 11:29) *
(только с типом bit Вы погорячились).

в книге единственного автора книги описывающий синтаксис языка Си для WinAVR Ю.А.Шпак "Программирование на языке C для AVRи PIC микроконтроллеров" на стр.111 описывется тип данных bit для описания бита
XVR
Цитата(MaxiMuz @ Nov 3 2011, 13:57) *
в книге единственного автора книги описывающий синтаксис языка Си для WinAVR Ю.А.Шпак "Программирование на языке C для AVRи PIC микроконтроллеров" на стр.111 описывется тип данных bit для описания бита

Да, для отдельной переменной, типа bit. В составе битовых полей в структуре это смысла не имеет.
MaxiMuz
а что делать ?
XVR
Цитата(MaxiMuz @ Nov 3 2011, 17:57) *
а что делать ?

Писать char
Код
struct Bfield
{
  char bOne:1;
  char bTwo:1;
  char bFree:1;
};
MaxiMuz
Цитата(XVR @ Nov 3 2011, 17:10) *
Писать char
Код
struct Bfield
{
  char bOne:1;
  char bTwo:1;
  char bFree:1;
};

тогда получиться что битовое поле будет занимать 1 байт ?
Sergey_Aleksandrovi4
Цитата(MaxiMuz @ Nov 4 2011, 13:22) *
тогда получиться что битовое поле будет занимать 1 байт ?

Нет, т.к. 3 битовых поля упакуются в одну переменную указанного типа (в Вашем случае 8-битный char). Вот была совсем недавно тема (хоть в названии значится IAR, но справедливо для всех Си-компиляторов) http://electronix.ru/forum/index.php?showtopic=83920
UPD Возможно назову вещи не совсем правильно, но в общем случае битовое поле - это всего лишь средство языка облегчающее труд программиста. А на выходе после компиляции получим те же операции побитовых И и ИЛИ (что в первом посте этой темы).
demiurg_spb
Цитата(MaxiMuz @ Nov 4 2011, 12:22) *
тогда получиться что битовое поле будет занимать 1 байт ?
Да. Пока количество бит в поле не превысит 8-ми штук.
Вместо char предпочтительнее всё же использовать uint_fast8_t или uint8_t или unsigned char.
Вообще по классике (в вашем диалекте) битовые поля объявляют так:
Код
struct Bfield
{
   unsigned bOne:1;
   unsigned bTwo:1;
   unsigned bFree:1;
};
Sergey_Aleksandrovi4
Цитата(MaxiMuz @ Nov 4 2011, 13:22) *
тогда получиться что битовое поле будет занимать 1 байт ?


Цитата(Sergey_Aleksandrovi4 @ Nov 7 2011, 14:11) *
Нет.

Цитата(demiurg_spb @ Nov 7 2011, 14:51) *
Да.


Тогда я ничего не понимаю. Что есть битовое поле? Это структура вида
Код
struct Bfield
{
   unsigned chdr bOne:1;
   unsigned chdr bTwo:1;
   unsigned chdr bFree:1;
};

или это запись вида
Код
   unsigned chdr bOne:1;

внутри структуры?

А будет ли легитимна конструкция, когда в структуру помимо (?)битовых полей(?) запаковываются переменные?
Код
struct Bfield
{
   unsigned chdr bOne:1;
   unsigned chdr bTwo:1;
   unsigned chdr bFree:1;
   int Var1;
   unsigned char Arr[3];
   float Var2;
};
_Артём_
Цитата(Sergey_Aleksandrovi4 @ Nov 7 2011, 19:58) *
А будет ли легитимна конструкция, когда в структуру помимо (?)битовых полей(?) запаковываются переменные?
Код
struct Bfield
{
   unsigned chdr bOne:1;
   unsigned chdr bTwo:1;
   unsigned chdr bFree:1;
   int Var1;
   unsigned char Arr[3];
   float Var2;
};


Должна быть легетимна.
Проверял на IAR, MSVC++ и других.
demiurg_spb
Цитата(Sergey_Aleksandrovi4 @ Nov 7 2011, 20:58) *
Что есть битовое поле? Это структура...
Да. За одним маленьким исключением - нет способа взять адрес поля структуры являющегося битовым полем (offsetof не канает).
Оно должно быть понятно, ибо минимальная адресуемая величина - байт.
MaxiMuz
В WinAVR (20080610) пишу:
Код
#include <avr/io.h>
#include <inttypes.h>

#define  KeyMask (1<<Btn1)|(1<<Btn2)

struct Bfield
{
  char One : 1;
  char bTwo : 1;
  char bFree : 1;
};

int main (void)
{
Bfield.bTwo=1;
Bfield.bOne=0;
if (~(PINB)&(KeyMask))
        {
        PORTB=KeyMask;
        }
}

Вместо char пробывал и unsigned char и unsigned int8_t и просто unsigned
В итоге ошибка:
Код
test.c:27: error: 'Bfield' undeclared (first use in this function)
test.c:27: error: (Each undeclared identifier is reported only once
test.c:27: error: for each function it appears in.)

Что я не так делаю ?
Сергей Борщ
QUOTE (MaxiMuz @ Nov 9 2011, 13:13) *
Что я не так делаю ?
Вы объявили тип Bfield, но не переменную этого типа.
CODE
struct
{
  char One : 1;
  char bTwo : 1;
  char bFree : 1;
}  Bfield;
Вот так будет работать.
MaxiMuz
Цитата(Сергей Борщ @ Nov 9 2011, 13:24) *
Вы объявили тип Bfield, но не переменную этого типа.
Код
struct
{
  char One : 1;
  char bTwo : 1;
  char bFree : 1;
}  Bfield;
Вот так будет работать.

Работает, Спасибо ! Получается что в книге Шпак Ю.А. описание структур неполное sad.gif
Кстати , а как теперь сделать так чтобы битовая область находилась в регистре МК как глобальная переменная ?
demiurg_spb
Скачайте WinAVR да посмотрите заголовочные файлы любой XMega
а также любой тулчейн для ARM и в нём заголовочные файлы любого контроллера.
Так и сможете понять два применяемых там метода (с разименованными указателями и нет).
CODE
typedef struct ADC_struct /* Analog-to-Digital Converter */
{
register8_t CTRLA; /* Control Register A */
register8_t CTRLB; /* Control Register B */
...
ADC_CH_t CH2; /* ADC Channel 2 */
ADC_CH_t CH3; /* ADC Channel 3 */
} ADC_t;

#define ADCA (*(ADC_t *) 0x0200) /* Analog to Digital Converter A */
#define ADCB (*(ADC_t *) 0x0240) /* Analog to Digital Converter B */
Палыч
Цитата(MaxiMuz @ Nov 9 2011, 16:31) *
как теперь сделать так чтобы битовая область находилась в регистре МК как глобальная переменная ?

О каком регистре идёт речь? General Purpose Working Register? Тогда как-то так:
Код
register struct
{
  char One : 1;
  char bTwo : 1;
  char bFree : 1;
}  Bfield   asm ("r6");
MaxiMuz
Спасибо Палыч , работает sm.gif
MaxiMuz
Решил не создавать новой темы.
Вообщем нужно в битовую область размером в байт записать некую переменную с таким же размером.
Сделал указатель на структуру (битовую область):
Код
volatile struct
{
  uint8_t bOne : 1;
  uint8_t bTwo : 1;
  uint8_t bThree : 1;
  uint8_t bFour : 1;
}  *RF;

обращаюсь к ней:
Код
(*RF).bOne=1;

но выражение:
Код
volatile uint8_t Cnt1;
.....
(*RF)=Cnt1;
выдает ошибку:
Цитата
error: incompatible types in assignment

Размеры здесь вроде совпадают. Как правильно целиком записать байт в ячейку битового поля?
Палыч
Цитата(MaxiMuz @ Jan 18 2012, 22:02) *
Как правильно ...?

Используйте union
_Артём_
Цитата(MaxiMuz @ Jan 18 2012, 20:02) *
Решил не создавать новой темы.
Вообщем нужно в битовую область размером в байт записать некую переменную с таким же размером.
Сделал указатель на структуру (битовую область):
Код
volatile struct
{
  uint8_t bOne : 1;
  uint8_t bTwo : 1;
  uint8_t bThree : 1;
  uint8_t bFour : 1;
}  *RF;

обращаюсь к ней:
Код
(*RF).bOne=1;

но выражение:
Код
volatile uint8_t Cnt1;
.....
(*RF)=Cnt1;
выдает ошибку:
Размеры здесь вроде совпадают. Как правильно целиком записать байт в ячейку битового поля?


union можно.
Или так:
Код
volatile struct TestbitBield
{
    unsigned char bOne : 1;
    unsigned char bTwo : 1;
    unsigned char bThree : 1;
    unsigned char bFour : 1;
}  RF; /// !!! не *RF
unsigned char Cnt1;

RF.bOne=1;
unsigned char *ptr_dbg=(unsigned char *)&RF;
*ptr_dbg=Cnt1;

Палыч
Цитата(_Артём_ @ Jan 18 2012, 22:36) *
Или так

"Наглое" преобразование типа - источник ошибок.
demiurg_spb
Цитата(MaxiMuz @ Jan 18 2012, 21:02) *
(*RF)=Cnt1;[/code] выдает ошибку:
Правильно выдаёт.
Цитата
Размеры здесь вроде совпадают.
Дело не в размерах а в типах. Вы структуре (агрегату) присваиваете байт.
По аналогии (конечно притянутой за уши): массиву не присвоить значение, это можно сделать лишь его элементу.
Как уже было подмечено, для решения вашей задачи есть специальный инструмент - union.
Он позволяет обращаться к одной сущности по-разному.
MaxiMuz
Всем спасибо!
Используя подставной указатель:
Код
unsigned char *ptr_dbg=(unsigned char *)&RF;
все работает , но код получается грамоздким; с union значительно меньше.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.