Страницы

вторник, 15 января 2013 г.

Миландр MDR32F9Q2I. ASM. Средства разработки на ассемблере


Миландр MDR32F9Q2I. ASM. Средства разработки на ассемблере
С целью изучения сред программирования для микроконтроллеров ARM Cortex-M3 Миландр MDR32F9Q2I, кратко рассмотрены интегрированные пакеты и их ассемблеры. 
Микроконтроллеры были приобретены у производителя. Была сделана  небольшая отладочная плата, заказана в производстве. Пока делают печатные платы, спаял на макетке. Подключил UART. Сделал прототипы загрузчика для загрузки по UART на Python и C# Visual Studio 2010 Express. В планах подключить открытые JTAG-средства. Выбираю ассемблер, смотрю на спецификацию.

Страница микроконтроллера на сайте производителя:

Форум на сайте производителя:


Отечественная интегрированная среда Phyton CodeMaster-ARM

Поставляется с отладочными платами от производителя.
Содержит собственный ассемблер mcaarm.exe. Ассемблер содержит собственный формат директив. Со средой поставляется описание ассемблера на русском языке, что является несомненным плюсом для начинающих. Ассемблер среды Phyton CodeMaster-ARM, поддерживает синтаксис UML.

ARM MACRO ASSEMBLER Version 1.01.101130 Demo
Copyright (C) 2009 Phyton, Inc.


Среда разработки IAR IAR Embedded workbench (EWBAR)

Среда поставляется с собственным ассемблером IASMARM. Ассемблер имеет собственный синтаксис директив. Синтаксис директив в чём то похож, на синтаксис ассемблера Keil, что потенциально позволяет производить перенос кода с одного ассемблера на другой - с небольшими правками, в основном касающимися синтаксиса директив, макросов и пр., оставляя мнемокоды UML нетронутыми.


Среда разработки Keil uVision v.4

Keil uVision - набор инструментов, для разработки программ на компьютерных языках C, C++, ассемблер (UAL) для микроконтроллеров, в том числе с ядром ARM Cortex-M3.
В наборе инструментов Keil присутствует ассемблер armasm, а также встроенный оптимизированный ассемблер, для разбора инструкций включённых в текст программы на языке CИ. Ассемблер имеет собственный синтаксис директив. Поддерживает UAL синтаксис команд.

В четвертой версии Keil uVision, поставляется версия 5.02 ассемблера. Расположен он в папке c:\Keil\ARM\ARMCC\bin, при установке среды в c:\Keil.


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


Среда разработки GNU GCC ARM

Открытая, бесплатная, без ограничений размера кода, система компиляторов, в том числе для ARM.
Содержит собственный ассемблер GNU AS, с собственными синтаксисом.

Ассемблер GNU AS наиболее мощный из всех, т.к. поддерживает (в одном стиле) ассемблеры очень многих наборов команд различных процессоров. С этой точки зрения - перспективен.



Для выбора ассемблера (да какой выбор-то - gnu arm, т.к. и Linux используется), составил небольшую табличку сравнения мнемоник, чтобы не путаться в синтаксисе.


Подобие подобия. Краткий синтаксис директив ассемблеров для ARM
Таблица №1

 

Phython

CodeMaster

ARM

IAR

Embedded

Workbench

Keil

MDK-ARM

GNU AS

 

Сайт





 

 

mcaarm.exe v. 1.01.101130

 

Armasm 5.02

GNU assembler version 2.23.51 (arm-none-eabi)

 

Комментарии

; - строка

; - строка

// - строка

/* */ - группа строк

; - строка

# - имеет доп. спец. значение

; - строка

@ - строка

/* */ - группа строк

 

Символы (метки)

Latin1 - символы, цифры, спецсимволы

Latin1,a-zA-Z, цифры,

 символы _ $, могут содержать печатные символы, если заключены в апострофы ``

 

Символы, цифры, знак подчёркивание (_). Различается регистр символов.

Unicode-строка, цифры, 3 символа "_.$"

Различается регистр символов.

 

Директива

THUMB, указывающая на 16-битные инструкции ARM, ассемблеру

.THUMB

THUMB

THUMB

.thumb или .code16

 

Директива включение другого файла с исходным кодом

.INCLUDE

INCLUDE или $

GET или INCLUDE

.include

 

Импорт символов

.EXTRN

.EXTRNx - типизированный импорт

IMPORT или

EXTERN или

EXTWEAK

IMPORT или

EXTERN

.import

 

Экспорт символов

.PUBLIC

PUBLIC или

PUBWEAK

EXPORT или

GLOBAL,

EXPORTAS

.global

.globl

 

Объявление функций (подпрограмм)

.FUNC и .ENDF

Или .EXTRNF

Явно не выделено

FUNCTION или PROC и .ENDP .ENDFUNC

.func

 

Объявление

Макросов (начало и конец)

.MACRO и .ENDMAC

MACRO и ENDM

Или ENDR

MACRO и MEND

.macro и .endm

 

Присваивание символического имени выражению

.EQU распространяется на модуль внутри файла

или .DEFINE распространяется на весь файл

.SET или =  - может быть переопределено в том же модуле

.LABELx - типизированные метки

EQU в пределах модуля

ALIAS в пределах модуля

SET, SETA, ASSIGN временно

DEFINE - на весь файл

EQU

.equ

 

Определение секций кода и данных

.ASEG и .ENDSEG

.RSEG и .ENDSEG

OSEG и .ENDSEG

SECTION или RSEG

И END

ALIGNROM, ALIGNRAM, EVEN,ODD

AREA CODE

AREA DATA

.section

 

Конец файла

.END - конец модуля и конец файла

.ENDMOD - конец модуля

END

END

.end

 

Модуль начало

.PMODULE

.LMODULE

PROGRAM или NAME или MODULE

 

Явно не выделено

Явно не выделено

 

Заголовок и подзаголовок на каждой странице

 

.TITL

.STITL

Явно не выделено

TTL и SUBT

.ttl и .sbttl

 

Условное

.IF, .ELSE, .ENDIF

IF и ENDIF

IF, ELSE, ENDIF, and ELIF

.if или несколько .ifxx, где xx-какое-либо условие

И .endif

.else и .elseif

 

Предопределённые символы регистров

 

CPSR, R0–R12, R13 (SP), R14 (LR), R15 (PC), SPSR  и пр.

 
 

 

 

Вызов процедуры

 

 

BL имя

 

 

 

 

 

 

 

Bus Blaster v.2 как UART-TTL

Использование JTAG-отладчика BusBlaster v.2 в качестве UART-TTL адаптера

