Акселерометр представляет собой датчик, измеряющий проекции ускорения на три пространственные оси. Учитывая величину ускорения свободного падения (g) и данные измерения по трем осям, можно определить ориентацию акселерометра в пространстве. Для этих целей его и используют, например, в мобильных телефонах для поворота изображения на экране, а также в играх. В этой статье я рассмотрю модуль с акселерометром ADXL345 позиционирующийся под платформу Arduino.
Я заказывал модуль здесь. Акселерометр ADXL345 способен измерять ускорение величиной до ±16 g, с максимальным разрешением 13 бит, частота измерения может достигать 3200 Гц. Обладает низким энергопотреблением, максимум 140 мкА, напряжение питания может находиться в пределах 2…3,6 В. Акселерометр поддерживает два распространенных интерфейса связи SPI и I2C, а также имеет два выхода прерываний и встроенный буфер для хранения данных. Схема модуля приведена ниже:
Режимы питания и энергосбережения
Ток потребления акселерометра зависит от частоты измерения (дискретизации) ускорения, ниже в таблице приведены значения тока для различных частот, при напряжении питания 2,5В:
Частота измерения ускорения и обновления выходных данных, Гц | Полоса пропускания, Гц | Биты задания частоты (Rate), регистр BW_RATE | Потребление акселерометра, мкА |
3200 | 1600 | 1111 | 140 |
1600 | 800 | 1110 | 90 |
800 | 400 | 1101 | 140 |
400 | 200 | 1100 | 140 (90) |
200 | 100 | 1011 | 140 (60) |
100 | 50 | 1010 | 140 (50) |
50 | 25 | 1001 | 90 (45) |
25 | 12,5 | 1000 | 60 (40) |
12,5 | 6,25 | 0111 | 50 (34) |
6,25 | 3,13 | 0110 | 45 |
3,13 | 1,56 | 0101 | 40 |
1,56 | 0,78 | 0100 | 34 |
0,78 | 0,39 | 0011 | 23 |
0,39 | 0,20 | 0010 | 23 |
0,20 | 0,10 | 0001 | 23 |
0,10 | 0,05 | 0000 | 23 |
В скобках указаны токи для режима пониженного энергопотребления, который управляется битом LOW_POWER регистра BW_RATE. Уменьшение потребления осуществляется за счет большего шума (снижается точность). Установка других частот в этом режиме не дает никакого преимущества в экономии.
После подачи питания акселерометр находится в режиме ожидания, с минимальным потребление энергии, около 0,1 мкА, при этом ускорение не измеряется. Для перехода в режим измерения необходимо установить бит Measure регистра POWER_CTL. Функция автоматического перехода в спящий режим при простое, позволяет дополнительно экономить энергию, более подробно о режиме будет сказано ниже.
Интерфейс передачи данных
Передача данных может осуществляться по двум протоколам, SPI и I2C. Для подключения интерфейса I2C, необходимо подтянуть линию CS к высокому логическому уровню. Для интерфейса SPI вывод CS управляется внешним контроллером. Для SPI доступны два режима: 3-х и 4-х проводная схема. В 4-х проводной схеме для передачи данных используется две линии акселерометра (кроме CS и SCLK), это SDI – вход данных, SDO – выход.
Для 3-х проводной схемы используется одна линия SDIO, при этом, внешний контроллер должен перенастраивать свой вход в соответствии с направлением передачи. В этом случае линию SDO необходимо подтянуть к высокому или низкому уровню через резистор в 10 кОм, в модуле вывод подтянут к низкому уровню. Во время передачи данных на линии CS необходимо установить низкий логический уровень, линия SCLK должна находиться в высоком логическом уровне, когда передача данных отсутствует. Ниже представлена структура первого байта для пакета SPI:
Структура первого байта для пакета SPI | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
RW | MB | A5 | A4 | A3 | A2 | A1 | A0 |
Байты передаются старшим битом вперед. Бит RW указывает операцию: 1 – чтение, 0 – запись. Для передачи нескольких байт за сеанс связи, необходимо установить бит MB, нулевое значение соответствует передаче одного байта. Биты A5-A0 задают адрес регистра, к которому идет обращение. Окончание передачи данных выполняется установкой высокого логического уровня на линии CS.
Максимальная частота тактирования SPI интерфейса равна 5 МГц. Для частоты измерения (обновления данных) 3200 и 1600 Гц, SPI интерфейс должен функционировать на частоте не ниже 2 МГц. Для частоты измерения 800 Гц, не ниже 400 кГц и т.д. в такой же пропорции, иначе могут возникнуть пропуски новых данных измерения.
Для интерфейса связи I2C поддерживаются стандартная скорость передачи в 100 кГц, а также высокая 400 кГц. Линия ALT_ADDRESS отвечает за адрес акселерометра на шине I2C. При высоком логическом уровне на линии, акселерометру присваивается 7-ми битный адрес со значением 0011101, при низком уровне 1010011. Для корректного функционирования интерфейса, линии SDA и SCL необходимо подтянуть к питающему напряжению.
Из-за ограничения скорости передачи данных в 400 кГц, максимальная частота измерения ускорения не должна превышать 800 Гц.
Описание регистров ADXL345
Акселерометр ADXL345 имеет достаточно много регистров настройки и управления, перечень которых представлен в следующей таблице:
Адрес | Название | Тип | Состояние после сброса | Описание |
0 (0x00) | DEVID | R | 11100101 | Номер ID |
1-28 (0x01-0x1C) | Reserved | Зарезервировано | ||
29 (0x1D) | THRESH_TAP | R/W | 00000000 | Значение уставки для толчка |
30 (0x1E) | OFSX | R/W | 00000000 | Смещение для оси X |
31 (0x1F) | OFSY | R/W | 00000000 | Смещение для оси Y |
32 (0x20) | OFSZ | R/W | 00000000 | Смещение для оси Z |
33 (0x21) | DUR | R/W | 00000000 | Длительность толчка |
34 (0x22) | Latent | R/W | 00000000 | Задержка перед ожиданием второго толчка |
35 (0x23) | Window | R/W | 00000000 | Время для обнаружения второго толчка |
36 (0x24) | THRESH_ACT | R/W | 00000000 | Значение уставки функции активности |
37 (0x25) | THRESH_INACT | R/W | 00000000 | Значение уставки функции бездействия |
38 (0x26) | TIME_INACT | R/W | 00000000 | Время бездействия |
39 (0x27) | ACT_INACT_CTL | R/W | 00000000 | Привязка событий активности/бездействия на оси |
40 (0x28) | THRESH_FF | R/W | 00000000 | Значение уставки свободного падения |
41 (0x29) | TIME_FF | R/W | 00000000 | Время свободного падения |
42 (0x2A) | TAP_AXES | R/W | 00000000 | Привязка событий толчка на оси |
43 (0x2B) | ACT_TAP_STATUS | R | 00000000 | Регистр флагов событий толчка или активности |
44 (0x2C) | BW_RATE | R/W | 00001010 | Настройка частоты дискретизации |
45 (0x2D) | POWER_CTL | R/W | 00000000 | Настройка режима энергосбережения |
46 (0x2E) | INT_ENABLE | R/W | 00000000 | Регистр управления прерываниями |
47 (0x2F) | INT_MAP | R/W | 00000000 | Назначение выходных линий для прерываний |
48 (0x30) | INT_SOURCE | R | 00000010 | Регистр флагов прерываний |
49 (0x31) | DATA_FORMAT | R/W | 00000000 | Настройка формата выходных данных |
50 (0x32) | DATAX0 | R | 00000000 | Выходные данные для оси X (младший байт) |
51 (0x33) | DATAX1 | R | 00000000 | Выходные данные для оси X (старший байт) |
52 (0x34) | DATAY0 | R | 00000000 | Выходные данные для оси Y (младший байт) |
53 (0x35) | DATAY1 | R | 00000000 | Выходные данные для оси Y (старший байт) |
54 (0x36) | DATAZ0 | R | 00000000 | Выходные данные для оси Z (младший байт) |
55 (0x37) | DATAZ1 | R | 00000000 | Выходные данные для оси Z (старший байт) |
56 (0x38) | FIFO_CTL | R/W | 00000000 | Настройка буфера FIFO |
57 (0x39) | FIFO_STATUS | R | 00000000 | Регистр состояния буфера FIFO |
Тип: R – только чтение, R/W – чтение и запись |
Регистр DEVID содержит ID номер акселерометра, значение равно 0xE5.
Регистры OFSX, OFSY, OFSZ предназначены для задания смещения выходных данных по осям X, Y, Z. Содержимое каждого регистра складывается с измеренным значением ускорения по соответствующей оси. Младшему значимому биту соответствует ускорение 15,6 mg (расчетный коэффициент 15,6 mg/LSB), причем учитывается знак, для значения 0x7F получим примерно +2g, для 0x80 соответственно -2g. Подробнее про использование регистров будет сказано позже.
Регистр THRESH_TAP содержит значение уставки ускорения, которое используется для обнаружения кратковременного воздействия на акселерометр, то есть для фиксации толчка. Значение регистра рассчитывается исходя из расчетного коэффициента 62,5 mg/LSB (для значения 0xFF получим пороговое ускорение 16g). Значение равное 0 при разрешенном прерывании может привести к некорректному поведению.
Регистр DUR задает максимальную длительность толчка, в течение которого значение ускорения должно быть выше уставки заданной в регистре THRESH_TAP, при выполнении этих условий фиксируется событие толчка и генерируется прерывание. Если по истечении заданного времени ускорение остается уставки, событие толчка не засчитывается. Расчетный коэффициент 625 мкс/LSB, значение 0 отключает функции обнаружения толчка/двойного толчка.
Регистр Latent содержит значение временной задержки после обнаружения первого толчка и началом временного интервала для сканирования второго толчка. Временной интервал задается в регистре Window. Расчетный коэффициент 1,25 мс/LSB, значение 0 отключает функции обнаружения двойного толчка.
В регистре TAB_AXES можно задать оси X, Y, Z, по которым будут отслеживаться толчки, для этого необходимо установить биты TAP_x enable. Если бит TAP_x сброшен, то соответствующая ось не участвует в обнаружении толчков. При установке бита Suppress, событие двойного толчка не фиксируется, если во время задержки (Latent) после обнаружения первого толчка, возникает ускорение, превышающее значение уставки в регистре THRESH_TAP.
Регистр TAB_AXES | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
0 | 0 | 0 | 0 | Suppress | TAP_X enable | TAP_Y enable | TAP_Z enable |
Ниже представлена поясняющая картинка:
Регистры THRESH_ACT и THRESH_INACT содержат значения уставок, которые используются для выявления факта изменения ускорения. Расчетный коэффициент равен 62,5 mg/LSB, значение 0 при разрешенном прерывании может привести к некорректному поведению. Если ускорение превышает значение уставки в регистре THRESH_ACT, возникает событие активности, по которому генерируется прерывание. Событие бездействия возникает, когда значение ускорение меньше уставки в регистре THRESH_INACT, в течение времени, превышающего значение в регистре TIME_INACT. Расчетный коэффициент для времени 1 сек/LSB.
С помощью регистра ACT_INACT_CTL можно задать оси X, Y, Z, для которых будет отслеживаться событие активности (биты ACT_x enable) или бездействия (биты INACT_x enable), для этого нужно установить соответствующие биты. Если все биты сброшены, функция отслеживания отключается. При отслеживании активности, сравнение ускорений по осям выполняется с помощью логической функции “И”, то есть превышение уставки по любой оси вызывает событие активности. Для бездействия используется функция “ИЛИ”, событие возникает, если ускорение по все осям меньше уставки в течение времени заданного в регистре TIME_INACT. Кроме этого можно задать режим сравнения ускорений: если биты ACT ac/dc и INACT ac/dc сброшены, то используется абсолютное сравнение, текущее значение сравнивается с уставкой. Если я правильно понял, при установленных битах, с значением уставки сравнивается результат разницы между двумя измерениями.
Регистр ACT_INACT_CTL | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
ACT ac/dc | ACT_X enable | ACT_Y enable | ACT_Z enable | INACT ac/dc | INACT_X enable | INACT_Y enable | INACT_Z enable |
Регистр THRESH_FF содержит значение уставки, которое сравнивается с ускорением по каждой оси (лог. функция “И”), если значения ускорений по всем осям меньше уставки в течение времени заданного в регистре TIME_FF, то возникает событие свободного падения и генерируется прерывание. Расчетный коэффициент для уставеи 62,5 mg/LSB, рекомендуемые значения от 300 до 600 mg. Для временного промежутка коэффициент равен 5 мс/LSB, рекомендуемые значения от 100 до 350 мс. Значение регистров равное 0 при разрешенном прерывании может привести к некорректному поведению.
Регистр ACT_TAP_STATUS содержит флаги, которые указывают соответствующую ось, на которой в первую очередь произошло событие активности (биты ACT_x source) или толчка (биты TAP_x source). Установленный бит указывает на факт возникновения события. Этот регистр не очищается, а перезаписывается новыми данными, регистр должен быть прочитан перед сбросом флагов прерываний. Если отслеживание по какой-либо оси было отключено, то соответствующий бит сбросится после возникновения очередного события. Бит Asleep указывает на состояние акселерометра, если значение равно 1, модуль находится в спящем режиме и наоборот.
Регистр ACT_TAP_STATUS | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
0 | ACT_X source | ACT_Y source | ACT_Z source | Asleep | TAP_X source | TAP_Y source | TAP_Z source |
Регистр BW_RATE отвечает за частоту выходных данных и режим пониженного потребления. Сброшенному биту LOW_POWER соответствует нормальный режим работы, если бит установлен, акселерометр переходит в режим пониженного энергопотребления. Биты Rate отвечают за частоту выходных данных, выше в статье приведена таблица настройки частоты.
Регистр BW_RATE | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
0 | 0 | 0 | LOW_POWER | Rate |
Регистр POWER_CTL управляет режимами энергосбережения акселерометра. Бит Link связывает функции активности и бездействия, если бит установлен, запуск функции активности задерживается до обнаружения события бездействия, и наоборот. Если бит сброшен, эти функции равноправны и выполняются независимо друг от друга.
Установка бита AUTO_SLEEP включает функцию автоматического перехода в спящий режим, сброс бита соответственно отключает ее. Функция активна, только в случае, если установлен бит Link. В этом режиме происходит автоматический переход в спящий режим, если включена функция бездействия и возникло данное событие. Если дополнительно включена функция активности, то акселерометр автоматически просыпается при возникновении данного события, и продолжает измерение в нормальном режиме. Установка бита AUTO_SLEEP при сброшенном бите Link, не влияет на работу акселерометра.
Для правильной работы функции Link, управляющему устройству необходимо отслеживать возникновение событий активности и бездействия с помощью прерываний, и своевременно сбрасывать флаги прерываний путем чтения регистра INT_SOURCE. Если, например, не сброшен флаг прерывания события активности (Activity), то акселерометр в последующем не перейдет в спящий режим, при включенной функции автоматического сна.
Сброс бита Measure переводит акселерометр в режим ожидания с минимальным потреблением энергии, ускорение при этом не измеряется. Установка бита переводит акселерометр в режим измерения.
Установка бита Sleep переводит акселерометр в спящий режим, во время которого передача данных в буфер FIFO останавливается, прерывание по обновлению данных измерения (DATA_READY) отключается. Регистры выходных данных DATAX, DATAY, DATAZ обновляются с частотой, которая задается битами Wakeup. В спящем режиме действует только функция активности.
Биты Wakeup | Частота обновления данных (измерения) | |
D1 | D0 | |
0 | 0 | 8 Гц |
0 | 1 | 4 Гц |
1 | 0 | 2 Гц |
1 | 1 | 1 Гц |
Регистр POWER_CTL | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
0 | 0 | Link | AUTO_SLEEP | Measure | Sleep | Wakeup |
При сбросе битов Link, AUTO_SLEEP, Sleep, рекомендуется перевести акселерометр в режим ожидания, а затем обратно в режим измерения, это необходимо, чтобы акселерометр выполнил корректное смещение, если спящий режим был отключен вручную. В противном случае первые несколько измерений ускорения могут иметь дополнительный шум, особенно если бит сброшен во время спящего режима. Честно говоря, я не совсем понял, что тут имелось в виду.
Регистр INT_ENABLE содержит биты разрешения различных прерываний. Возможны прерывания по следующим событиям:
- обновление данных по измерению ускорения, бит DATA_READY;
- толчок, то есть кратковременное изменение ускорения, бит SINGLE_TAP;
- двойной толчок, бит DOUBLE_TAP;
- активность, бит Activity;
- бездействие, бит Inactivity;
- свободное падение, бит FREE_FALL;
- количество измерений достигло значения уставки, бит Watermark;
- переполнение буфера FIFO либо перезапись непрочитанных данных, бит Overrun.
Установка битов разрешает соответствующие прерывания, сброс запрещает. Функции, закрепленные за битами DATA_READY, Watermark, Overrun действую постоянно, биты рекомендуется настраивать перед включением выходов прерываний.
Регистр INT_MAP содержит биты с такими же названиями, как в регистре INT_ENABLE, здесь можно назначить прерывания на один из двух выходов акселерометра. При нулевом значении бита, соответствующее прерывание назначается на вывод INT1, иначе на вывод INT2. Если на один вывод назначено несколько прерываний, любое из них вызовет изменение логического уровня на выходе (используется лог. функция “ИЛИ”).
Флаги прерываний находятся в регистре INT_SOURCE, и имеют такие же названия как биты в регистре INT_ENABLE. Установка флагов в 1 означает, что произошло соответствующее прерывание. Флаг DATA_READY устанавливается, когда получены новые данные измерения ускорения. Флаг Watermark связан с буфером FIFO, о котором будет сказано позже. В случае если буфер FIFO отключен, флаг Overrun устанавливается, когда новые данные перезаписывают еще непрочитанные в регистрах DATAX, DATAY, DATAZ. Если буфер FIFO включен, флаг Overrun указывает на его переполнение. Флаги DATA_READY, Watermark, Overrun устанавливаются независимо от того, разрешены прерывания или нет, и сбрасываются путем чтения регистров DATAX, DATAY, DATAZ. Для сброса флагов DATA_READY, Watermark может потребоваться несколько чтений, в зависимости от количества данных в буфере FIFO, остальные флаги сбрасываются путем чтения регистра INT_SOURCE.
Регистры INT_ENABLE, INT_MAP, INT_SOURCE | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
DATA_READY | SINGLE_TAP | DOUBLE_TAP | Activity | Inactivity | FREE_FALL | Watermark | Overrun |
С помощью регистра DATA_FORMAT осуществляется настройка формата выходных данных для регистров DATAX, DATAY, DATAZ, а также ряда других функций. Установка бита SELF_TEST запускает самодиагностику акселерометра, при этом проверяются механические и электронные системы акселерометра. В процессе проверки значения ускорений будут меняться.
Бит SPI настраивает режим интерфейса передачи данных, значение 1 устанавливает 3-х проводной режим SPI, нулевое значение 4-х проводной режим.
Бит INT_INVERT настраивает активный логический уровень на выводах прерываний INT1, INT2. При нулевом значении бита, активный логический уровень – высокий, для значения 1 активный уровень низкий.
С помощью бита FULL_RES настраивается величина разрешения, с которой будет измеряться ускорение. При установке бита, включается режим расширенного разрешения, которое зависит от предела установленного битами Range, результат измерения рассчитывается исходя из коэффициента 3,9 mg/LSB. Нулевое значение бита устанавливает фиксированное разрешение 10 бит, при этом результат измерения, а также расчетный коэффициент, будут зависеть от выбранного предела.
Бит Justify задает способ выравнивания результата измерения внутри регистров DATAX, DATAY, DATAZ, значение бита равное 1, устанавливает левое выравнивание, 0 – правое.
Биты Range | Предельное значение измеряемого ускорения | |
D1 | D0 | |
0 | 0 | ±2 g |
0 | 1 | ±4 g |
1 | 0 | ±8 g |
1 | 1 | ±16 g |
Регистр DATA_FORMAT | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
SELF_TEST | SPI | INT_INVERT | 0 | FULL_RES | Justify | Range |
Регистры DATAX0, DATAX1, DATAY0, DATAY1, DATAZ0, DATAZ1 хранят результат измерения ускорения. Значение ускорения для каждой оси представлено двумя байтами, DATAx1 старший, DATAx0 младший байт. Рекомендуется прочитать все 6 байт за одну операцию, чтобы исключить потерю данных, так как между раздельными операциями чтения, содержимое регистров может обновиться.
Регистр FIFO_CTL управляет режимом работы кольцевого буфера FIFO, это небольшая внутренняя память акселерометра, которая может хранить результат 32-х измерений для каждой оси. Биты FIFO_MODE устанавливают один из четырех режимов работы:
- Bypass – буфер отключен, содержимое остается пустым;
- FIFO – буфер заполняется до переполнения, после чего данные не сохраняются, но акселерометр продолжает работать;
- Stream – при переполнении буфера, старые данные перезаписываются новыми, получаем кольцевой буфер.
- Trigger – буфер сохраняет данные до возникновения события триггера, после чего переключается в режим FIFO. Я детально не разбирался с этим режимом.
Бит Trigger связывает событие триггера с выходом прерывания INT1 или INT2. Биты Samples задают количество измерений, при превышении которого устанавливается флаг прерывания Watermark в регистре INT_SOURCE, данная функция действует для режимов FIFO и Stream, для режима Trigger биты Samples имеют другое назначение. Нулевые значения битов Samples в режиме Trigger, могут привести к некорректному поведению.
Регистр FIFO_CTL | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
FIFO_MODE | Trigger | Samples |
Регистр FIFO_STATUS отображает состояние буфера. Бит FIFO_TRIG указывает на возникновение события триггера, биты Entries указывают размер буфера, который занят данными, то есть количество измерений, которые хранятся в буфере на текущий момент.
Регистр FIFO_STATUS | |||||||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
FIFO_TRIG | 0 | Entries |
Доступ к буферу осуществляется с помощью регистров хранения результата DATAX, DATAY, DATAZ, для чтения данных из буфера, необходимо многократно прочитать регистры хранения. За одну операцию необходимо прочитать все 6 байт, так как, данные отдельного измерения (ускорение по всем осям) стираются, независимо от количества прочитанных байт.
Формат выходных данных
Результат измерения ускорения помещается в регистры выходных данных DATAX0, DATAX1, DATAY0, DATAY1, DATAZ0, DATAZ1, по два байта на каждое ускорение. Для частоты измерения 3200 и 1600 Гц формат данных меняется в зависимости от заданного разрешения и выбранного предела измерения.
При использовании частоты измерения 3200 и 1600 Гц в режиме раширенного разрешения (FULL_RES) или фиксированном разрешении 10 бит для предела ±2 g, младший значимый бит (LSB) всегда остается равным 0, независимо от способа выравнивания. Для пределов ±4 g, ±8 g, ±16 g, в 10-битном разрешении, младший значимый бит учитывается в результате измерения, то есть не всегда равен 0. Для частот измерения 800 Гц или ниже, младший значимый бит всегда учитывается, независимо от режима разрешения и выбранного предела.
В режиме расширенного разрешения, пределу ±2 g соответствует 10 бит данных, 11 бит для предела ±4 g, 12 бит для ±8 g, и 13 бит для ±16 g. В случае правого выравнивания, меняется положение старшего значимого бита (MSB), для левого выравнивания, положение младшего значимого бита. Кроме этого, при левом выравнивании, биты, лежащие правее младшего значимого (LSB), всегда равны 0. Ниже приведена поясняющая картинка:
Результат измерения ускорения может принимать как положительные, так и отрицательные значения, в зависимости от ориентации акселерометра. В следующей таблице представлены значения выходных данных в зависимости от величины ускорения, разрешения, и предела измерения:
Разрешение, предел измерения | Расчетный коэффициент | Величина измеряемого ускорения | Значение выходных данных |
10 бит, ±2 g
Расширенное разрешение: ±2 g |
3,9 mg/LSB | +1 g | 256 (0x100) |
-1 g | 768 (0x300) | ||
10 бит, ±4 g | 7,8 mg/LSB | +1 g | 128 (0x80) |
-1 g | 896 (0x380) | ||
10 бит, ±8 g | 15,6 mg/LSB | +1 g | 64 (0x40) |
-1 g | 960 (0x3C0) | ||
10 бит, ±16 g | 31,2 mg/LSB | +1 g | 32 (0x20) |
-1 g | 992 (0x3E0) | ||
Расширенное разрешение: ±4 g (11 бит) | 3,9 mg/LSB | +1 g | 256 (0x100) |
-1 g | 1792 (0x700) | ||
Расширенное разрешение: ±8 g (12 бит) | 3,9 mg/LSB | +1 g | 256 (0x100) |
-1 g | 3840 (0xF00) | ||
Расширенное разрешение: ±16 g (13 бит) | 3,9 mg/LSB | +1 g | 256 (0x100) |
-1 g | 7936 (0x1F00) |
Значения выходных данных могут варьироваться, и не совпадать для разных осей, при одинаковой величине ускорения. В этом случае для компенсации могут использоваться регистры смещения OFSX, OFSY, OFSZ для каждой оси. Например, необходимо уменьшить значение выходных данных по оси Z на 80 mg, так как расчетный коэффициент регистра смещения составляет 15,6 mg/LSB, величина смещения составит 80/15,6=5. Смещение прибавляется к регистру выходных данных, поэтому для его уменьшения используем отрицательно число -5. В регистр смещения записываем число 251 (0xFB).
Подключение ADXL345 к микроконтроллеру
Я подключил акселерометр к микроконтроллеру PIC16F628A, для вывода данных измерения использовал графический дисплей Nokia 5110, схема подключения ADXL345 приведена ниже:
Светодиод HL1 служит индикатором, и мигает в процессе передачи данных.
Часть кода программы представлена ниже (полный код доступен для скачивания в конце статьи):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #include <P16F628A.INC> LIST p=16F628A __CONFIG H'3F18' ;Конфигурация микроконтроллера Sec equ 20h ;вспомогательный регистр счета Sec1 equ 21h ;вспомогательный регистр счета nomer equ 22h ;регистр хранения кода ascii символа scetbit equ 23h ;регистр счета кол-ва бит perem equ 24h ;вспомогательный регистр приема/передачи байта по spi temp equ 25h ;вспомогательный регистр счета tmp_symb equ 26h ;вспомогательный регистр счета для таблицы данных shet equ 27h ;регистры подпрограммы преобразования двоичного числа bcd1 equ 28h ;в десятичное bcd2 equ 29h ; bcd3 equ 2Ah ; rezLH equ 2Bh ; rezLL equ 2Ch ; data_x0 equ 30h ;регистры приема и передачи данных по SPI для акселерометра data_x1 equ 31h ; data_y0 equ 32h ; data_y1 equ 33h ; data_z0 equ 34h ; data_z1 equ 35h ; kol_byte equ 36h ;счетчик кол-ва байт для приема/передачи по SPI adr_byte equ 37h ;регистр адреса для приема/передачи по SPI #DEFINE res_lcd PORTB,4 ;присвоение названий линиям ввода-вывода #DEFINE cs PORTB,5 ;для работы с LCD дисплеем #DEFINE dat_com PORTB,6 ; #DEFINE sdata PORTB,7 ; #DEFINE sclk PORTA,1 ; #DEFINE int_1 PORTB,0 ;присвоение названий линиям ввода-вывода #DEFINE cs_aks PORTB,1 ;для работы с акселерометром ADXL345 #DEFINE sda_aks PORTB,2 ; #DEFINE scl_aks PORTB,3 ; #DEFINE led PORTA,0 ;светодиод индикации передачи данных ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0000h ;начать выполнение программы с адреса 0000h goto Start ;переход на метку Start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Основная программа Start movlw b'00000010' ;установка значений выходных защелок порта A movwf PORTA ; movlw b'00111110' ;установка значений выходных защелок порта B movwf PORTB ; movlw b'00000111' ;выключение компараторов movwf CMCON ; bsf STATUS,RP0 ;выбрать 1-й банк movlw b'00000001' ;настройка линий ввода\вывода порта B movwf TRISB ;RB0 - на вход, остальные на выход movlw b'11111100' ;настройка линий ввода\вывода порта A movwf TRISA ;RA0, RA1 на выход, остальные на вход bcf STATUS,RP0 ;выбрать 0-й банк call init_lcd ;вызов подпрограммы инициализации дисплея call clear_lcd ;вызов подпрограммы очистки дисплея call viv_not ;вывод на дисплей сообщения "--- " call paus_aks ;вызов подпрограммы паузы для полного включения акселерометра call aks_init ;вызов подпрограммы инициализации акселерометра ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; met_1 btfss int_1 ;опрос линии прерывания акселерометра goto met_1 ;нет прерывания: переход на метку met_1 bsf led ;получено прерывание, включаем светодиод movlw .50 movwf adr_byte ;адрес первого регистра результата измерения movlw .6 movwf kol_byte ;считать 6 байт call priem_spi ;вызов подпрограммы чтения по spi ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; call ust_cur_1 ;вызов подпрограммы установки курсора в позицию X0-Y0 movlw 'X' ;вывод символа 'X' call viv_symb ; movlw ':' ;вывод символа ':' call viv_symb ; movf data_x0,W ;Загрузка двоичных значений ускорения по оси X movwf rezLL ;в регистры подпрограммы двоично-десятичное преобраз. movf data_x1,W ; movwf rezLH ; btfss rezLH,1 ;проверка отрицательного числа goto met_2 ;число положительное, переход на метку met_2 movlw '-' ;число отрицательное, вывод символа '-' call viv_symb ; comf rezLL,F ;инвертирование значения ускорения comf rezLH,W ; andlw b'00000011' ;обнуление незначащих битов movwf rezLH ; movlw .1 ;прибавление числа 1, для получения положительного addwf rezLL,F ;числа btfsc STATUS,C ; incf rezLH,F ; goto met_3 ;переход на метку met_3 met_2 movlw ' ' ;вывод символа ' ' call viv_symb ; movlw b'00000011' ;обнуление незначащих битов andwf rezLH,F met_3 call bin2bcd ;вызов подпрограммы двоичо-десятичного преобразования call vivod_usk ;вызов подпрограммы вывода на дисплей значения ускорения ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; call ust_cur_2 ;вызов подпрограммы установки курсора в позицию X0-Y1 movlw 'Y' ;вывод символа 'Y' call viv_symb ; movlw ':' ;вывод символа ':' call viv_symb ; movf data_y0,W ;Загрузка двоичных значений ускорения по оси Y movwf rezLL ;в регистры подпрограммы двоично-десятичное преобраз. movf data_y1,W ; movwf rezLH ; btfss rezLH,1 ;проверка отрицательного числа goto met_4 ;число положительное, переход на метку met_4 movlw '-' ;число отрицательное, вывод символа '-' call viv_symb ; comf rezLL,F ;инвертирование значения ускорения comf rezLH,W ; andlw b'00000011' ;обнуление незначащих битов movwf rezLH ; movlw .1 ;прибавление числа 1, для получения положительного addwf rezLL,F ;числа btfsc STATUS,C ; incf rezLH,F ; goto met_5 ;переход на метку met_5 met_4 movlw ' ' ;вывод символа ' ' call viv_symb ; movlw b'00000011' ;обнуление незначащих битов andwf rezLH,F met_5 call bin2bcd ;вызов подпрограммы двоичо-десятичного преобразования call vivod_usk ;вызов подпрограммы вывода на дисплей значения ускорения call ust_cur_3 ;вызов подпрограммы установки курсора в позицию X0-Y2 movlw 'Z' ;вывод символа 'Z' call viv_symb ; movlw ':' ;вывод символа ':' call viv_symb ; movf data_z0,W ;Загрузка двоичных значений ускорения по оси Z movwf rezLL ;в регистры подпрограммы двоично-десятичное преобраз. movf data_z1,W ; movwf rezLH ; btfss rezLH,1 ;проверка отрицательного числа goto met_6 ;число положительное, переход на метку met_6 movlw '-' ;число отрицательное, вывод символа '-' call viv_symb ; comf rezLL,F ;инвертирование значения ускорения comf rezLH,W ; andlw b'00000011' ;обнуление незначащих битов movwf rezLH ; movlw .1 ;прибавление числа 1, для получения положительного addwf rezLL,F ;числа btfsc STATUS,C ; incf rezLH,F ; goto met_7 ;переход на метку met_7 met_6 movlw ' ' ;вывод символа ' ' call viv_symb ; movlw b'00000011' ;обнуление незначащих битов andwf rezLH,F met_7 call bin2bcd ;вызов подпрограммы двоичо-десятичного преобразования call vivod_usk ;вызов подпрограммы вывода на дисплей значения ускорения bcf led ;выключаем светодиод goto met_1 ;переход на метку met_1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vivod_usk movf bcd1,W ;извлечения разряда десятков тысяч andlw b'00001111' ; addlw .48 ; call viv_symb ;вызов подпрограммы вывода символа на дисплей swapf bcd2,W ;извлечения разряда тысяч andlw b'00001111' ; addlw .48 ; call viv_symb ;вызов подпрограммы вывода символа на дисплей movf bcd2,W ;извлечения разряда сотен andlw b'00001111' ; addlw .48 ; call viv_symb ;вызов подпрограммы вывода символа на дисплей swapf bcd3,W ;извлечения разряда десятков andlw b'00001111' ; addlw .48 ; call viv_symb ;вызов подпрограммы вывода символа на дисплей movf bcd3,W ;извлечения разряда единиц andlw b'00001111' ; addlw .48 ; call viv_symb ;вызов подпрограммы вывода символа на дисплей return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма инициализации акселерометра aks_init movlw .49 movwf adr_byte ;адрес регистра DATA_FORMAT movlw .1 movwf kol_byte ;передача одного байта movlw b'01000000' ;самотестирование self-test отключено, 3-х проводной режим SPI, movwf data_x0 ;активный уровень выхода прерываний - высокий, разрешение 10 бит, ;правое выравнивание результата, предел измерения 2g call send_spi ;вызов подпрограммы записи по spi movlw .44 movwf adr_byte ;адрес регистра BW_RATE movlw .1 movwf kol_byte ;передача одного байта movlw b'00000111' ;нормальный режим работы (пониженное потребление выключено), movwf data_x0 ;частота дискретизации 12,5 Гц (частота обновления результата измерения) call send_spi ;вызов подпрограммы записи по spi movlw .46 movwf adr_byte ;адрес регистра INT_ENABLE (настройка прерываний) movlw .1 movwf kol_byte ;передача одного байта movlw b'10000000' ;разрешить прерывание по готовности результата измерения DATA_READY, movwf data_x0 ;остальные прерывания запрещены call send_spi ;вызов подпрограммы записи по spi movlw .30 movwf adr_byte ;адрес регистра OFSX (смещение по оси X) movlw .3 movwf kol_byte ;передача трех байт movlw .26 ; movwf data_x0 ;смещение для оси X (регистр OFSX) movlw .12 ; movwf data_x1 ;смещение для оси Y (регистр OFSY) movlw .150 ; movwf data_y0 ;смещение для оси Z (регистр OFSZ) call send_spi ;вызов подпрограммы записи по spi movlw .45 movwf adr_byte ;адрес регистра POWER_CTL movlw .1 movwf kol_byte ;передача одного байта movlw b'00001000' ;связь событий активности и бездействия выключена, режим автоматического movwf data_x0 ;перехода в сон отключен, активировать режим измерения, спящий режим выключен, ;частота дискретизации для спящего режима 8 Гц call send_spi ;вызов подпрограммы записи по spi return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма приема данных по SPI priem_spi bsf adr_byte,7 ;установка бита RW для операции чтения по spi movf kol_byte,W ;проверка кол-ва байт для приема sublw .1 btfss STATUS,C goto pri_2 btfss STATUS,Z return ;кол-во байт для приема равно 0:выход из подпрограммы bcf adr_byte,6 ;сбрасываем бит MB, читаем только один байт данных goto pri_3 pri_2 bsf adr_byte,6 ;устанавливаем бит MB, читаем несколько байт данных pri_3 bsf STATUS,RP0 ;перенастройка линии sda_aks на выход bcf TRISB,2 bcf STATUS,RP0 bcf cs_aks ;сбрасываем линию выбора CS, начало передачи данных movf adr_byte,W call send_sp ;передача адреса регистра акселерометра bsf STATUS,RP0 ;перенастройка линии sda_aks на вход bsf TRISB,2 bcf STATUS,RP0 movlw data_x0 ;установка начального регистра для приема данных movwf FSR decf FSR,F pri_1 incf FSR,F call priem_sp ;вызов подпрограммы приема данных movwf INDF decfsz kol_byte,F goto pri_1 bsf cs_aks ;поднимаем линию выбора CS return priem_sp movlw .8 ;подпрограмма приема байта по spi movwf scetbit povtor1 bcf scl_aks rlf perem,F bsf scl_aks btfsc sda_aks bsf perem,0 btfss sda_aks bcf perem,0 decfsz scetbit,F goto povtor1 movf perem,W return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма передачи данных по SPI send_spi bcf adr_byte,7 ;сброс бита RW для операции записи по spi movf kol_byte,W ;проверка кол-ва байт для передачи sublw .1 btfss STATUS,C goto sen_2 btfss STATUS,Z return ;кол-во байт для передачи равно 0:выход из подпрограммы bcf adr_byte,6 ;сбрасываем бит MB, передаем только один байт данных goto sen_3 sen_2 bsf adr_byte,6 ;устанавливаем бит MB, передаем несколько байт данных sen_3 bsf STATUS,RP0 ;перенастройка линии sda_aks на выход bcf TRISB,2 bcf STATUS,RP0 bcf cs_aks ;сбрасываем линию выбора CS, начало передачи данных movf adr_byte,W call send_sp ;передача адреса регистра акселерометра movlw data_x0 ;установка начального регистра для передачи данных movwf FSR decf FSR,F sen_1 incf FSR,F movf INDF,W call send_sp ;передача данных на акселерометр decfsz kol_byte,F goto sen_1 bsf cs_aks ;поднимаем линию выбора CS return send_sp movwf perem ;подпрограмма отправки байта по spi movlw .8 movwf scetbit povtor bcf scl_aks btfsc perem,7 bsf sda_aks btfss perem,7 bcf sda_aks bsf scl_aks rlf perem,F decfsz scetbit,F goto povtor return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bin2bcd movlw .16 ;Подпрограмма преобразования двоичного числа movwf shet ;в десятичное clrf bcd1 ;Двухбайтное число предварительно загружается clrf bcd2 ;в регисты rezLH, rezLL clrf bcd3 ;Результат преобразования: goto bin2bcd_1 ;единицы в младшем полубайте bcd3 ;десятки в старшем полубайте bcd3 adjdec movlw 0x33 ;сотни в младшем полубайте bcd2 addwf bcd1,F ;тысячи в старшем полубайте bcd2 addwf bcd2,F ;десятки тысяч в младшем полубайте bcd1 addwf bcd3,F ; ; .................. .................. .................. End ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Я использовал 3-х проводной SPI интерфейс для связи с акселерометром. Для передачи и приема данных используются две подпрограммы send_spi и priem_spi. Перед вызовом подпрограмм, в регистр adr_byte записывается адрес регистра акселерометра, к которому идет обращение, в случае передачи/приема нескольких байт, этот адрес будет начальным. В регистр kol_byte необходимо записать количество байт данных для передачи/приема. Данные для передачи, необходимо размещать последовательно, начиная с регистра data_x0, при получении данных, они также помещаются в данные регистры, начиная data_x0.
После настройки регистров микроконтроллера, выполняется вызов подпрограммы инициализации акселерометра aks_init. Здесь настраиваются следующие режимы: 3-х проводной SPI, высокий активный уровень выхода прерываний, фиксированное разрешение 10 бит, предел ±2 g, правое выравнивание, частота измерения 12,5 Гц, нормальный режим работы, разрешение прерываний по обновлению данных (DATA_READY). Спящий режим, а также автоматический переход в сон отключен, установка режима измерения.
Кроме этого, в моем случае дополнительно задается смещение выходных данных. Дело в том, что имеющийся у меня экземпляр акселерометра выдавал ненулевые значения для величины ускорения 0 g, по оси X: -105, Y: -48, Z: 420. Для примера рассчитаю смещение для оси Z, здесь необходимо уменьшить значение на 420, расчетный коэффициент выходных данных 3,9 mg/LSB, для регистра смещения коэффициент равен 15,6 mg/LSB. Значение смещения составит (420*3,9)/15,6=105, в регистр OFSZ записываем отрицательное число 150 (0x96), для остальных осей расчет аналогичен.
После инициализации идет опрос линии прерывания, при появлении которого считывается 6 байт данных из регистров DATAX, DATAY, DATAZ, если значение отрицательное, выполняется инвертирование и прибавление единицы, для получения положительного значения. Кроме этого незначащие биты обнуляются согласно разрешению 10 бит, далее выполняется двоично-десятичное преобразование, и наконец, вывод символа оси, знака, и собственно результата измерения ускорения. Далее цикл начинается заново, с опроса линии прерывания.
Одна из моих конструкций с применением акселерометра, это RGB куб, который меняет цвет свечения в зависимости от ориентации в пространстве.
На следующем видеоролике можно увидеть показания ускорений, в зависимости от ориентации акселерометра:
Нужна помощь. Можете понятно обЪяснить (желательно с кодом для Arduino) как поменять частоту датчика.