Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Другие темы раздела
C (СИ) Отображение картинки bmp https://www.cyberforum.ru/ c-beginners/ thread1587040.html
Привет. Пытаюсь отобразить картинку по вертикали, но компилятор ругается. Подскажите, что не так? :cry: Буду благодарен #include <stdint.h> #include <malloc.h> #include <stdio.h> #include...
C (СИ) Исправить ошибки в коде
В чем тут ошибка не пойму, все как по книге написал!
C (СИ) Табулирование функции на заданном интервале
#include <stdio.h> #include <stdlib.h> #include <math.h> main(int argc, char * argv) { double h,x,t,ep,eps,fun,Pi; int n; puts("Программа составления таблицы функции,"); puts("заданной на...
C (СИ) Вычисление площади круга: координаты центра и одной из точек окружности задаются в виде параметров функции создать подпрограмму-функцию для вычисления и вывода на экран площади круга, где координатв центра и одной из точек окружности задаются в виде параметров функции https://www.cyberforum.ru/ c-beginners/ thread1586883.html
C (СИ) Найти количество таких чисел из диапазона от 1 до N, что их сумма цифр делится на K https://www.cyberforum.ru/ c-beginners/ thread1586874.html
Вводятся два числа N и K. Выведите количество чисел из диапазона от 1 до N таких, что их сумма цифр делится на K. мой код зацикливается, не могунайти ошибку. #include <stdio.h> int main()...
Второе предложение из первой строки копировать во вторую строку C (СИ)
Даны строки: #include <iostream> #include <string> s1= "Hello world. I go to sleep? I not eating!",s2;Как можно второе предложение из первой строки копировать во вторую строку и при этом поменять...
C (СИ) Вычислить натуральный логарифм X в N итерациях с помощью цепных дробей
Программа вычисляет натуральный логарифм X в N итерациях с помощью цепных дробей и выводит значение в виде cf_log(X) = CF_LOG_X. Задаются значения в качестве аргументов --log X N. Функция...
C (СИ) Перевод из 8 в 10 систему счисления Здравствуйте, помогите пожалуйста доделать лабу...как можно быстро перевести из 8 в 10 сс? Не существует ли интерпретаторов? Перевод где //int Perevod(int natur) #include <iostream> #include... https://www.cyberforum.ru/ c-beginners/ thread1586815.html
C (СИ) Описать функцию Min2 вещественного типа, находящее минимальное из двух вещественных чисел A и B https://www.cyberforum.ru/ c-beginners/ thread1586719.html
Описать функцию Min2 вещественного типа, находящее минимальное из двух вещественных чисел A и B. С помощью этой функции найти минимальное из пар чисел A и B, A и C, A и D, если даны числа A, B, C, D....
C (СИ) Удалить в строке самое длинное/короткое слово Я в программировании полный 0, но практические нужно делать, если не трудно , то люди добрые помогите пожалуйста 1) Ввести простое предложение. Заменить в нём одно из слов (по запросу) на новое и... https://www.cyberforum.ru/ c-beginners/ thread1586713.html
1 / 1 / 0
Регистрация: 03.09.2015
Сообщений: 11
11.12.2015, 12:17  [ТС] 0

В чем суть операторов << и >>

11.12.2015, 12:17. Просмотров 9306. Ответов 10
Метки (Все метки)

Ответ


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


§ Обзор стандартных операций с регистрами

Настало время перейти к более серьёзным операциям над регистрами и программными переменными. Управление работой микроконтроллера в большинстве случаев сводится к следующему простому набору действий с его регистрами:

1. Запись в регистр необходимого значения.
2. Чтение значения регистра.
3. Установка в единицу нужных разрядов регистра.
4. Сброс разрядов регистра в ноль.
5. Проверка разряда на логическую единицу или логический ноль.
6. Изменение логического состояния разряда регистра на противоположное.

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

A = 16; // Присвоить переменной A значение 16;
A = B; // Считать значение переменной B и присвоить это значение переменной A;
A = B+10; // Считать значение переменной B, прибавить к считанному значению 10, результат присвоить переменной A (значение переменной B при этом не изменяется).