BusBlaster v.2 - небольшая плата открытого JTAG-отладчика, созданная на сайте DangerousPrototypes.com. В наличии имеется вторая версия платы.
Проверку и настройку производил в системе Windows 7 Home Basic. В Ubuntu Linux 12.04, работает.
Планируемое использование - отладка ARM-микроконтроллеров Cortex-M3, в том числе Миландр MDR32F9Q2I.

JTAG-отладчик основан на распространённой микросхеме FTDI FT2232H - мост USB-Serial. Из особенностей - применения CPLD микросхемы, в качестве согласующего логические уровни буфера, с возможностью перепрограммирования, для изображения из себя различных jtag-отладчиков. 

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

Сайт поддержки отладчика: http://dangerousprototypes.com/docs/Bus_Blaster 

Руководство по настройке программы отладчика urJTAG (en): http://dangerousprototypes.com/docs/Bus_Blaster_urJTAG_guide

Руководство по настройке программы отладчика OpenOCD (en): http://dangerousprototypes.com/docs/Bus_Blaster_OpenOCD_guide

Заметка по смене VID/PID у EEPROM памяти BusBlaster http://dangerousprototypes.com/docs/Bus_Blaster_custom_USB_VID_and_PID

Страница микросхемы FT2232H на сайте производителя: http://www.ftdichip.com/Products/ICs/FT2232H.htm

Bus Blaster v.2. Thank to DangerousPrototypes.com

Идентификационные данные отладчика на шине USB:
VID = 0x0403 (FTDI)
PID = 0x6010 (FT2232H)


Для подключения и проверки работоспособности отладчика BusBlaster надо выполнить несколько шагов:


1. Установка драйверов микросхемы FT2232H. Это могут быть фирменные драйверы (фирмы FTDI) http://www.ftdichip.com/Drivers/D2XX.htm , либо открытые libUSB http://sourceforge.net/projects/libusb-win32/.

2. Установить программы отладчиков urJTAG или OpenOCD, или всё вместе.

3. Установка программы отладчика urjtag. 
Во время установки, надо указать путь c:\urjtag, вместо C:\Program Files\UrJTAG, иначе установщик не работает.
Лучше использовать исправленную версию, с сайта DangerousPrototypes.com

4. Соединение JTAG отладчика и отлаживаемого устройства. Соединение должно происходить сигнал в сигнал, как подписано.
TDO - TDO
TDI - TDI
TCK - TCK
TMS - TMS
TRST - TRST
Обязательно! Питание с отлаживаемого (целевого) устройства, должно подаваться на микросхему буфера, через VTG пин JTAG разъёма, т.к. часть микросхемы буфера не запитана.



5. Проверка возможности использования BusBlaster v.2 , как обычного UART-TTL

В микросхеме FT2232H присутствуют выводы TXD-RXD (38,39) Обозначаются также BDBUS0, BDBUS1, которые выведены на разъём JP1 (контакты 2 - TCK,3 - TDI).

Итак, в моей системе Windows, рабочий COM порт оказался 25 (их ведь 2 в микросхеме), настройка 9600-8-1. Замкнутые выводы RX-TX на разъёме JP1 и получили простой порт для обмена данными.

Также, в диспетчере устройств Windows можно переназначить появляющийся 25 порт, на любой доступный.

6. Установил исправленную версию urjtag и стала срабатывать опция interface=1, на которой определяется устройство - микросхема CPLD. Это уже радует.
Перед использованием положить bsdl файл микросхемы CPLD (или иной) в папку c:\urjtag
7. Команды выполняемые в программе: urjtag-rev11
jtag> cable jtagkey interface=1
jtag> bsdl path c:\urjtag
jtag> detect
IR length: 8
Chain length: 1
Device Id: 00000110111000011100000010010011 (0x06E1C093)
Filename: c:/urjtag/XC2C32A.bsd
jtag>




8. Прошить в CPLD последний вариант буфера Jtagkey. Т.е. теперь отладчик совместим с отладчиком JTAGkey.

9. Для быстрой проверки работоспособности отладчика с разным ПО, я подключаю его JTAG-порт, к порту JTAG на пинах JP1, и устанавливаю JP4 (подаю питание). Если всё работает, то определяется IDCODE Xilinx.

Небольшое описание платы отладчика на память.


BusBlaster v.2 - расположение компонентов



JP1 - Выход JTAG, напрямую с микросхемы FT2232H? Для чего?
Используется как подсоединение второго порта к jtag- интерфейсу буферной микросхемы CPLD. Может использоваться как UART-TTL.
JP2 - Неиспользуемые выводы
JP3 - Микросхема памяти EEPROM (Хранение идентификаторов USB VID/PID)
JP4 - Подача питания 3.3V. При снятой перемычке питание на микросхему буфера (часть микросхемы) подаётся от отлаживаемого устройства. При установленной перемычке - питание берется у BusBlaster для питания отлаживаемого устройства, а также для питания микросхемы буфера (IO).

JTAG - 20-выводной разъём соответствует стандарту JTAG ARM 20 pin

XC2C32A CPLD - XC2C32A CoolRunner-II CPLD, микросхема программируемой логики, используется в качестве буферной, для согласования логических уровней с отлаживаемым устройством (1.8 - 3.3В).

FT2232H - микросхема моста USB-Serial, выполняющая основную работу.

Из плюсов
1. Буферная согласующая микросхема
2. Поддержка OpenOCD
3. Отладочная плата для Xilinx CPLD


Из недостатков

1. Не все возможные выводы разведены, т.к. что потенциал микросхемы FTDI FT2232H слегка ограничен. Например, не получилось сделать 2 порта. Может потом.


суббота, 12 января 2013 г.

MSP430.Начало

Микроконтроллеры MSP430 Value line. С чего начать?
 
Ниже перечислены простые действия, которые надо выполнить чтобы перейти к использованию микроконтроллера семейства Texas Instruments MSP430 Value Line. Это недорогое семейство стало массово доступно, после выпуска фирмой Texas Instruments, недорогой (4.3$) отладочно-демонстрационной платы. Относительно низкая цена - дотационный продукт, стоимость всех составляющих его компонентов - выше. Ну что же, скажем спасибо и будем пользоваться. Данная отладочная плата полезна начинающим изучать программирование микроконтроллеров.
 
  • Приобретение комплекта отладочной платы MSP-EXP430G2 LaunchPad kit в интернет-магазине http://estore.ti.com/
  • Установка программного обеспечения - среды Composer Studio - редактора, отладчика
  • Подключение демонстрационной отладочной платы к настольной ЭВМ
  • Запуск среды разработки
  • Выбор языка программирования для разработки (C или ассемблер)
  • Создание нового проекта на выбранном языке программирования, самостоятельно, либо на основе предлагаемых шаблонов
 
