Запись бита. Чтение бита

Содержание

Слайд 2

Запись одного бита Установка одного бита: a |= 1 Сброс одного

Запись одного бита

Установка одного бита:
a |= 1<<7; // установить седьмой бит
Сброс

одного бита:
a &= ~(1<<3); // сбросить третий бит
Инверсия одного бита:
a ^= 1<<5; // инверсия пятого бита
Слайд 3

Чтение одного бита if( a & (1 Писать if( a & (1 Скобки лучше ставить. Серьезно.

Чтение одного бита

if( a & (1<<7) ) – это условие истинно,

если седьмой бит равен единице.
Писать if( a & (1<<7) == 1<<7) можно, но бессмысленно.
Скобки лучше ставить. Серьезно.
Слайд 4

Запись нескольких бит Объединение через ИЛИ: a |= (1 Три волшебных

Запись нескольких бит

Объединение через ИЛИ:
a |= (1<<7) | (1<<8); // установить

седьмой и восьмой биты
Три волшебных числа:
a |= 0x3<<7; // установить седьмой и восьмой биты
a |= 0x7<<7; // установить седьмой, восьмой и девятый биты
a |= 0xF<<7; // установить 7,8,9 и 10й биты
Шестнадцатеричный код без сдвигов:
016 === 00002. Т.е. 10016 == 1 0000 00002
a |= 0x180; // == a |= (1<<7) | (1<<8)
Слайд 5

Чтение нескольких бит (аналогично) Объединение через ИЛИ: a & (1 Три

Чтение нескольких бит (аналогично)

Объединение через ИЛИ:
a & (1<<7 | 1<<8)
Три волшебных

числа:
a & (3<<7)
Шестнадцатеричный код без сдвигов:
a & 0x180
Слайд 6

Как помигать светодиодом? Что такое мигание? Это когда какое-то время светодиод

Как помигать светодиодом?

Что такое мигание?
Это когда какое-то время светодиод горит, а

потом какое-то время не горит!
Значит, нужно:
Зажечь светодиод
Подождать
Погасить светодиод
Подождать
Повторить 1-4
Слайд 7

Как подождать? С помощью функции delay? Но как она работает? Самый

Как подождать?

С помощью функции delay? Но как она работает?
Самый простой способ

– пустой цикл for:
for(uint32_t i=0; i<1000; i++) {;}
Ничего не делать 1000 раз подряд.
Количество итераций выбирается либо на глаз, либо исходя из частоты процессора (у нас – 72 МГц)
Слайд 8

А можно ли чуть попроще помигать? Можно: Подождать Инвертировать состояние ножки Повторить 1-2

А можно ли чуть попроще помигать?

Можно:
Подождать
Инвертировать состояние ножки
Повторить 1-2

Слайд 9

Краткое содержание этой серии Как на микроконтроллере измерять время Что такое прерывания и зачем они нужны

Краткое содержание этой серии

Как на микроконтроллере измерять время
Что такое прерывания и

зачем они нужны
Слайд 10

Как измерять время? Вопрос на засыпку: что значит «измерять время»? Измерять,

Как измерять время?

Вопрос на засыпку: что значит «измерять время»?
Измерять, сколько времени

прошло между событиями А и Б
Отмерять необходимый промежуток времени и что-нибудь делать
Слайд 11

Как измерять время? И как же это сделать? Использовать процессорные такты

Как измерять время?

И как же это сделать?
Использовать процессорные такты как «тики»

- например, с помощью пустых циклов
Использовать специализированное периферийное устройство - таймер
Слайд 12

Микропроцессор и его ядро

Микропроцессор и его ядро

Слайд 13

Ядро Cortex M3 Что общего у микроконтроллеров на таком ядре? Система

Ядро Cortex M3

Что общего у микроконтроллеров на таком ядре?
Система команд и

время их выполнения
Одинаковая периферия ядра (с вариациями)
Контроллер прерываний
Периферия уровня ядра описана в документе про ядро — cortex m3 user guide.
Периферия конкретного МК — в документе про конкретный МК (напри, stm32f10x reference manual)
Слайд 14

Так как же измерять время? Мы хотим: Измерять время между событиями Отмерять интервалы времени

Так как же измерять время?

Мы хотим:
Измерять время между событиями
Отмерять интервалы времени

Слайд 15

Так как же измерять время? Допустим, у нас есть ЧАСЫ. Как

Так как же измерять время?

Допустим, у нас есть ЧАСЫ.
Как с их

помощью отмерить интервал?
Запомнить момент начала измерения
Вычислить момент, соответствующий концу интервала
Ждать
Слайд 16

А как не пропустить момент? Периодически посматривать на часы!

А как не пропустить момент?

Периодически посматривать на часы!

Слайд 17

«Основные свойства часов» Значение часов изменяется каждую секунду на фиксированную величину.

«Основные свойства часов»
Значение часов изменяется каждую секунду на фиксированную величину.
Когда часы

досчитывают до 23:59:59, они начинают отсчет от 00:00:00.
Слайд 18

Таймер SysTick Простейший таймер, периферия ядра Cortex M3 (поэтому его описание

Таймер SysTick

Простейший таймер, периферия ядра Cortex M3
(поэтому его описание нужно

искать в документе Cortex M3 user guide, глава 4, стих 4)
Как вы думаете, что он из себя представляет?
Это регистр-счетчик. В начальный момент времени он равен какому-то числу
Каждый «тик» таймера счетчик уменьшается на 1
После достижения нуля, счет начинается заново
Слайд 19

Таймер SysTick — особенности Счетчик 24-битный (макс. 16 777 216) Частота

Таймер SysTick — особенности

Счетчик 24-битный (макс. 16 777 216)
Частота тиков не регулируется

и всегда равна частоте ядра
Направление счета не меняется — всегда к нулю
По достижению нуля счет начинается заново сразу же
Прерывание всегда разрешено!
Регистры SysTick'a в мануале и в коде называются по-разному
Слайд 20

Таймер SysTick — использование Настройка производиться через структуру SysTick. В ней

Таймер SysTick — использование

Настройка производиться через структуру SysTick. В ней

есть четыре регистра:
CTRL – управление (битовое поле)
LOAD – начальное значение счета (число)
Чтобы получить 100 тиков – нужно записать 99
VAL – текущее значение счетчика (число)
CALIB – калибровочный регистр
Слайд 21

Таймер SysTick — использование SysTick->LOAD = 1000 – 1; Задаем начало

Таймер SysTick — использование

SysTick->LOAD = 1000 – 1; Задаем начало

отсчета, таймер сделает 1000 тиков.
Помните, максимальное значение LOAD = 224 = 16 777 216
SysTick->CTRL = 1<<2 | 1<< 0; - Выбираем источник частоты и запускаем счет
Опрос регистра SysTick->VAL — текущее значение счетчика..?
Постоянный опрос регистра называется «поллинг» - polling
Слайд 22

Таймер SysTick — использование Почему поллинг регистра SysTick->VAL работает не всегда?

Таймер SysTick — использование

Почему поллинг регистра SysTick->VAL работает не всегда?
Потому

что счетчик меняется с частотой работы процессора! Он может не успеть «заметить» момент, когда счетчик равен нулю!
Что же делать?
Проверять бит COUNTFLAG в регистре SysTick->CTRL.
Он не сбрасывается, когда счет начинается заново (сбрасывается при чтении).
Или использовать прерывание!
Но этот флаг выставляется в момент изменения значения счетчика с 1 на 0. Именно поэтому я раньше писал про 99 тиков при значении RELOAD=100.
Слайд 23

Таймер SysTick — использование Для настройки таймера SysTick фирма ARM предоставляет

Таймер SysTick — использование

Для настройки таймера SysTick фирма ARM предоставляет

библиотечную функцию SysTick_Config.
Она принимает 1 параметр – значение Reload. Всю остальную настройку она в себе прячет.
Однако, она в том числе разрешает прерывание!
Если оно вам не нужно, его приходится запрещать самостоятельно.
Слайд 24

Таймер SysTick — правильное использование Магическая строчка __disable_irq(); - запрет прерываний

Таймер SysTick — правильное использование

Магическая строчка __disable_irq(); - запрет прерываний
Вызов

SysTick_Config — задание reload value и включение счета
Опрос флага COUNTFLAG в регистре SysTick->CTRL
Это 16-й бит; для значения (1<<16) заведен псевдоним SysTick_CTRL_COUNTFLAG_Msk
Постоянный опрос регистра называется «поллинг» - polling
Слайд 25

Как вычислить нужный reload? Текущая частота ядра хранится в переменной SystemCoreClock

Как вычислить нужный reload?

Текущая частота ядра хранится в переменной SystemCoreClock

(в герцах).
Я хочу, чтобы SysTick досчитал до нуля за 1 миллисекунду. Какой нужно задать reload value?
SystemCoreClock / reload = 1000 (Герц) =>
reload = SystemCoreClock / 1000
Помните, максимальное значение reload — 16,7 миллионов!
Слайд 26

А что же такое прерывание? Как засечь интервал времени с помощью

А что же такое прерывание?

Как засечь интервал времени с помощью

часов?
Постоянно смотреть на часы, не пора ли
Завести будильник!
Прерывание — это как будильник. Оно произойдет в нужный момент «само».
Слайд 27

А что же такое прерывание? Прерывание (interrupt) — это аппаратный вызов

А что же такое прерывание?

Прерывание (interrupt) — это аппаратный вызов

функции по какому-то событию.
Такая функция называется «обработчик прерывания» (interrupt handler).
Вызывать ее программисту НЕ НУЖНО!
Ее вызовет контроллер прерываний, когда придет нужный момент.
Слайд 28

Прерывания Как вы думаете, какие бывают прерывания? Прерывания по исключительным ситуациям

Прерывания

Как вы думаете, какие бывают прерывания?
Прерывания по исключительным ситуациям (исключения, exceptions)

– например, деление на ноль, аппаратный отказ оперативной памяти и т.п.
Прерывания от периферийных устройств – переполнение таймера, внешний сигнал на ножке, завершение работы АЦП и т.п.
Программные прерывания (по приказу программиста)
Слайд 29

Прерывания В чем основное отличие функции-обработчика прерывания от обычной функции? Ее

Прерывания

В чем основное отличие функции-обработчика прерывания от обычной функции?
Ее вызов происходит

аппаратно, в заранее неизвестный момент.
Какие параметры должны быть у функции-обработчика?
Никаких, ведь ее не вызывает программист.
А что она должна возвращать?
Ничего, неизвестно, куда возвращать.
Т.е. тип: void xxxx (void);
Слайд 30

Прерывания А что, если запретить все прерывания (вызвать __disable_irq())? Прерывания не

Прерывания

А что, если запретить все прерывания (вызвать __disable_irq())?
Прерывания не будут происходить.
А

что, если разрешить прерывание, но не написать функцию-обработчик?
Вызовется обработчик по-умолчанию (из файла …startup.s), в котором просто бесконечный цикл.
Слайд 31

Как использовать прерывания? Написать функцию-обработчик (в Keil это функция с заранее

Как использовать прерывания?

Написать функцию-обработчик (в Keil это функция с заранее

определенным именем, например SysTick_Handler)
Запретить все прерывания - __disable_irq();
Настроить нужное прерывание
Разрешить все прерывания - __enable_irq();
Ждать, пока оно произойдет (можно делать что-то полезное, а не просто ждать)