§ Запись и чтение регистров

Из рассмотренных примеров видно, что оператор присваивания сам по себе решает две первые задачи — запись и чтение значений регистров. Например для отправки микроконтроллером AVR байта по шине UART достаточно записать его в передающий регистр с именем UDR:

UDR = 8; // Отправить по UART число 8;

Чтобы получить принятый по UART байт достаточно считать его из регистра UDR:

A = UDR; // Считать принятый байт из UART и переписать в переменную A.


§ Установка битов регистров

Язык Си не имеет в своём составе команд непосредственного сброса или установки разрядов переменной, однако присутствуют побитовые логические операции "И" и "ИЛИ", которые успешно используются для этих целей.

Оператор побитовой логической операции "ИЛИ" записывается в виде вертикальной черты - "|" и может выполнятся между двумя переменными, а так же между переменной и константой. Напомню, что операция "ИЛИ" над двумя битами даёт в результате единичный бит, если хотя бы один из исходных битов находится с состоянии единицы. Таким образом для любого бита логическое "ИЛИ" с "1" даст в результате "1", независимо от состояния этого бита, а "ИЛИ" с логическим "0" оставит в результате состояние исходного бита без изменения. Это свойство позволяет использовать операцию "ИЛИ" для установки N-ого разряда в регистре. Для этого необходимо вычислить константу с единичным N-ным битом по формуле 2^N, которая называется битовой маской и выполнить логическое "ИЛИ" между ней и регистром, например для установки бита №7 в регистре SREG:

(SREG | 128) — это выражение считывает регистр SREG и устанавливает в считанном значении седьмой бит, далее достаточно изменённое значение снова поместить в регистр SREG:

SREG = SREG | 128; // Установить бит №7 регистра SREG.

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

Приведённый программный код, устанавливая седьмой бит в регистре SREG, выполняет вполне осмысленную работу - разрешает микроконтроллеру обработку программных прерываний. Единственный недостаток такой записи — в константе 128 не легко угадать установленный седьмой бит, поэтому чаще маску для N-ного бита записывают в следующем виде:

(1<<N) - это выражение на языке Си означает, число один, сдвинутое на N разрядов влево, это и есть маска с установленным N-ным битом. Тогда предыдущий код в более читабельном виде:

SREG = SREG | (1<<7);

или ещё проще с использование краткой формы записи языка Си:

SREG |= (1<<7);

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

§ Сброс битов в регистрах

Ещё одна логическая операция языка Си – побитовое "И", записывается в виде символа "&". Как известно, операция логического "И", применительно к двум битам даёт единицу тогда и только тогда, когда оба исходных бита имеют единичное значение, это позволяет применять её для сброса разрядов в регистрах. При этом используется битовая маска, в которой все разряды единичные, кроме нулевого на позиции сбрасываемого. Её легко получить из маски с установленным N-ным битом, применив к ней операцию побитного инвертирования:

~(1<<N) в этом выражении символ "~" означает смену логического состояния всех битов маски на противоположные. Так, например, если (1<<3) в двоичном представлении – 00001000b, то ~(1<<3) уже 11110111b. Сброс седьмого бита в регистре SREG будет выглядеть так:

SREG = SREG & (~ (1<<7));

или кратко:

SREG &= ~ (1<<7);

В упомянутом ранее заголовочном файле для конкретного микроконтроллера приведены стандартные имена разрядов регистров специального назначения, например:

#define OCIE0 1

здесь #define – указание компилятору заменять в тексте программы сочетание символов "OCIE0" на число 1, то есть стандартное имя бита OCIE0, который входит в состав регистра TIMSK микроконтроллера Atmega64 на его порядковый номер в этом регистре. Благодаря этому установку бита OCIE0 в регистре TIMSK можно нагляднее записывать так:

TIMSK|=(1<<OCIE0);

Устанавливать или сбрасывать несколько разрядов регистра одновременно можно, объединяя битовые маски в выражениях оператором логического "ИЛИ":

PORTA |= (1<<1)|(1<<4); // Установить выводы 1 и 4 порта A в единицу;
PORTA&=~((1<<2)|(1<<3)); // Выводы 2 и 3 порта A сбросить в ноль.