Итак, подготовительные действия выполнены.
 
Теперь надо сформировать понимание микроконтроллера, что это такое, как это работает. Уровни понимания могут быть разные, нас же интересует, в любом микроконтроллере, это его возможности общаться с внешним миром - микросхемами, устройствами, другими микроконтроллерами, настольной ЭВМ, какие команды он понимает. Вся эта электронная братия, на данном историческом этапе, может общаться друг с другом просто, - цифровыми сигналами - заранее определёнными (по соглашению в индустрии) уровнями напряжения (TTL), коих всего два. Можно сказать, что микроконтроллер - это цифровое устройство, скрывающее сложность аналоговых сигналов, за ширмой простого выбора. Микроконтроллер любит хорошо кушать - питается электричеством.
 
 
 
Микроконтроллер, это результат развития электронной отрасли, особенно последних десятилетий после изобретения микросхем. Это постепенно выделившаяся, обособившаяся часть из многих разработанных устройств - это шаблонная часть встречающаяся очень часто, это слаженная работа нескольких устройств в одном корпусе, - результат миниатюризации электронной техники.
 
 
 
 
Если посмотреть обычным взором на микроконтроллер - небольшой кусочек материи, с железными выводами, понять его возможности и назначение не представляется возможным. Отсюда вытекает особенность использования любого микроконтроллера - чтение документации к нему. Без этого - никак. Каждый микроконтроллер (семейство) - уникальный специфический продукт, со своими особенностями. Поэтому, - только документация, примеры, книги.
 
 
 
Безусловно, ранее приобретённый опыт ускоряет понимание документации, относящейся к конкретному микроконтроллеру. Большую пользу принесут знания более высокого уровня, - обобщение понимания микроконтроллеров, наработанные алгоритмы. Они все очень похожи, при всём их различии. "У всех есть ножки". Физическое воплощение их, выражается в разнообразных стандартных корпусах, коих великое множество. Внутреннее наполнение - ещё более разнообразно.
 
 
 
Микроконтроллеры - продукт человеческого гения, рождённый в попытке переложить часть своего общения (взаимодействия) с миром на технику. Человек передал микроконтроллеру право принимать решения в этом мире, оставив себе лишь ложное чувство контроля.
 
 
 
Нет ли в этом стремления человека отделиться от мира, от его разнообразия, непосредственного взаимодействия?
 
 
 
Микроконтроллер оценил доверие и принялся шевелить ножками - вверх - вниз, вверх - вниз.
 
Практически любой микроконтроллер сконструирован так, что ему для функционирования требуется внешний сигнал - тактовый генератор - такт - ритм - счёт ( И раз, два, три, - раз, два, три, раз). И что удивительно, микроконтроллер всё успевает за один такт. А это всё - это его состояние. Состояние ножек внутренних и внешних - вверху или внизу. С каждым тактом, он меняет своё состояние - полное состояние . В общем-то, больше он ничего не делает - такова судьба в мире с двумя положениями. Всё остальное - фантазии создателя - человека. Человек, мера всех вещей, он задаёт смысл состояниям микроконтроллера, серии состояний. Движение состояний - всё.
 
Правильно функционирующий микроконтроллер, своё полное состояние, меняет по указанию человека. Указание - это машинные команды, их последовательность. Микроконтроллеру всё равно какие указания - они все правильные, с его точки зрения. Человеку же, не всё мило. 
 
В процесс общения человека и микроконтроллера, вклинивается нечто. Это нечто - уровень понимания человеком микроконтроллера. Хороший уровень понимания - общение идёт успешно.
 
Человеку воспринимать язык микроконтроллера сложно - это набор нулей и единиц, их много, миллионы. Указания давать битами - мука.
 
Поэтому, человек придумал хитрость. Он не стал общаться битами, он стал общаться словами из битов. А т.к. микроконтроллеру всё равно, то он пошёл на поводу у человека и стал с ним общаться словами из битов. Вначале было слово из 8 бит, потом пошли 16, 32, 64, 128.
 
В океане нулей и единиц, человек задал, самому себе, смысл слов. Постепенно, слова из набора бит наскучили ему. Он придумал как ещё сократить написание - ввёл систему счисления, используя известные ему цифры и буквы. Правда, шестнадцатеричную, поскольку посчитал так будет удобнее микроконтроллеру. Шестнадцатеричные цифры быстро привели его в уныние - их опять было "много и непонятно". Тогда он стал использовать слова своего языка, сокращения, - и так изобрёл ассемблер. Дело обобщения, повышения абстракции, пошло быстрее и человек изобрёл язык высокого уровня. Конечно, несколько пафосно назвав - "высокого уровня".
 
Это позволило человеку давать больше указаний микроконтроллеру. А тот исправно их выполнял. Но, то самое "нечто" опять вмешалось в разговор. И человек перестал понимать самого себя, что же он хочет сказать микроконтроллеру - так появились ошибочные указания - ошибки программирования.
 
Микроконтроллер исполняет всё, но человек определяет результат.
 
 
Для начала работы с любым микроконтроллером, не только MSP430 надо сделать несколько предварительных вещей:
 
Сформировать схему подачи требуемого питания. Некоторые микроконтроллеры предпочитают напряжение 5В, некоторые - 3.3 В, бывает что довольствуются и меньшим - 2,7 В, 1.8 В.
 
Сформировать схему сброса, т.е. перевода из неопределённого состояния после подачи питания, в известное начальное, которое задумано конструктором и описано в документации.
 
Обеспечить доступ к периферийным устройствам микроконтроллера. Т.е. сформировать подключения к портам ввода-вывода.
 
Т.к. в современном мире не принято общаться с микроконтроллером напрямую, то потребуется посредники в виде настольной ЭВМ и программатора - передающего указания человека.
 
В отладочной плате MSP430 LaunchPad от Texas Instruments, более опытные инженеры всё это сделали вместо человека. MSP430 LaunchPad содержит на печатной плате встроенный отладчик-программатор с подключением по шине USB к настольной ЭВМ, сам микроконтроллер. Они также создали ассемблер для этой серии, компилятор языка высокого уровня СИ, хорошую документацию и примеры, а также программную среду Composer Studio. Это сильно облегчает использование, по сравнению с тем, что было каких-то 20 лет назад.
 
 
Основная сложность на первоначальном этапе, - понять задумки конструктора. Определить из чего, из каких периферийных устройств состоит конкретный микроконтроллер, как их устанавливать в начальное состояние как с ними общаться на языке высокого уровня (что писать в программе). Объем информации достаточно большой, поэтому надо заглянуть в конструкторскую документацию (datasheet - листок данных по контроллеру).
 
