Перейти к содержанию
    

Вопрос по побитовым операциям

Здравствуйте.

В языке Си, чтобы выставить или обнулить отдельный бит в регистре, нужно использовать команды сдвига и логические операции. Например был регистр 01010001, а стал 01010101. Но тогда же остальные биты в байте тоже же перезапишутся, просто с предыдущими значениями. А можно ли выставить (или обнулить) только один бит в регистре, не трогая остальные биты? На языке Си.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 минуту назад, Damyen сказал:

В языке Си, чтобы выставить или обнулить отдельный бит в регистре

В языке си нету регистров.

21 минуту назад, Damyen сказал:

А можно ли выставить (или обнулить) только один бит в регистре, не трогая остальные биты? На языке Си.

Регистры есть в микроконтроллерах. А можно или нет производить операции с отдельными битами каждого конкретного периферийного регистра - читайте в мануале на ваш микроконтроллер. Некоторые периферийные регистры это позволяют. Но для этого нужно сперва открыть и прочитать мануал на эту периферию.

Также средства для атомарных манипуляций с битами есть в некоторых архитектурах. В ARM например - (bit-banding). На уровне ядра (CPU).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да я понимаю, что регистры есть в МК. И также знаю, что это можно сделать на ассемблере. Но вот для операций с отдельными битами на Си, прочитал, что можно использовать команду PORTB = PORTB | (1 << 5), чтобы выставить 5 бит. Но если внимательно на нее посмотреть, то мы все равно взаимодействуем со всем регистром МК, а не с одним битом.

Изменено пользователем Damyen

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В Си нет таких средств, так что только через вставку ассемблерных команд SBI, CBI.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как раз то "PORTB = PORTB | (1 << 5)" после компиляции "превратится" в одну SBI. Другое дело, что в AVR битовые операции взаимодействуют со всем байтом данных, т.е. производится операция  "чтение-модификация-запись".
И пофиг тут, Си или ассемблер.)

Изменено пользователем v05

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно записать еще короче: PORTB |= 1 << 5; Знак |= означает сокращенную запись двух операций. Учите язык Си!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я специально взял в кавычки. Типа как у ТС). Можно (и нужно!) еще короче, не привязываясь к физике - ни портам, ни к битам, ни к уровням (активный низкий или высокий). 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как не привязываться к портам то? Это же не большой компьютер. Код для микроконтроллера обязательно требует операций с конкретными портами, с конкретной периферией. Рано или поздно вы столкнетесь с низкоуровневым кодом, работающим непосредственно с железом микроконтроллера. Даже если вы используете ардуиновскую DigitalWrite, то всё равно её ведь кто-то написал, опираясь на уровень работы с регистрами и битами. Так что... Учите не только язык Си, но и матчасть!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Естественно, на физике будут обращения к портам. А на логике о портах, битах и активных уровнях мне знать ничего не надо. 

if (pin(BUTTON))
  on(LED);

И не важно куда и как подключен BUTTON и куда и как LED (сегодня так - завтра эдак), программа будет без изменений, изменится только описание.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дак про логику тут никто и не спрашивал, кагбе у топикстартера пока еще базовые вопросы... Похвально, конечно, что вы знаете про логику, похвально. Ну а я вот могу еще круче: PowerLamp::On(); и догадайтесь, как это сделано 🙂 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

typedef struct
{
  union
  {
    __IO uint32_t ctrl1;
    struct
    {
      __IO uint32_t sbf                  : 1; /* [0] */
      __IO uint32_t rm                   : 1; /* [1] */
      __IO uint32_t ren                  : 1; /* [2] */
      __IO uint32_t ten                  : 1; /* [3] */
      __IO uint32_t idleien              : 1; /* [4] */
      __IO uint32_t rdbfien              : 1; /* [5] */
      __IO uint32_t tdcien               : 1; /* [6] */
      __IO uint32_t tdbeien              : 1; /* [7] */
      __IO uint32_t perrien              : 1; /* [8] */
      __IO uint32_t psel                 : 1; /* [9] */
      __IO uint32_t pen                  : 1; /* [10] */
      __IO uint32_t wum                  : 1; /* [11] */
      __IO uint32_t dbn                  : 1; /* [12] */
      __IO uint32_t uen                  : 1; /* [13] */
      __IO uint32_t reserved1            : 18;/* [31:14] */
    } ctrl1_bit;
  };
} 

#define USART1 ((usart_type *) USART1_BASE)

USART1->ctrl1_bit.uen = 1;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/30/2024 at 1:13 PM, v05 said:

Другое дело, что в AVR битовые операции взаимодействуют со всем байтом данных, т.е. производится операция  "чтение-модификация-запись".

Нет.
SBI и CBI работаю напрямую с битами.
А вот SBR и CBR через чтение-модификация-запись.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/1/2024 at 9:14 PM, dimka76 said:

Нет.
SBI и CBI работаю напрямую с битами.

Да что вы говорите! Можно ссылку?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 8/1/2024 at 9:55 PM, v05 said:

Да что вы говорите! Можно ссылку?

https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-Instruction-Set-Manual-DS40002198A.pdf

Quote

SBI – Set Bit in I/O Register

Description Sets a specified bit in an I/O Register. This instruction operates on the lower 32 I/O Registers – addresses 0-31.

Operation:

(i) I/O(A,b) ← 1

Quote

SBR – Set Bits in Register

 Description Sets specified bits in register Rd. Performs the logical ORI between the contents of register Rd and a constant mask K,

and places the result in the destination register Rd. (Equivalent to ORI Rd,K.)

Operation:

(i) Rd ← Rd v K

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...