§ Проверка разрядов регистра на ноль и единицу

Регистры специального назначения микроконтроллеров содержат в своём составе множество битов-признаков, так называемых "флагов”, уведомляющих программу о текущем состоянии микроконтроллера и его отдельных модулей. Проверка логического уровня флага сводится к подбору выражения, которое становится истинным или ложным в зависимости от того установлен или сброшен данный разряд в регистре. Таким выражением может служить логическое "И” между регистром и маской с установленным разрядом N на позиции проверяемого бита :

(REGISTR & (1<<N)) в этом выражении операция "И” во всех разрядах кроме N-ного даст нулевые значения, а проверяемый разряд N оставит без изменения. Таким образом возможное значения выражения будут или 0 или 2^N, например для второго бита регистра SREG:



Приведённое выражение можно использовать в условном операторе if (выражение) или операторе цикла while (выражение), которые относятся к группе логических, то есть воспринимают в качестве аргументов значения типа истина и ложь. Поскольку язык Си, приводя числовые значения к логическим, любые числа не равные нулю воспринимает как логическую истину, значение (REGISTR & (1<<N)) равное 2^N в случае установленного бита, будет воспринято как "истина".

Если появляется необходимость при установленном бите N получить для нашего выражения логическое значение «ложь», достаточно дополнить его оператором логической инверсии в виде восклицательного знака - !(REGISTR & (1<<N)). Не следует путать его с похожим оператором побитовой инверсии (~) меняющим состояние битов разряда на противоположное. Логическая инверсия работает не с числовыми значениями, а с логическими, то есть преобразует истинное в ложное и наоборот. Такая конструкция приводится в DataSheet на Atmega как пример для ожидания установки бита UDRE в регистре UCSRA, после которого можно отправлять данные в UART:

while ( !( UCSRA & (1<<UDRE)) ) { } // Ждать установки UDRE.

Здесь при сброшенном бите UDRE выражение ( UCSRA & (1<<UDRE)) даст значение ”ложь”, инвертированное !( UCSRA & (1<<UDRE)) — ”истину”, и пока это так, программа будет выполнять действия внутри фигурных скобок, то есть не делать ничего (стоять на месте). Как только бит UDRE установится в единицу, программа перейдёт к выполнению действий следующих за конструкцией while(), например займётся отправкой данных в UART.

§ Изменение состояния бита регистра на противоположное

Эту проблему с успехом решает логическая операция побитного "ИСКЛЮЧАЮЩЕГО ИЛИ” и соответствующий ей оператор Си, записываемый в виде символа " ^ ”. Правило "исключающего или" с двумя битами даёт "истину” тогда и только тогда, когда один из битов установлен, а другой сброшен. Не трудно убедиться, что этот оператор, применённый между битовой маской и регистром, скопирует в результат биты стоящие напротив нулевых битов маски без изменения и инвертирует расположенные напротив единичных. Например, если: reg=b0001 0110 и mask=b0000 1111, то reg^mask=b0001 1001. Таким способом можно менять состояние светодиода, подключенного к пятому биту порта A:

#define LED 5 // Заменять в программе сочетание символов LED на число 5 (вывод светодиода).

PORTA ^=(1<< LED); // Погасить светодиод, если он светится и наоборот.


Вернуться к обсуждению:
В чем суть операторов << и >>
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.12.2015, 12:17
Готовые ответы и решения:

В чем суть continue в if-else
код первый. прата глава 7 упражнение 3. оператор continue отсутствует, все прекрасно работает....

Строгое чередование: в чем суть алгоритма?
Объясните пожалуйста смысл этого алгоритма. Я не могу понять, зачем мы turn присваиваем 1-i? Он же...

В чем суть функций putchar и getchar
подскажите кто знает что деляют эти функции

Поразрядные операции - в чем суть и применение?
Добрый вечер. Объясните, в каких задачах они могут понадобиться и как ими пользоваться. А конкретно...

__________________
Помогаю в написании курсовых работ и дипломов здесь.
10
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.