Вторая сложность - переложить свои задумки на язык конкретного микроконтроллера.
 
MSP430 LaunchPad поставляется с двумя микроконтроллерами: MSP430G2231 и MSP430G2211, различающимися лишь составом устройств - периферии. Более новая версия отладочной платы (ревизии - пересмотра 1.5) содержит микроконтроллер MSP430G2553.
 
Документация на семейство микроконтроллеров: http://www.ti.com/lit/pdf/slau144
Документация на микроконтроллер MSP430G2231: http://www.ti.com/product/msp430g2231, http://www.ti.com/lit/gpn/msp430g2231
Документация на микроконтроллер MSP430G2553: http://www.ti.com/lit/zip/slac485
 
Любой микроконтроллер содержит то, главное устройство, которое получив сигнал тактового генератора, выполняет всю работу по пониманию пользовательской программы - арифметическое логическое устройство (АЛУ).
 
 
Указания пользователя - программа содержится внутри микроконтроллера во встроенной памяти постоянного хранения - так называемая ПЗУ - постоянное запоминающее устройство. Сейчас, это разновидность Flash-памяти, с возможностью обновления программы посредством программатора-отладчика. Ранее это были однократно программируемые ПЗУ, ещё ранее - не было и этого.
 
Практические потребности сохранения состояний на длительности нескольких тактов (сквозь время), вызвали появление оперативного запоминающего устройства - ОЗУ, а также внутренних регистров АЛУ, специальных регистров периферии, конфигурационных регистров. Без этих устройств микроконтроллер являлся бы устройством без памяти, что было бы не очень практично.
 
Микроконтроллер MSP430G2231 содержит 16-битное арифметико-логическое устройство, т.е. микроконтроллер 16-разрядный. Понимающий слова из 2 байт.
 
Из документации становиться понятно, что микроконтроллер MSP430G2231, содержит 2Кибибайта (2048 байт) постоянной памяти программ, 128 байт оперативного запоминающего устройства.
 
Микроконтроллер MSP430G2xxx - построен по архитектуре фон-Неймана, - единое адресуемое пространство памяти, что сокращает число команд по обращению к различным типами памяти, т.к. минимальная часть любой памяти (ячейка памяти) адресуется однообразно - 16-разрядным словом, имеющим смысл адреса. Вся совокупность ячеек памяти образует единое пространство памяти. Однако это вводит определённые границы для диапазонов памяти, со своим смыслом, например диапазон ПЗУ, диапазон ОЗУ, диапазон специальных регистров и т.п.
 
Структуру диапазонов памяти человек назвал картой памяти.
 
У микроконтроллера MSP430G2231 структура памяти такова и её можно посмотреть в руководстве пользователя для семейства микроконтроллеров MSP430x2xx. Руководство на английском языке, правда есть и перевод на русский язык.
 
Как становиться понятно, микроконтроллер содержит очень ограниченный набор периферийных устройств полезных человеку.
 
1 аналогово-цифровой преобразователь, 2 счётчика (таймера), один из которых (таймер) совмещённый с цепным псом (watchdog), 10 ножек (линий) ввода-вывода, USI - универсальный последовательный интерфейс для связи с внешним миром. Негусто.
 
Также, стоит добавить что присутствуют специальные устройства, облегчающие отладку указаний человека - JTAG, SBW, Emulation.
 
Внутри, микроконтроллер понимает указания человека строго последовательно, слово за слово, команда за командой. Некоторые слова понимаются и исполняются за один такт тактового генератора, другие за большее число тактов. Внутреннее состояние микроконтроллера, при выполнении многотактовых команд, в промежутке между началом исполнения команды и её завершением (смена состояния видимых регистров, памяти и пр.) мало волнует человека - не несёт ему смысла. Это внутренняя кухня микроконтроллера - там может существовать тьма подсобных регистров.
 
Человеку важно понимать лишь смену состояния между командами. А это содержимое памяти, видимых регистров АЛУ, видимых спец. регистров. Слово видимых - т.е. тех, которые описаны в документации.
 
Документация на микроконтроллер MSP430G2231 говорит о 16 регистрах АЛУ, вот о смене их состояния надо заботиться при написании программ (на языке Ассемблера). Язык Си избавляет и от этой заботы.
 
Видимые регистры - это подсобная память АЛУ - это регистры для обмена словами с другими устройствами микроконтроллера. По другому то они не общаются.
 
Фактически, человеку при изучении нового микроконтроллера надо понимать специальный язык - имена (сокращения, аббревиатуры) специальных регистров и пр., это помимо имён машинных команд АЛУ. Имена машинных команд , во многом называются так, как и в других микроконтроллерах, т.к. выполняют понятный (часто повторяющийся) набор операций. А вот, специальные имена, зависящие от периферии - это да, это и есть язык конкретного микроконтроллера, он тем обширнее, чем больше дополнительных устройств входит в состав. Однообразия здесь ждать не приходится. Так что - чтение документации. Без этого языка, даже на Си программировать невозможно. Си только скрывает машинные команды АЛУ от человека. Но человек же, хочет управлять периферией. Так что, да - документация.
 
 
 
После подачи питания микроконтроллеру и сброса в начальное известное состояние (reset), АЛУ начинает выполнять указания, с определённого адреса, в данном случае с адреса начала постоянной памяти программ (ПЗУ, flash). У микроконтроллера MSP430G2231 этот адрес начинается с 0F800h и заканчивается на 0FFFFh, что даёт 2КиБ. Начальный адрес можно заменить, записав его в вектор прерывания (reset). Выполнив все команды из памяти, дойдя до конечного адреса, микроконтроллер останавливается. Чтобы он работал постоянно, его надо зациклить.
 
Карта памяти MSP430G2231
 
Диапазон адресов регистров специальных функций (SFR) - 0h-Fh, что составляет 16 ячеек
Байтовый диапазон периферийных устройств - 010h - 0FFh, что составляет 240 ячеек
2-х байтовый диапазон периферийных устройств - 0100h - 1FFh, что составляет 256 ячеек, или 128 слов
Адрес оперативной памяти (ОЗУ) - 0200h, что составляет 128 ячеек
Диапазон адресов информационной памяти - 010FFh … 01000h, 256 ячеек, сегменты A,B,C,D
Диапазон адресов таблицы векторов прерываний - 0FFC0h - 0FFFEh, входит в диапазон постоянной памяти
Диапазон адресов постоянной памяти - 0F800h - 0FFFFh, что составляет 2048 ячеек (2КиБ)
 
Каждый диапазон имеет специальный смысл, разъяснение которого описано в документации.
 
