Книга по работе с WinAVR и AVR Studio / AVR_14_2011
.pdf
СПРАВОЧНЫЙ МАТЕРИАЛ
|
|
Роман Абраш |
Книга по работе |
|||||
|
|
|
|
|
|
|
||
|
|
г. Новочеркасск |
с WinAVR и AVR Studio |
|||||
|
|
E-mail: arv@radioliga.com |
||||||
|
|
|
|
power_timer2_disable() – выключение |
|
clock_div_64 = 6, |
||
|
|
Продолжение. Начало |
|
|
||||
|
|
|
таймера 2 |
|
clock_div_128 = 7, |
|||
|
|
в №1-12/2010; №1/2011 |
|
|
||||
|
|
|
power_timer3_enable() – включение |
|
clock_div_256 = 8 |
|||
|
|
|
|
таймера 3 |
|
} clock_div_t; |
||
|
avr/power.h – Поддержка PRR |
power_timer3_disable() – выключение |
|
|
|
|
||
|
Некоторые модели микроконтроллеров |
таймера 3 |
|
и 2 макроса: |
||||
|
AVR имеют встроенный регистр PRR (Power |
power_timer4_enable() – включение |
|
clock_prescale_set(x) – установка зна- |
||||
|
Reduction Register – регистр снижения мощ- |
таймера 4 |
|
чения делителя частоты (х – одно из значе- |
||||
|
ности) или несколько таких регистров PRRn. |
power_timer4_disable() – выключение |
|
ний clock_div_t) |
||||
|
С их помощью имеется возможность отклю- |
таймера 4 |
|
clock_prescale_get() – получить значе- |
||||
|
чить часть неиспользуемой программой пе- |
power_timer5_enable() – включение |
|
ние текущего делителя (возвращаемый тип |
||||
|
риферии для снижения потребляемой мик- |
таймера 5 |
|
результата – clock_div_t) |
||||
|
роконтроллером мощности. |
power_timer5_disable() – выключение |
|
avr/sfr_defs.h – Регистры |
||||
|
Этот модуль определяет рад макросов, |
таймера 5 |
|
|||||
|
облегчающих использование PRR. Однако, |
power_twi_enable() – включение моду- |
|
специальных функций AVR |
||||
|
нормальное их функционирование возмож- |
ля TWI |
|
Данный модуль определяет символьные |
||||
|
но только для тех микроконтроллеров, ко- |
power_twi_disable() – выключение мо- |
|
имена для всех регистров специальных |
||||
|
торые действительно содержат этот регистр |
дуля TWI |
|
функций, а так же вводит ряд макросов, |
||||
|
(регистры) и соответствующую периферию; |
power_usart_enable() – включение мо- |
|
упрощающих типичные действия над бито- |
||||
|
кроме того, иногда одна и та же периферия |
дуля USART |
|
выми значениями этих регистров. |
||||
|
отличается в наименовании (например, |
power_usart_disable() – выключение |
|
Модуль подключается автоматически, |
||||
|
USART и USART0). |
модуля USART |
|
если подключен модуль avr/io.h – Специфич- |
||||
|
Здесь перечислены все соответствую- |
power_usart0_enable() – включение |
|
ные для AVR функции ввода-вывода, поэто- |
||||
|
щие макросы, однако о наличие поддерж- |
модуля USART0 |
|
му нет необходимости подключать его явно. |
||||
|
ки ими выбранного программистом микро- |
power_usart0_disable() – выключение |
|
Макросы |
||||
|
контроллера следует справляться в доку- |
модуля USART0 |
|
|||||
|
ментации. При попытке использовать непод- |
power_usart1_enable() – включение |
|
Все макросы определены, как макро- |
||||
|
держиваемый микроконтроллер будут воз- |
модуля USART1 |
|
сы-функции. |
||||
|
никать ошибки компиляции. |
power_usart1_disable() – выключение |
|
|
|
|
||
|
power_adc_enable() – включение встро- |
модуля USART1 |
|
_BV() |
||||
|
енного АЦП (не путать35 с битом ADEN в |
power_usart2_enable() – включение |
|
_BV(bit) – макрос, преобразующий но- |
||||
|
соответствующем регистре) |
модуля USART2 |
|
мер бита в битовую маску. Данная команда |
||||
|
power_adc_disable() –выключениеАЦП |
power_usart2_disable() – выключение |
|
используется для работы с битами SFR, |
||||
|
power_lcd_enable() – включение моду- |
модуля USART2 |
|
выполняя следующее действие: (1<<(bit)). |
||||
ля ЖКИ-драйвера |
power_usart3_enable() – включение |
|
|
|
|
|||
|
power_lcd_disable() – выключение мо- |
модуля USART3 |
|
bit_is_set() |
||||
дуля ЖКИ-драйвера |
power_usart3_disable() – выключение |
|
bit_is_set(sfr, bit) – макрос, возвращаю- |
|||||
|
power_psc0_enable() – включение мо- |
модуля USART3 |
|
щий логическое значение ИСТИНА, если бит |
||||
дуля Power Stage Controller 0 |
power_usb_enable() – включение моду- |
|
bit в указанном регистре sfr установлен. Ис- |
|||||
|
power_psc0_disable() – выключение |
ля USB |
|
пользуется для проверки состояния флагов. |
||||
модуля Power Stage Controller 0 |
power_usb_disable() – выключение |
|
|
|
|
|||
|
power_psc1_enable() – включение мо- |
модуля USB |
|
bit_is_clear() |
||||
дуля Power Stage Controller 1 |
power_usi_enable() – включение моду- |
|
bit_is_clear(sfr, bit) – макрос, возвраща- |
|||||
|
power_psc1_disable() – выключение |
ля USI |
|
ющий логическое значение ИСТИНА, если |
||||
модуля Power Stage Controller 1 |
power_usi_disable() – выключение мо- |
|
бит bit в регистре sfr не установлен. Исполь- |
|||||
|
power_psc2_enable() – включение мо- |
дуля USI |
|
зуется для проверки состояния флагов. |
||||
дуля Power Stage Controller 2 |
power_vadc_enable() – включение мо- |
|
|
|
|
|||
|
power_psc2_disable() – выключение |
дуля VADC |
|
loop_until_bit_is_set() |
||||
модуля Power Stage Controller 2 |
power_vadc_disable() – выключение |
|
loop_until_bit_is_set(sfr, bit) – макрос, |
|||||
|
power_spi_enable() – включение моду- |
модуля VADC |
|
выполняющий цикл ожидания (путем непре- |
||||
ля SPI |
power_all_enable() – включить все мо- |
|
рывного опроса соответствующего sfr) до |
|||||
|
power_spi_disable() – выключение мо- |
дули |
|
тех пор, пока бит bit в регистре sfr не будет |
||||
дуля SPI |
power_all_disable() – выключить все |
|
установлен. |
|||||
|
power_timer0_enable() – включение |
модули |
|
|
|
|
||
таймера 0 |
|
|
loop_until_bit_is_clear() |
|||||
|
power_timer0_disable() – выключение |
Некоторые модели AVR имеют регистр |
|
loop_until_bit_is_clear(sfr, bit) – макрос, |
||||
таймера 0 |
CLKPR предварительного деления тактовой |
|
выполняющий цикл ожидания (путем непре- |
|||||
|
power_timer1_enable() – включение |
частоты, при помощи которого так же мож- |
|
рывного опроса соответствующего sfr) до |
||||
таймера 1 |
но снижать потребляемую мощность. Для |
|
тех пор, пока бит bit в регистре sfr не будет |
|||||
|
power_timer1_disable() – выключение |
работы с этим регистром введен особый тип: |
|
сброшен. |
||||
таймера 1 |
typedef enum{ |
|
|
|
|
|||
|
power_timer2_enable() – включение |
clock_div_1 = 0, |
|
avr/sleep.h – Управление |
||||
таймера 2 |
clock_div_2 = 1, |
|
энергосберегающими режимами |
|||||
|
|
|
|
clock_div_4 = 2, |
|
и режимами «сна» |
||
|
|
|
|
|||||
|
35 Данное примечание относится и к другим макро- |
clock_div_8 = 3, |
|
В этом модуле определен ряд макро- |
||||
|
сам – они обеспечивают именно отключение/включение |
clock_div_16 = 4, |
|
сов и функций, реализующих общий интер- |
||||
|
питания соответствующей периферии при помощи регис- |
|
||||||
|
clock_div_32 = 5, |
|
фейс управления режимами «сна». |
|||||
|
тров PRR. |
|
||||||
5 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Радиолюбитель – 02/2011 |
|
|
|
|
|
|
|
|
|
|
СПРАВОЧНЫЙ МАТЕРИАЛ
Использование инструкции SLEEP по- |
avr/version.h – Контроль |
В приведенном примере для сохра- |
|
зволяет снизить общее энергопотребление |
версии avr-libc |
нения значения MCUSR использована |
|
в некоторых применениях. Микроконтрол- |
Модуль определяет несколько кон- |
переменная mcusr_mirror, которая не полу- |
|
леры AVR реализуют несколько различных |
стант, которые могут использоваться в |
чает значение 0 по умолчанию (характер- |
|
вариантов «сна», для которых в модуле оп- |
программе для проверки совместимости |
ное для Си-программ) – секция «.noinit». А |
|
ределены следующие константы (о поддер- |
исходного текста с используемой версией |
функция, которая осуществляет инициали- |
|
жке выбранным контроллером соответству- |
avr-libc. |
зацию этой переменной содержимым |
|
ющего режима следует справиться в доку- |
__AVR_LIBC_VERSION_STRING__ – |
MCUSR и одновременно запрещает рабо- |
|
ментации к контроллеру, не все константы |
строчное представление версии библиоте- |
ту WDT, get_mcusr() размещается в секции |
|
определены для любого контроллера): |
ки, например, ″1.6.2″ |
автоматической инициализации пользова- |
|
SLEEP_MODE_IDLE – режим «без- |
__AVR_LIBC_VERSION__ – версия биб- |
теля «.init3», т.е. будет выполнена сразу |
|
действия» Idle |
лиотеки в виде длинного целого числа без |
после инициализации стека. Функция не |
|
SLEEP_MODE_PWR_DOWN – режим |
знака, например, 10602UL |
имеет пролога и эпилога, поэтому ее код |
|
«отключения» Power Down |
__AVR_LIBC_DATE_STRING__ – строч- |
будет помещен в соответствующей секции |
|
SLEEP_MODE_PWR_SAVE – режим |
ное представление даты релиза библиоте- |
как inline. |
|
«экономии» Power Save |
ки (совпадает с релизом WinAVR), напри- |
Дополнительно о секциях памяти и по- |
|
SLEEP_MODE_ADC – режим «сниже- |
мер, ″20080403″ |
рядке их инициализации см. в главе Сек- |
|
ния шума АЦП» ADC Noise Reduction |
__AVR_LIBC_DATE__ - дата релиза |
ции памяти. |
|
SLEEP_MODE_STANDBY – режим |
библиотеки в виде длинного целого числа |
|
|
«ожидания» |
без знака, например, 20080403UL |
Макросы и константы модуля |
|
SLEEP_MODE_EXT_STANDBY – рас- |
__AVR_LIBC_MAJOR__ – версия биб- |
В модуле определен ряд констант для |
|
ширенный режим «ожидания» |
лиотеки, например, 1 |
задания периода переполнения WDT. Так |
|
Практическиуправлениережимомэнер- |
__AVR_LIBC_MINOR__ – «подверсия» |
как некоторые модели микроконтроллеров |
|
госбережения сводится к вызову макроса |
библиотеки, например, 6 |
могут иметь и другие значения программи- |
|
set_sleep_mode() для указания нужного ре- |
__AVR_LIBC_REVISION__ – номер ре- |
руемых периодов, реальное количество кон- |
|
жима и последующего включения этого ре- |
лиза подверсии, например, 2 |
стант может быть другим (нетрудно выяс- |
|
жима макросом sleep_mode(). Следует по- |
|
нить, взглянув в содержимое файла wdh.h). |
|
мнить, что если нет необходимости остано- |
avr/wdt.h – Поддержка WDT AVR |
Из наименования константы очевидно ее |
|
вить работу микроконтроллера вплоть до |
Модуль реализует необходимый и дос- |
смысловое значение, поэтому детальное |
|
аппаратного сброса, необходимо разрешить |
таточный минимум макросов, при помощи |
описание не приводится. |
|
прерывания до выполнения этих макросов. |
которых реализуется взаимодействие со |
WDTO_15MS |
|
В некоторых случаях может потребо- |
сторожевым таймером (WDT) любого мик- |
WDTO_30MS |
|
ваться большая гибкость в управлении ре- |
роконтроллера AVR. |
WDTO_60MS |
|
жимами экономии, для чего предусмотре- |
Для работы с WDT требуется выпол- |
WDTO_120MS |
|
ны отдельные функции sleep_enable(), |
нение определенной четко регламентиро- |
WDTO_250MS |
|
sleep_disable() и sleep_cpu(). |
ванной процедуры, которую макросы реа- |
WDTO_500MS |
|
|
лизуют автоматически. В частности, в нуж- |
WDTO_1S |
|
Функции и макросы модуля |
ных случаях на время происходит глобаль- |
WDTO_2S |
|
|
ное запрещение прерываний. Програм- |
WDTO_4S |
|
set_sleep_mode() |
мист может не беспокоиться о дополни- |
WDTO_8S |
|
set_sleep_mode(mode) – макрос, подго- |
тельных действиях, используя предлагае- |
|
|
тавливающий микроконтроллер к заданно- |
мые макросы. |
Так же в модуле определены три мак- |
|
му режиму сна. Параметр mode – одна из |
Единственное, о чем следует помнить, |
роса типа функция. |
|
определенных ранее констант режима. Этот |
это особенность, присущая новым моделям |
|
|
макрос эквивалентен переходу в режим Idle, |
микроконтроллеров (например, ATMega88 |
wdt_enable() |
|
т.е. остановки тактового генератора и от- |
и т.п.): после аппаратного сброса WDT про- |
wdt_enable(value) – макрос, включаю- |
|
ключения периферии, если это требуется |
должает работать, причем с минимальным |
щий WDT с периодом переполнения, задан- |
|
режимом, не происходит. Для полноценно- |
предделителем (обычно, период WDT со- |
ным значением value, которое должно быть |
|
го включения режима требуется второй |
ставляет 15 мс). Поэтому следует выклю- |
одной из рассмотренных ранее констант |
|
макрос sleep_mode() |
чать его (если нужно) как можно раньше. |
WDTO_xxxS. |
|
|
При этом может потребоваться особый под- |
|
|
sleep_mode() |
ход для того, чтобы определить причину |
wdt_reset() |
|
sleep_mode() – макрос, переводящий |
аппаратного сброса. Рекомендуется при- |
wdt_reset() – макрос, осуществляющий |
|
микроконтроллер в режим сна. Его реали- |
держиваться следующего подхода (см. |
сброс счетчика WDT, эквивалент инструк- |
|
зация такова, что программист вправе счи- |
врезку): |
ции WDR. |
|
тать, что «возврат» из макроса произойдет |
|
|
|
уже после «пробуждения» контроллера. |
#include <stdint.h> |
|
|
|
|
||
sleep_enable() |
#include <avr/wdt.h> |
|
|
// объявление «неинициализируемой» переменной |
|
||
void sleep_enable(void) – функция, уста- |
|
||
uint8_t mcusr_mirror _attribute_ ((section (І.noinitІ))); |
|||
навливающая бит разрешения режима сна |
|||
|
|
||
(SE-бит) |
// объявление функции «запоминания» значения MCUSR |
||
|
|||
sleep_disable() |
void get_mcusr(void) \ |
|
|
__attribute__((naked)) \ /* без пролога и эпилога */ |
|||
void sleep_disable(void) – функция, сбра- |
|||
__attribute__((section(І.init3І))); /* в секции автоматической инициализации пользователя */ |
|||
сывающая бит разрешения режима сна (SE- |
|||
|
|
||
бит) |
void get_mcusr(void){ |
|
|
|
|
||
sleep_cpu() |
mcusr_mirror = MCUSR; |
|
|
MCUSR = 0; |
|
||
void sleep_cpu(void) – функция, «усып- |
|
||
wdt_disable(); |
|
||
ляющая» микроконтроллер, т.е. эквивален- |
|
||
} |
|
||
тная команде SLEEP |
|
||
|
|
||
|
|
|
5 9 |
Радиолюбитель – 02/2011 |
|
|
|
|
|
|
СПРАВОЧНЫЙ МАТЕРИАЛ
wdt_disable() |
началом (внутри атомарного блока преры- |
правильное значение CRC входило в со- |
||||
wdt_disable() – макрос, выключающий |
вания, разумеется, запрещены). |
став обрабатываемого блока данных. |
||||
WDT. Если WDT включен постоянно (т.е. так |
|
|
|
|||
задано fuse-битами), этот макрос, есте- |
ATOMIC_FORCEON |
Функции модуля |
||||
ственно, не выполняет своей функции. |
ATOMIC_FORCEON – константа для |
|
|
|||
|
|
|
использования в качестве параметра мак- |
_crc16_update() |
||
ВСПОМОГАТЕЛЬНЫЕ МОДУЛИ |
роса ATOMIC_BLOCK(). Указывает, что в |
uint16_t _crc16_update (uint16_t crc, |
||||
К вспомогательным модулям отнесены |
конце атомарного блока прерывания про- |
uint8_t data) |
||||
те из входящих в AVR-LIBC, которые слу- |
сто должны быть принудительно разреше- |
Параметры: |
||||
жат для упрощения некоторых действий, |
ны. Использование этого параметра позво- |
uint16_t crc – текущее значение CRC |
||||
часто необходимых в системах на базе мик- |
ляет несколько сократить объем кода и по- |
uint8_t data – байт данных |
||||
роконтроллеров AVR. Это сервисные функ- |
высить скорость исполнения атомарного |
Возвращаемое значение: новое зна- |
||||
ции и функции, разработанные по инициа- |
блока, однако программист должен быть |
чение CRC |
||||
тиве сообщества программистов (GCC и |
уверен, что глобальное разрешение преры- |
Описание: функция подсчета 16-раз- |
||||
WinAVR – это открытый проект, любой доб- |
ваний после атомарного блока – это дей- |
рядной контрольной суммы по полиному, |
||||
роволец имеет возможность пополнить их |
ствительно то, что он хочет. |
типичному для дисковых накопителей x16 + |
||||
функциональность, если она одобрена ос- |
|
x15 + x2 + 1 (0xА001). Для верного подсчета |
||||
тальным сообществом). |
NONATOMIC_RESTORESTATE |
контрольной суммы начальное значение crc |
||||
|
|
|
NONATOMIC_RESTORESTATE – кон- |
должно быть 0xFFFF. |
||
util/atomic.h – Атомарные и |
станта для использования в качестве пара- |
|
|
|||
неатомарные участки кода |
метра макроса NONATOMIC_BLOCK(). Ука- |
_crc_xmodem_update() |
||||
Модуль реализует средства управления |
зывает на то, что перед началом не-атомно- |
uint16_t _crc_xmodem_update (uint16_t |
||||
«атомарностью»36 участков кода. |
го блока должно быть сохранено значение |
crc, uint8_t data) |
||||
Данный модуль использует расширения |
SREG, а после его завершения – восстанов- |
Параметры: |
||||
СИ, вводимые стандартом ISO C99, и по- |
лено.Этогарантирует,чтоблокдействитель- |
uint16_t crc – текущее значение CRC |
||||
этому может использоваться только с оп- |
но будет выполнен не атомарно, при этом |
uint8_t data – байт данных |
||||
цией компилятора–std=с99или–std=gnu99. |
состояние флага глобального разрешения |
Возвращаемое значение: новое зна- |
||||
|
|
|
прерываний после блока будет таким же, как |
чение CRC |
||
Определения модуля |
и перед ним (внутри не-атомарного блока |
Описание: функция подсчета 16-раз- |
||||
|
|
|
прерывания, естественно, разрешены). |
рядной контрольной суммы по полиному, |
||
ATOMIC_BLOCK() |
|
требуемому протоколом Xmodem x16 + x12 + |
||||
ATOMIC_BLOCK(type) – макрос, слу- |
NONATOMIC_FORCEOFF |
x5 + 1 (0x1021). Для верного подсчета конт- |
||||
жащий для определения блока кода, ог- |
NONATOMIC_FORCEOFF – константа |
рольной суммы начальное значение crc |
||||
раниченного фигурными скобками, как |
для использования в качестве параметра |
должно быть 0. |
||||
исполняющегося атомарно. В качестве |
макроса NONATOMIC_BLOCK(). Указывает |
|
|
|||
параметра type должна использоваться |
на то, что по завершению не-атомарного |
_crc_ccitt_update() |
||||
константа ATOMIC_FORCEON или |
блока прерывания просто должны быть при- |
uint16_t _crc_ccitt_update (uint16_t crc, |
||||
ATOMIC_RESTORESTATE. |
нудительно запрещены. Использование это- |
uint8_t data) |
||||
Пример использования макроса: |
го параметра позволяет несколько сокра- |
Параметры: |
||||
|
|
|
тить объем кода и повысить скорость испол- |
uint16_t crc – текущее значение CRC |
||
ATOMIC_BLOCK(ATOMIC_FORCEON){ |
|
нения не-атомарного блока, однако про- |
uint8_t data – байт данных |
|||
ctr_copy = ctr; |
|
граммист должен быть уверен, что глобаль- |
Возвращаемое значение: новое зна- |
|||
} |
|
|
ное запрещение прерываний после не-ато- |
чение CRC |
||
|
|
|
марного блока – это действительно то, что |
Описание: функция подсчета 16-раз- |
||
|
|
|
||||
NONATOMIC_BLOCK() |
он хочет. |
рядной контрольной суммы по полиному, |
||||
NONATOMIC_BLOCK(type) – макрос, |
Важной особенностью ATOMIC-блоков |
требуемому стандартом CCITT (использует- |
||||
служащий для определения блока кода, |
кода является то, что внутри могут быть ис- |
ся в протоколах PPP и IrDA) x16 + x12 + x5 + 1 |
||||
ограниченного фигурными скобками, как |
пользованы любые операторы Си, в том чис- |
(0x8408). Для верного подсчета контрольной |
||||
исполняющегося «не атомарно» (см. |
ле break и return, при этом состояние аппа- |
суммы начальное значение crc должно быть |
||||
ATOMIC_BLOCK()). Это может потребовать- |
рата прерываний будет корректно востанов- |
0xFFFF. |
||||
ся, если внутри большого атомарного блока |
лено при исполнении этих операторов. |
Примечание: хотя полином выглядит |
||||
есть участки, не требующие атомарности. |
|
точно так же, как и для Xmodem, существу- |
||||
|
|
|
util/crc16.h – Вычисления CRC |
ет принципиальная разница в алгоритме |
||
ATOMIC_RESTORESTATE |
Модуль содержит определения несколь- |
вычисления CRC, связанная с порядком |
||||
ATOMIC_RESTORESTATE – константа |
ких inline-функций для быстрого вычисле- |
поступления битов на обработку (старший- |
||||
для использования в качестве параметра |
ния циклических контрольных сумм (CRC) |
младший). |
||||
макроса ATOMIC_BLOCK(). Указывает, что |
по широкоизвестным полиномам. |
|
|
|||
в начале блока состояние SREG должно |
Алгоритм использования этих функций |
_crc_ibutton_update() |
||||
быть запомнено, а в конце блока – восста- |
для контроля целостности блока данных |
uint8_t _crc_ibutton_update (uint8_t crc, |
||||
новлено в прежнем виде. Это гарантирует, |
(основное назначение CRC) в общем слу- |
uint8_t data) |
||||
что состояние флага глобального разреше- |
чае следующий: |
Параметры: |
||||
ния прерываний после завершения атомар- |
- вводится переменная, например, |
uint8_t crc – текущее значение CRC |
||||
ного блока будет таким же, как и перед его |
C_R_C (ей должно быть присвоено строго |
uint8_t data – байт данных |
||||
|
|
|
определенное начальное значение) |
Возвращаемое значение: новое зна- |
||
36 Полноценное определение термина «атомарный» |
||||||
- последовательно для каждого из зна- |
чение CRC |
|||||
не приводится, в данном контексте можно считать, что это |
||||||
чений проверяемого блока вызывается со- |
Описание: функция подсчета 8-разряд- |
|||||
означает исполнение одного или более операторов Си как |
||||||
одной команды, т.е. без возможности прерывания посере- |
ответствующая функция, которая модифи- |
ной контрольной суммы по полиному, ис- |
||||
дине участка. Не смотря на кажущуюся странность этого |
цирует значение переменной C_R_C |
пользуемому в приборах iButton37 x8 + x5 + |
||||
термина в применении к одному оператору, это так: опе- |
||||||
ратор long tmp = 0; фактически будет оттранслирован в 5 |
- после того, как все данные «обсчи- |
x4 + 1 (0x8C). Для верного подсчета конт- |
||||
ассемблерных инструкций, исполняемых последователь- |
таны» сравнение полученного значения |
рольной суммы начальное значение crc |
||||
но; между ними вполне возможно возникновение преры- |
C_R_C с заранее известным (правиль- |
должно быть 0. |
||||
вания, что будет соответствовать прерыванию «в середи- |
||||||
ным) значением CRC или нулем, если |
|
|
||||
не» оператора. |
37 Зарегистрированная торговая марка Maxim-Dallas. |
|||||
6 0 |
Радиолюбитель – 02/2011 |
|
СПРАВОЧНЫЙ МАТЕРИАЛ
util/delay.h – Реализация |
F_CPU миллисекунд (где F_CPU в мегагер- |
Реализуется это несколько необычным спо- |
|
задержек программными |
цах). Программист не обязан следить за |
собом. |
|
циклами |
тем, чтобы параметр ms находился в допу- |
Перед подключением модуля следует |
|
Модуль определяет функции, являющи- |
стимых пределах – если его значение ока- |
определить две константы: F_CPU (такто- |
|
еся всего лишь более удобной «оберткой» |
жется больше, чем допустимо, произойдет |
вая частота микроконтроллера в герцах) и |
|
базовым функциям задержек программны- |
автоматическое снижение точности выдер- |
BAUD (желаемая скорость работы UART в |
|
ми циклами (см. util/delay_basic.h – Базовые |
жки интервала (никаких уведомлений об |
бодах). Так же можно дополнительно опре- |
|
задержки программными циклами). Для |
этом не происходит), таким образом, функ- |
делить значение BAUD_TOL, которое зада- |
|
нормального функционирования функций |
ция сможет реализовывать задержки |
ет допустимую погрешность скорости в про- |
|
необходимо, чтобы было определено зна- |
вплоть до 65535 секунд. |
центах (по умолчанию 2%). После опреде- |
|
чение константы F_CPU, равное тактовой |
|
ления этих констант следует подключить мо- |
|
частоте микроконтроллера в герцах, до под- |
util/delay_basic.h – Базовые за- |
дуль setbaud.h, т.е. например, так: |
|
ключения модуля. Возможно определить эту |
держки программными циклами |
|
|
|
|||
константу внутри make-файла или, что то |
Модуль определяет две базовых inline- |
#include <avr/io.h> |
|
же самое, непосредственно в параметрах |
функции задержек программным циклом |
|
|
компилятора. |
известной длительности, которые предназ- |
#define F_CPU 4000000 // указали тактовую |
|
Функции задержек реализованы следу- |
начены для получения очень коротких и точ- |
частоту контроллера |
|
ющим образом. По значению задержки, |
ных задержек, и активно используются фун- |
|
|
полученному как параметр функции (в виде |
кциями _delay_us() и _delay_ms(). |
static void uart_9600(void){ |
|
константы) на этапе компиляции вычисля- |
Функции не выполняют запрещения |
#define BAUD 9600 |
|
ется количество пустых программных цик- |
прерываний на время своей работы. Поэто- |
#include <util/setbaud.h> |
|
лов, которые при заданной тактовой часто- |
му следует учитывать, что это может повли- |
UBRRH = UBRRH_VALUE; |
|
те нужно выполнить для получения этой за- |
ять на точность формируемых задержек. |
UBRRL = UBRRL_VALUE; |
|
держки. В итоге компилятор строит код, ко- |
Для организации длительных задержек |
#if USE_2X |
|
торый и выполняет эту задачу. |
более эффективно использование аппарат- |
UCSRA |= (1 << U2X); |
|
Чтобы это было возможно, необходи- |
ных таймеров. |
#else |
|
мо, чтобы вычисления над константами с |
|
UCSRA &= ~(1 << U2X); |
|
плавающей точкой были проведены на эта- |
Функции модуля |
#endif |
|
пе компиляции, т.е. необходимо, чтобы была |
|
} |
|
включена оптимизация при компиляции. |
_delay_loop_1() |
|
|
Если проект скомпилирован при отключен- |
void _delay_loop_1 (uint8_t count) |
static void uart_38400(void){ |
|
ной оптимизации – задержки, обеспечива- |
Описание: функция обеспечивает ис- |
#undef BAUD // отменим определение, чтобы |
|
емые функциями, не гарантируются. |
полнение count раз (от 1 до 256) наикрат- |
избежать предупреждения компилятора |
|
Таким образом, для использования мо- |
чайшего цикла со счетчиком (т.е. одна ите- |
#define BAUD 38400 |
|
дуля delay.h необходимо выполнить 2 ус- |
рация цикла длится 3 машинных такта). |
#include <util/setbaud.h> |
|
ловия: |
Дополнительно тратится время на инициа- |
UBRRH = UBRRH_VALUE; |
|
1. Объявить F_CPU, равное тактовой |
лизацию задействованного счетного реги- |
UBRRL = UBRRL_VALUE; |
|
частоте контроллера в герцах до подклю- |
стра. |
#if USE_2X |
|
чения модуля |
Примечание: для организации 256 по- |
UCSRA |= (1 << U2X); |
|
2. Включить оптимизацию (любого уров- |
вторений цикла следует передать в функ- |
#else |
|
ня) при компиляции. |
цию параметр ноль. |
UCSRA &= ~(1 << U2X); |
|
Примечание: функции реализуют за- |
|
#endif |
|
держки путем программных циклов, кото- |
_delay_loop_2() |
} |
|
рые могут быть могут быть прерваны зап- |
void _delay_loop_2 (uint16_t count) |
|
|
|
|||
росом прерывания. Разумеется, в этом слу- |
Описание: функция обеспечивает ис- |
В приведенном примере показано оп- |
|
чае длительность задержки окажется боль- |
полнение count раз (от 1 до 65536) наикрат- |
ределение двух функций, которые настра- |
|
ше заданного значения, и чем чаще проис- |
чайшего цикла со счетчиком (т.е. одна ите- |
ивают UART на скорости 9600 и 38400 бод |
|
ходят прерывания и чем сложнее (т.е. дли- |
рация цикла длится 4 машинных такта). |
соответственно. Делается это путем пере- |
|
тельнее) обработчики прерываний, тем эта |
Дополнительно тратится время на инициа- |
определения вышеупомянутых констант и |
|
погрешность выше. |
лизацию задействованного счетного реги- |
многократного подключения модуля |
|
|
стра. |
setbaud.h. |
|
Функции модуля |
Примечание: для организации 65536 |
В самом модуле на основании задан- |
|
|
повторений цикла следует передать в фун- |
ных констант производится расчет значе- |
|
_delay_us() |
кцию параметр ноль. |
ний других констант, которые затем исполь- |
|
void _delay_us(double us) |
|
зуются для инициализации UBRR и UCSRA. |
|
Описание: функция осуществляет за- |
util/parity.h – Генерация битов |
Таким образом, модуль использует ряд |
|
держку в us микросекунд. Максимально |
четности |
«входных» определений, формируя рад |
|
возможное значение задержки 768 / F_CPU |
Модуль определяет единственный мак- |
«выходных»: |
|
микросекунд (где F_CPU в мегагерцах). |
рос, реализующий оптимизированную ас- |
UBRR_VALUE – значение для записи в |
|
Программист не обязан следить за тем, что- |
семблерную функцию вычисления бита чет- |
UBRR |
|
бы параметр us находился в допустимых |
ности для байта данных (может использо- |
UBRRL_VALUE – значение для записи |
|
пределах – если его значение окажется |
ваться при обмене по UART). |
в UBRRL |
|
больше, чем допустимо, вызов функции ав- |
|
UBRRH_VALUE – значение для записи |
|
томатически будет перенаправлен в функ- |
parity_even_bit() |
в UBRRH |
|
цию _delay_ms() (никаких уведомлений об |
parity_even_bit(val) – макрос, возвраща- |
USE_2X – логический флаг, определя- |
|
этом не осуществляется). |
ющий 1, если число единиц a байте val не- |
ющий необходимость установки бита U2X |
|
|
четное. |
в регистре UCSRA. |
|
_delay_ms() |
|
|
|
void _delay_ms(double ms) |
util/setbaud.h – Упрощение |
|
|
Описание: функция осуществляет за- |
вычисления скоростей UART |
|
|
держку в ms миллисекунд. Максимально |
Модуль облегчает расчет значений ре- |
|
|
Продолжение в №3/2011 |
|||
возможное значение задержки 262.14 / |
гистров управления аппаратного UART. |
|
|
|
6 1 |
Радиолюбитель – 02/2011 |
|
|
|
|
|
|