Микроконтроллер со столь ограниченным числом периферийных модулей, которые и делают основную полезную человеку работу, можно назвать контроллером одного устройства (одного датчика), одной функции. Его ниша - это разгрузка основного контроллера.
 
Встроенные периферийные устройства присоединяются к АЛУ через шины (набор проводов) - шины адреса, данных, и управления. Шина адреса и данных - 16-разрядная (16 проводная).
 
В микроконтроллере MSP430G2231 встроен собственный тактовый генератор, т.н. Clock System. Этот генератор (DSO - digitally controlled oscillator)обеспечивает микроконтроллер колебаниями (сменой состояния) равной длительности.
 
Внутри MSP430G2231 3 источника тактов, с разной частотой:
 
Вспомогательный (ACLK - Auxiliary Clock), которые берет колебания от встроенного низкочастотного колебательного устройства, либо от внешнего кварцевого генератора.
Главный (MCLK Main clock), используется АЛУ.
Подглавный SMCLK - Sub-Main clock. Используемый периферийными устройствами.
 
Центральный процессор содержит шестнадцать 16-битных регистров. Регистры R0, R1, R2 и R3 имеют специальные функции. Регистры с R4 по R15 являются регистрами общего назначения.
 
Вся работа АЛУ с периферийными устройствами происходит через регистры периферии, а в микроконтроллере MSP430G2231 регистры отображены в определённые адреса общей памяти т.н. память периферийных устройств. Таким образом, вся работа по указанию АЛУ что делать с периферийным устройством, сводится к записи специальных значений в регистры устройства (их расположение описано в документации), а также в обработке событий от таймера-счётчика, посредством прерываний.
 
Работа с периферийным устройством микроконтроллера делиться на 2 части: на подготовку - инициализацию (настройка на определённую функциональность), и непосредственную работу с инициализированным (настроенным) устройством, с его функцией.
 
 
 

MSP430 Периферийное устройство "Таймер-счётчик"

Периферийное устройство счётчик-таймер, у микроконтроллера MSP430G2231, носит название Timer_A2. Он является 16-битным, т.е. диапазон счёта от 0 до 65535. Считает он такты источника тактов, который можно выбрать при настройке.
 
Что может делать таймер, в частности, в микроконтроллере MSP430G2231? Какие его функции доступны и как они настраиваются (инициализируется)? Подробное описание таймера Timer_A2 можно получить в документации на семейство микроконтроллеров MSP430Gx2xx, в главе 12.
 
Таймер-счётчик позволяет порождать цифровые сигналы определённой, достаточно точной длительности, например, миллисекундные колебания на выделенной ножке микроконтроллера.
 
Таймер-счётчик позволяет порождать цифровые сигналы нерегулярной длительности, т.н. широтно-импульсная модуляция
 
Таймер-счётчик позволяет рассчитывать точные временные интервалы, для целей программы, между событиями
 
Таймер-счётчик позволяет считать импульсы поступающие на специально выделенный вход (ножку микроконтроллера, включённую на приём)
 
Таймер-счётчик позволяет установить специально выделенный вывод в определённое значение, при достижении таймером-счётчиком определённого значения.
 
Таймер-счётчик позволяет определить интервал времени между двумя состояниями?
 
Таймер-счётчик - хороший инструмент для работы со временем. Стоит заметить, что микроконтроллер позволил человеку иметь дело с достаточно малыми величинами времени - миллисекундами, микросекундами. В миллисекундный диапазон попадает достаточное число процессов, которыми можно управлять с помощью микроконтроллера, например двигатели, сервоприводы и пр. Управлять - это подавать малого тока управляющие сигналы, а не большого тока (силовые). Силовая часть обычно реализуется вне микроконтроллера, но управляется микроконтроллером. Однако, есть микроконтроллеры и со встроенными силовыми схемами.
 
Посмотрим на регистры устройства "таймер-счётчик".
 
Самый главный регистр таймера-счётчика Timer_A2, носит название TAR, что в английском языке означает Timer A Register. Это вершина устройства таймера-счётчика. Значение этого регистра можно прочитать, можно установить, очистить, в коде программы. Значение может увеличиваться от 0 до 65535, либо уменьшаться от 65535 до 0, либо до определённой границы, либо вначале увеличиваться, а потом уменьшаться. Адрес этого регистра - 0170h.
 
Далее, второй по важности регистр относящийся к таймеру-счётчику - регистр управления режимом таймера-счётчика и его имя Timer A Control (TACTL), с адресом - 0160h. Он позволяет задать режимы работы таймера, и ещё несколько настроек, рассмотренных ниже.
 
Регистр управления таймером (TACTL) не простой, а имеет структуру, частям которой даны названия. Т.к. это слова, то он имеет 16 бит, часть из которых не используется. Структуру регистра можно посмотреть в главе 12.3.1 "TACTL, Timer_A Control Register".
 
Биты управляющего регистра (TACTL )таймера-счётчика. Только 9 бит из 16, остальные не используются.
 
 
 
0 TAIFG
1 TAIE
2 TACLR
3 не используется
4 MCx
5 MCx
6 IDx
7 IDx
8 TASSELx
9 TASSELx
 
Итак, структура TACTL приведена выше. Не очень понятно, правда. Расшифруем, т.к. система мнемонических обозначений достаточно регулярна. Два бита 8-9 (4 варианта) под именем TASSEL (Timer A Source Selection) отвечают за выбор источника тактовых сигналов, как-то TACLK, ACLK, SMCLK, INCLK.
 
Тактовый сигнал пропускается через делитель, а значение делителя (4 варианта) задается битами 6-7 под именем Idx (Input Divider), как-то /1, /2, /4, /8
 
Далее, биты 4-5 под именем MCx (Mode Control), которые задают режим таймера, как-то таймер выключен, счёт до границы TACCR0, счёт до 65535 (0FFFFh), счёт вверх до границы TACCR0, затем вниз до 0 и т. д.
 
Бит 2 TACLR (Timer A Clear) обнуляет регистр таймера-счётчика, делитель и направление счёта.
 
Бит 1 - включает обработчик прерывания от таймера-счётчика
 
Бит 0 - флаг, выставляется при срабатывании прерывания от таймера-счётчика
 
Для человека, владеющего английским языком как родным, всё достаточно прозрачно. Нам же, приходится писать комментарии к программам.
 
Этих двух регистров достаточно для многих задач с использованием таймера-счётчика. Но, это подводит нас к следующим дополнительным управляющим регистрам, ещё более расширяющих настройки таймера-счётчика.
 
У микроконтроллера MSP430G2231, в устройстве "таймер-счётчик" есть 2 одинаковых регистра захвата/сравнения, под именами: TACCR0, TACCR1, с адресами: 0172h, 0174h. Соответственно есть регистры настройки и у этих регистров, под именами: TACCTL0, TACCTL1, с адресами: 0162h, 0164h.
 
Смысл этих регистров сравнения может быть понят из описания и примеров, потому что логика их действий сложная, с массой тонкостей, но общий смысл - выполнение каких-либо действия при равенстве значений счётчика и регистра сравнения (TAR = TACCRx),понятен.
 
Режим захвата используется при вычислении временных интервалов. В этом режиме, при поступлении сигнала, значение регистра TAR копируется в один из регистров захвата TACCR.
 
Регистр TACCR0, как было упомянуто, используется в специальном режиме счёта (MDx = 01), т.н. "Up" до значения (до границы) взятого из регистра TACCR0. Когда таймер достигает в регистре TAR значения TACCR0, то он начинает с 0. При этом, при достижении значения TACCR0 (Т.е. фронт тактового импульса) устанавливается флаг прерывания CCIFG, а потом, когда таймер начнёт с 0 и опять же по фронту тактового импульса, будет установлен флаг прерывания TAIFG.
 
ШИМ - широтно-импульсная модуляция, про простому, формирование импульсов указанной длительности (ширины), а ширины потому что высота всегда соответствует уровню логической единица (либо 0, если наоборот). Т.е. за импульс можно принять либо логическую 1, либо 0.
 
Для удобство человека, чтобы в каждой программе не писать адреса специальных регистров и пр. придуман файл определений (header file), в котором уже заданы мнемоники известных регистров с их адресами, так что в программе можно использовать их имена.
 
Ранее мы упоминали, чтобы контроллер мог реально работать, надо его зациклить. В языке СИ этот цикл отображается в бесконечный цикл while() {}, в функции main(). Его ещё называют - вечный цикл, главный цикл.
 
Для малознакомых с языком СИ, функция main() - это функция входа в программу (эту функцию вызывает операционная система, для запуска программы, при запуске на компьютере, либо микроконтроллер, после сброса).
 
Самая простейшая программа, ничего не делающая, только создающая возможности для дела, выглядит так:
 
 
 
void main( void ) {
 
}
 
 или с главным циклом:
 
void main( void) {
  while (1) {
 
 }
}
 
Ну и добавив файл определений, для микроконтроллера MSP430G2231, получим:
 
#include "msp430g2231.h"
 
void main( void ) {
 
while (1) {
 
}
 
}
 
 
while (1) - это замена условия, всегда истина. В СИ true = 1, язык не строго типизированный, поэтому так можно.
 
В среде разработки Composer Studio, есть полезный инструмент, особенно после прочтения документации на микроконтроллер, под названием Grace - графический конфигуратор устройств. Простейший файл программы принимает вид:
 
#include <msp430.h>
 
#include <ti/mcu/msp430/csl/CSL.h>
 
int main(int argc, char *argv[])
 
{ 
  CSL_init(); // Activate Grace-generated configuration
 
// >>>>> Fill-in user code here <<<<<
 
return (0);
 
}
 
Продолжив далее, без Grace, определим кусок кода (функции), отвечающие за начальную настройку таймера. Для этого используем битовую арифметику языка СИ, для установки битов контрольного регистра TACTL .
 
Для того, чтобы установить отдельный бит регистра в единицу, используется поразрядная операция ИЛИ (|). Чтобы сбросить отдельный бит регистра, в ноль, используется поразрядная операция И (&) и инвертирование (двоичное дополнение) (~) правой части выражения.
 
 
Для битов, в файле определений, также даны имена, соответствующие именам в документации и несколько альтернатив.
 
Например, установить выбор источника: TACTL = TACTL | TASSEL_0 ;
 
Либо более сокращённая форма: TACTL |= TASSEL_0 ;
 
Чтобы установить несколько бит за раз, можно использовать такой синтаксис: TACTL |= (TASSEL_0 + ID_3);
 
Чтобы сбросить 4-бит: REGISTER &= ~BIT4;
 
Пример секундного таймера
 
В качестве примера, попробует сделать секундный таймер, который включает/выключает светодиод, расположенный на плате MSP430 LaunchPad и подключённый к одному из выводов.
 
В примере также будет задействовано встроенное устройство (Basic Clock Module+), для целей настройки тактовых генераторов.
 
Также задействуется устройство "Порт ввода вывода". Это простое устройство, так что его понять будет просто, из синтаксиса программы. Светодиод который мы будем использовать, подключён к порту P1.0. Он обозначен на плате как LED1.
 
 Первая проблема, с которой мы столкнёмся - это слишком быстрый счёт таймера. Отсюда следует, что надо уменьшить частоту таймера. Сделать это можно выбрав источник и установить делитель и всё равно, мы получим очень быстрый счёт. Поэтому, видимо, придётся применять программный делитель.
 
Также определим, для начала функции первоначального включения и настройки устройств. Может какие-то и не нужны, но для сохранения стиля написания, мы их напишем. Также будем писать комментарии, чтобы впоследствии, через время, легко читать назначение функций программы, не разбираясь в сокращениях на английском языке.
 
 
 
В языке СИ, функция - это просто обёртка последовательно исполняемого кода, чтобы код программы читался понятнее.
 
/*
initBCS() - включение и тонкая настройка устройства Basic Clock Module+, обеспечивающая наш проект тактовыми сигналами
*/
 
void initBCS() {
 
}
  
/*
init TimerA() - включение и тонкая настройка устройства таймер-счётчик
*/
void initTimerA () {
 
}
 
 
/*
initPort() - включение и тонкая настройка устройства "порт"
*/
void initPort() {
 
}
 
 
/*
main - точка входа 
*/
 
void main(void) {
  
WDTCTL = WDTPW + WDTHOLD; // Остановка WatchDog таймера, это странная особенность микроконтроллера
 
initBCS();
initTimerA();
initPort();
 
// Главный цикл программы микроконтроллера MSP430G2231
while (1) {
 
}
}
 
Итак, начальный каркас сформирован, пришло время наполнить его.
 
Для начала, примечание по стилю. Мы не будем использовать абсолютные значения, а будем использовать имена в переменных, константах и пр., чтобы алгоритм поведения программы был максимально понятным. Если такое, вообще применимо к языку СИ.
 
Жёстко задавать односекундный интервал в коде, как-то неправильно, вдруг понадобится 2-х секундный. Поэтому, без функции установки интервала не обойтись. Определим для этого функцию setPeriod() и потом добавим определение к каркасу. Также, возможно понадобиться 60-секундный интервал - минутный, определим константу minute, а также константу second.
 
 
int minute = 60; // Минутный интервал времени
int second = 1; // Секундный интервал
 
/*
setPeriod - установить временной интервал, в секундах
*/
 
void setPeriod(int seconds) { 
 
}
 
Сразу можно добавить её вызов в функцию main:
  
setPeriod(second); // Установить интервал включения-выключения светодиода
 
Однако, а вдруг понадобиться установить интервал в миллисекундах? Тогда напишем ещё одну функцию.
 
/*
setPeriodInMilliSeconds - установить временной интервал, в миллисекундах
*/
 
void setPeriodInMilliSeconds (int milliseconds) {
 
}
 
Но моргание светодиодом в миллисекундном режиме, не заметно человеческому глазу. Поэтому, это функцию пока не реализовываем.
 
Теперь, надо запустить таймер в работу, поэтому напишем функции включения, выключения таймера. Вполне возможно, в дальнейшем, запуск таймера, будет производиться по какому-либо событию, а не сразу при запуске программы. Функцию стоп можно и не реализовывать на данном этапе.
 
/*
 
 startTimer A- запуск таймера A в работу
 
*/
  
void startTimerA() {
 
}
 
/*
 
stopTimer - остановка таймера A
 
*/
  
void stopTimerA() {
 
}
 
Запуск и остановка таймера - простейшие реализации, поэтому сразу их и напишем, и добавим в соответствующие функции.
 
TACTL |= MC_2; // Запуск таймера в непрерывном режиме
  
И
 
TACTL |= MC_0; // Остановка таймера
 
Т.к. запуск и остановка, в микроконтроллере MSP430G2231, сопряжены с выбором способа счёта, то происходит как-бы перекрытие функциональности. Точно отделить настройку таймера от его запуска, не получается.
 
Теперь можно заняться включением и выключением светодиода. Можно пойти стандартным путём, а можно несколько сэкономить память.
 
 
 
Стандартный путь - 2 функцию вкл./выкл.
 
/*
 
powerOnLed() - включение светодиода
 
*/
void powerOnLed() {
 
}
 
/*
powerOffLed() - выключение светодиода
*/
void powerOffLed() {
 
}
 
 
Можно написать одну функцию, которая просто переключает светодиод в иное состояние, нежели он находится - powerSwitchLed()
 
/*
 
powerSwitchLed() - переключение состояния светодиода
 
*/
 
Void powerSwitchLed() {
 
}
 
Можно не писать функцию, а использовать непосредственно строку, которая меняет состояние ножки светодиода.
 
Реализацию можно сделать, жёстко зашив в функцию, тот светодиод, который переключается, а можно задать ножку, которая будет моргать.
 
Введение параметра в функцию - это неплохой способ расширить функциональность программы, под последующие изменения. Однако, это сразу добавляет в программу способ задания выбранного светодиода, будь то константа, структура и пр. Также, надо не забывать, что потребуется и инициализация ножек, т.к. цифровой порт может работать как на приём, так и на передачу (наш случай).
  
Напишем простейшую реализацию, которая переключает светодиод. Т.к. принцип работы с устройствами микроконтроллера MSP430G2231, стал более-менее понятен, то предположим, что и порт ввода-вывода настраивается и изменяется аналогично. Однако, почитаем документацию, глава 8.
 
Каждый порт, отражается регистрами PxIN, PxOUT, PxDIR и т.п., в области памяти периферийных байтовых устройств. В микроконтроллере MSP430G2231 - 1 полноценный (8 линий ввода-вывода) порт P1, и урезанный (2-линии ввода-вывода) P2. Для ввода - регистр PxIN, Для вывода - регистр P1OUT.
 
Т.к. мы будем выдавать сигнал на определённую линию порта P1, в данном случае, на линию под номером 0 (куда подключён светодиод), то вначале надо установить эту линию в направление - на выход. Делается это в регистре P1DIR, по адресу: 022h. Направление на выход - это логическая единица, а на вход - логический ноль.
 
Итак, можно проинициализировать линию 0, порта P1, на выход, и выключить светодиод, для начала.
 
P1DIR |= BIT0;
 
P1OUT &= ~BIT0;
 
Смущает только лишь имена. Ну тогда, переопределим.
 
#define LED BIT0
 
P1DIR |= LED;
 
P1OUT &= ~LED;
 
Включается светодиод, либо так:
 
P1OUT |= LED;
 
А переключение в другое состояние, так:
 
P1OUT ^= LED;
 
 
Теперь, мы подошли к функции программы, которая выполняет включение/выключение при достижении. Надёжнее это сделать с помощью механизма прерываний. Прерывания достаточно развиты в микроконтроллере MSP430G2231. Нам понадобиться прерывание, возникающее при достижении таймером конца счёта. Это вовлекает настройку у таймера-счётчика, а также таблицу прерываний и обработчик прерывания.
 
Для начала, обработчик прерывания - это обычная функция. Мы её и определим. Также на данном этапе, логично предположить что она вызывает функцию переключения светодиода, а значить мы может туда прописать (пока без обвязки) вызов этой функции. Это пока не рабочая конструкция, но передаёт смысл программы
 
/*
timeToSwitch - время переключать, функция обработчика прерывания от таймера
*/
void timeToSwitch() {
 
powerSwitchLed();
 
}
 
Теперь займёмся дополнительной инициализацией таймера, если нужно и затем прописыванием векторов прерываний.
  
Здесь вступают особенности синтаксиса, для задания прерываний на языке СИ, для микроконтроллеров MSP430. Я взял это из примеров, т.к. внятно описанный порядок не нашёл. Такой способ мне не нравиться, но когда надо быстро, сойдёт. На это накладывается и полностью забытый СИ.
 
Надо разрешить глобально прерывания, в функции main:
 
__enable_interrupt();
 
Либо так:
 
__bis_SR_register(GIE);
 
Установить обработчик прерывания от таймера-счётчика. Здесь мы несколько перепишем нашу функцию обработки:
 
#pragma vector=TIMERA0_VECTOR
__interrupt void timeToSwitch (void) {
 
}
 
Здесь: #pragma - специальное ключевое слово конкретного компилятора, которое указывает включить следующий за ним функцию, в вызов прерывания, в вектор прерывания таймера.
 
Что поделать, - особенности синтаксиса конкретного компилятора. Саму догадаться - нереально, так что - документация на компилятор, либо другие быстрые описания.
 
Теперь надо запретить прерывания, которые не обрабатываются, но которые могут возникнуть. Завернём это код в функцию:
 
forbiddenInterrupts(). Чуть позже её наполним. Её также будем вызывать из функции main.
 
/*
forbiddenInterrupts - запрет ненужных прерываний
*/
 
void forbiddenInterrupts() {
 
}
 
В принципе, высокоуровневая структура (некое подобие алгоритма) программы сформирована. Часть простых функций написана сразу, часть просто определена. Теперь можно заняться окончанием написания программы.
 
Для начала займёмся подсчётами необходимых значений, для настройки таймера, делителя тактового сигнала, программного делителя и пр.
 
Итак, постараемся обойтись встроенными средствами, и ничего (внешний кварц) не паять на плату.
 
Определимся с выбором тактового сигнала. Подробно, об этом, надо смотреть Главу 5 Руководства по семейству микроконтроллеров MSP430G2xxx.
 
Т.к. в последующем, сформированный код инициализации будет использоваться в других проектах, его надо сделать переносимым.
 
Я предполагаю, что микроконтроллер, работающий на полной тактовой частоте, выполнит больше работы, поэтому, основной код, будет работать на этой частоте. Отсюда проистекает решение - таймер будет работать на другой частоте, заданной в конфигурации.
 
Т.е. для основного источника тактового сигнала MCLK - я выберу DCOCLK.
 
Для таймера я выберу источник тактового сигнала SMCLK.
 
Начну с таймера.
 
Обнулю для начала настройку таймера, мало ли что.
 
TACTL |= TACLR;
 
Для таймера, источник тактового сигнала выбирается битами TASSELx.
 
TACTL |= TASSEL_2; // SMCLK
 
Делитель для тактового сигнала SMCLK - выберу максимальный = 8.
 
TACTL |= ID_3;
 
Надо разрешить прерывания по переполнению (достижению счётчиком максимального значения регистра)
 
С таймером-счётчиков Timer A, связано 2 вектора прерываний:
 
Вектор прерыванияTACCR0 для TACCR0 CCIFG
 
Вектор прерывания TAIV для всех остальных флагов CCIFG f и для флага TAIFG
 
 Для непрерывного режима, нас интересует TAIV. Прерывание по переполнению имеет меньший приоритет, чем прерывание по совпадению.
 
Разрешим прерывание по переполнению:
 
TACTL |= TAIE;
 
Выберем режим непрерывного счёта, но этот код поместим в функцию startTimerA()
 
TACTL |= MC_2;
 
Таймер-счётчик считает когда MCx > 0 и источник тактовых сигналов для него активен.
 
Для выбранного непрерывного режима, когда таймер-счётчик досчитает до конца (0FFFFh), начнёт с 0, и в момент начала (перед восходящим фронтом сигнала), установит флаг прерывания TAIFG.
 
Таймер, штука независимая, мы его настроили, и когда он завершит своё дело, он сообщит нам выставлением флагов. Ну а мы, если не проморгаем флажки (или забудем разрешить прерывания), то сможем что-то сделать по прерыванию.
 
Для настройки BCS+, придётся почитать документацию. Устройство сложное, много конфигураций.
 
Основные регистры задающие настройки подсистемы BCS+ BCSCTL1, BCSCTL2, BCSCTL3.
 
Регистр управляющий встроенным цифровым настраиваемым калиброванным генератором тактовых сигналов (DCO) - DCOCTL.
 
После сброса микроконтроллера, регистр DCOCTL принимает значения, соответствующие частоте в среднем диапазоне доступных частот микроконтроллера. Подробности надо смотреть в Главе 5.2 спецификации на семейство микроконтроллеров MSP430G2xxx.
 
 
CALBC1_1MHZ - калибровочный регистр для BCSCTL1, расположенный в памяти ПЗУ (flash), в сегмента А, прошит на заводе. 
CALDCO_1MHZ - калибровочный регистр для DCOCTL, расположенный в памяти ПЗУ (flash), в сегмента А, прошит на заводе.
 
 
Их определения приведены в файле определений (msp430g2231.h).
 
Их и перенесём, в управляющие регистры DCOCTL и BCSCTL1.
 
Здесь стоит заметить, что такие вещи (тонкости применения), как-то не очень явно прописаны в документации, обычно проскакивают мимо внимания, поэтому приходиться смотреть примеры, а потом находить в документации. Итеративное чтение документации, открывает новые бездны смысла.
 
Рассчитаем:
 
Если у нас, частота тактов основного источника MCLK составляет около 1000000 Гц, эту же частоту составляет и SMCLK. После делителя на 8, на таймер придёт сигнал с частотой 125000 Гц (125 кГц или 125000 фронтов в секунду). Таймер, начав считать, достигнет переполнения примерно за полсекунды (125000/65535). Примерно да, это не точно, для примера сойдёт. В противном случае, всё усложнится, потребуется стабильный генератор тактовых сигналов. Также, в описании характеристик встроенных источников тактовых сигналов, приведены параметры отклонения частоты, в зависимости от напряжения и температуры окружающей среды. Каково, 0.5%/Градус ?
 
А какая у нас точно частота микроконтроллера? А бог его знает.
 
Допишем обработчик прерывания:
Стоит, заметить, что здесь один обработчика для двух таймеров.
 
/* 
timeToSwitch1 - время переключать, функция обработчика прерывания от таймера
*/
 
#pragma vector=TIMERA0_VECTOR
#pragma vector=TIMERA1_VECTOR
__interrupt void timeToSwitch (void) { 
switch (TAIV) {
 
case TAIV_NONE:
 
break;
 
case TAIV_TACCR1:
 
break;
 
case TAIV_TAIFG: // Флаг переполнения
            
perioddec--;
if (perioddec == 0) { 
powerSwitchLed();
perioddec = period;
} 
break;
 
default:
break;
} // switch
 
} // timeToSwitch
 
 
И так как у нас, один период занимает полсекунды (приблизительно), то введём коэффициент 2, при установке периода.
 
 
 
int multiplicator = 2; // Умножитель периода, зависит от настроек тактовых генераторов
 
/*
setPeriod - установить временной интервал, в секундах
*/
 
void setPeriod(int seconds) {
period = seconds * multiplicator;
perioddec = period;
}
 
Также на контрасте с прерыванием, сделаем переключение зелёного светодиода(подключённого к выводу P1.6) в главном цикле. Эту часть возьмём из примера на сайте "Техасских инструментов", она тривиальна.
 
while (1) {
 
volatile unsigned int i; // volatile to prevent optimization 
P1OUT ^= BIT6; // Toggle P1.0 using exclusive-OR
i = 10000; // SW Delay
do i--;
while (i != 0);
}
 
Так постепенно, подобравшись к завершению, можно получить результирующий код. Приводить его нет смысла, т.к. теряется смысл постепенного, пошагового изучения.
 
Если очень кому-то будет надо, то в комментарии. Правда, я редко заглядываю в блог.