Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: СС430F5137 с нуля на asm
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
Страницы: 1, 2
vazz
Приобрел EM430F5137RF900 и MSP-FET430UIF, до приобретения особо не заморачивался с подготовкой "рабочего пространства" под новый проект, вроде бы камни не особенно новые, часто встречал различную информацию о них и не думал, что доставабельностью нужной для начала разработки инфы возникнут проблемы. Пол дня поискал в сети примеры заголовочных файлов под этот камень, примеры инициализации периферии, увы - результат 0. Это такой секрет? Такие данные достаются потом и кровью? Раньше работал с AVR (да и продолжаю время от времени), никаких таких проблем не помню, все было как-то проще достать и среда разработки нормальная (и бесплатная). Бог с ней со средой, поставил IAR KS на 4кБ кода (мне для попробовать). С самим ассемблером MSP и системой команд ознакомился поверхностно, страха не вызвал, вроде бы все просто (по крайней мере помигать светодиодом для начала - понятно как, а особенности и "камни" по ходу дела разберу). Стандартный заголовочный файл, который есть в папке иара "\inc" при пустом проекте вызывает негодование у компилятора IAR (дублирование лэйблов в объявлении регистров DMA). Попытался найти нормальный заголовочный файл в сети - нашел лишь такой же, "замазал" все места вызывающие негатив комментариями, чтобы не было ошибок. Далее попытался найти файл, который инициализировал бы мне всю периферию - тут все и загнулось. Я понимаю, что скорее всего при запуске МК все отключает сам и морганию светодиодом врядли что-то помешает, но хотелось бы иметь заготовку с полной инициализацией всех узлов МК ну и ессно полную таблицу векторов прерываний воткнуть в начало. Это добавляет уверенности в дальнейшем освоении камня. В отладчике иара тож пока особо не разобрался, если честно с первого раза иар вроде показался "классическим" средством разработки с простым и понятным интерфейсом, как начал лезть глубже - начало казаться, что первое впечатление обманчиво, чувство "чего-то не хватает" не покидает - ну к примеру как мне для отладчика задать тип МК, частоту кварца (чтоб время выполения отслеживать), также не нашел средства для заливки прошивки в МК (нужно отдельным ПО для этого ввоспользоваться чтоли?!). Прошу извинить за смешивание всего в кучу - помогите найти (или разобраться) с заголовочный файл для ассемблера под этот МК, файл инициализации всех устройств на борту, ну и вектора прерываний до кучи. На Си для МК не программирую и не особо горю желанием.
rezident
Цитата(vazz @ Feb 23 2013, 19:07) *
Стандартный заголовочный файл, который есть в папке иара "\inc" при пустом проекте вызывает негодование у компилятора IAR (дублирование лэйблов в объявлении регистров DMA). Попытался найти нормальный заголовочный файл в сети - нашел лишь такой же, "замазал" все места вызывающие негатив комментариями, чтобы не было ошибок.

Хедер cc430f5137.h из папки 430\inc\ не вызывает никаких негодований.
Цитата(vazz @ Feb 23 2013, 19:07) *
Далее попытался найти файл, который инициализировал бы мне всю периферию - тут все и загнулось. Я понимаю, что скорее всего при запуске МК все отключает сам и морганию светодиодом врядли что-то помешает, но хотелось бы иметь заготовку с полной инициализацией всех узлов МК ну и ессно полную таблицу векторов прерываний воткнуть в начало.

Я не знаю, каким именно предыдущим опытом вы так "развращены", но придется огорчить вас - в IAR нет встроенных средств для подготовки шаблона полной инициализации периферии. Можно использовать какие-то примеры, но полную инициализацию периферийных модулей вам придется писать самому - ручками. В IAR есть лишь этакий минивизард, который создает шаблон типа такого.
CODE
#include "msp430.h" ; #define controlled include file

NAME main ; module name

PUBLIC main ; make the main label vissible
; outside this module
ORG 0FFFEh
DC16 init ; set reset vector to 'init' label

RSEG CSTACK ; pre-declaration of segment
RSEG CODE ; place program in 'CODE' segment

init: MOV #SFE(CSTACK), SP ; set up stack

main: NOP ; main program
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; Stop watchdog timer
JMP $ ; jump to current location '$'
; (endless loop)
END

Цитата(vazz @ Feb 23 2013, 19:07) *
ну к примеру как мне для отладчика задать тип МК,
В опциях проекта задается. Project->Options->General Options->Target->Device в выпадающем списке выбираете CC430F5137.
Цитата(vazz @ Feb 23 2013, 19:07) *
частоту кварца (чтоб время выполения отслеживать),
В отладчике можно вывести окно Register, где отображаются CYCLECOUNTER и CCSTEP. Поделите их значение на частоту тактирования ядра (величина тактового сигнала MCLK) и вы получите время выполнения.
Цитата(vazz @ Feb 23 2013, 19:07) *
также не нашел средства для заливки прошивки в МК (нужно отдельным ПО для этого ввоспользоваться чтоли?!).
Опять же в опциях проекта нужно выбрать соответствующий эмулятор. Во-первых, нужно установить режим отладки, а не симуляции Project->Options->Debugger->Setup->FET Debugger. Во-вторых, выбрать его тип Project->Options->Debugger->FET Debugger->Setup->Texas Instrument USB-IF.

Вообще, хочется пожелать вам много терпения для изучении документации, которую вы можете найти на страничке продукта. http://www.ti.com/product/cc430f5137
В первую очередь вам понадобится User's Guide в котором описаны все, что есть общего в МК серии СС430. Конкретные же особенности данного кристалла (CC430F5137) вам следует уточнять в его datasheet. На той же страничке продукта есть дополнительные материалы по применению - Application Notes.
Про IAR читайте в его собственных документах. Help->ну и там соответствующий Guide.
vazz
Благодарю за напутственные пояснения, наконец-то появилось время вернуться к изучению данного вопроса. Значит подключил я отладчик к ПК и к таргету. Создал "пустой" проект на ассемблере. Узнал о том, что сторожевой таймер по умолчанию у MSP всегда включен - IAR сформировал начальный кусок кода с его отключением. Отлично, дополнительно я запретил все прерывания (на всякий случай) и принялся моргать светодиодом. Сходу получилось, я был рад, но потом начал разбираться в организации памяти этого камня и наткнулся на пока необъяснимую для меня (чайника) вещь. Я моргаю светодиодом с помощью начальной установки пина 0 порта 1 на вывод командой "BIS.W 0x0001,PADIR", затем собственно моргаю командами "BIS.W 0x0001,PAOUT" и "BIC.W 0x0001,PAOUT". При изменении кода на начальную установку командой "BIS.B 0x01,P1DIR" с морганием командами "BIS.B 0x01,P1OUT" и "BIC.B 0x01,P1OUT" иар благополучно запускает отладчик, но моргания не происходит. Почему? (прошу извинить за нубовские вопросы, но, как вы и сами знаете при начале освоения новой архитектуры бывают мелкие запинки, которые кажутся непреодолимыми стенами).

Честно говоря моргание не исчезает, почему то данные, которые я отправляю в порт не соответствуют реальным на плате таргета. Записываю 0x40 - получаю 0xFF. Эээ.. что-то я недочитал видимо..

Код
        DINT
        BIS.B   0xFF,P1DIR
        CLR.B   P1OUT
loop1:
        MOV.B     0x00,P1OUT
        MOV.B     0x01,P1OUT
        JMP loop1


Записываю в порт 0x00 - получаю 0x31. Записываю в порт 0x02 - получаю 0xFE. Что я делаю не так, Help!

Моргание получилось, ура, пока вслепую применил увиденный принцип записи (моргаю аж двумя светодиодами поочереди):

Код
        DINT
        CLR.B   P1SEL                  ; configure Port 1
        MOV.B   #0FFh,&P1DIR
        CLR.B   P1OUT
        CLR.B   P3SEL                  ; configure Port 3
        MOV.B   #0FFh,&P3DIR
        CLR.B   P3OUT
loop1:
        MOV.B     #00h,&P1OUT
        MOV.B     #40h,&P3OUT
        MOV.B     #01h,&P1OUT
        MOV.B     #00h,&P3OUT
        JMP loop1


Пока не понял как влияют символы "#" и "&", но они позволяют корректно передавать данные регистрам. Кстати, к примеру, запись числа в виде "#FFh" не катит, правильно будет "#0FFh" - этой фишки тоже пока не понял. Видимо все это особенности ассемблера.
rx3apf
"#" - непосредственный операнд, если значение начинается с hex-буквы, то надо ноль спереди. "&" - работа с переменной в памяти (или портом, которые тоже в памяти), адрес которой указан после этого символа.
vazz
А правда то, что ограничение 4кБ IAR Kickstart относится только к программам на Си? Если пишешь на ассемблере, то ограничений вообще никаких нет?
d7d1cd
Цитата(vazz @ Dec 28 2013, 21:31) *
А правда то, что ограничение 4кБ IAR Kickstart относится только к программам на Си? Если пишешь на ассемблере, то ограничений вообще никаких нет?

Вроде бы как да...
vazz
Почитал о режимах адресации, впринципе все понятно кроме одного: в чем принципиальная разница между символьной и абсолютной адресацией? Ну, к примеру, команды "MOV.B #00h,P3OUT" и "MOV.B #00h,&P3OUT" в результате дают одно и тоже. Единственное "преимущество" абсолюной адресации это гарантия переносимости программы с камня на камень. По-моему, можно на это забить по началу и пользоваться символьной адресацией без перегружения кода закорючками "&". Есть у профи мнения на этот счет? Или при обращении к конкретной периферии лучше изначально пользоваться абсолютной адресацией?
d7d1cd
Цитата(vazz @ Dec 29 2013, 13:47) *
Почитал о режимах адресации, впринципе все понятно кроме одного: в чем принципиальная разница между символьной и абсолютной адресацией? Ну, к примеру, команды "MOV.B #00h,P3OUT" и "MOV.B #00h,&P3OUT" в результате дают одно и тоже. Единственное "преимущество" абсолюной адресации это гарантия переносимости программы с камня на камень. По-моему, можно на это забить по началу и пользоваться символьной адресацией без перегружения кода закорючками "&". Есть у профи мнения на этот счет? Или при обращении к конкретной периферии лучше изначально пользоваться абсолютной адресацией?

Задавал я уже такой вопрос. Почитай: здесь. В принципе разницы нет, но при определенных условиях может быть выигрыш в размере кода.
vazz
Цитата(d7d1cd @ Dec 28 2013, 21:32) *
Вроде бы как да...

Я пока усмиряю тягу узнать все и сразу про эти MSP, поэтому не проверял. Вы случайно/специально не проверяли сей момент (на счет >4кБ ассемблерного кода)?
d7d1cd
Цитата(vazz @ Dec 29 2013, 15:55) *
Я пока усмиряю тягу узнать все и сразу про эти MSP, поэтому не проверял. Вы случайно/специально не проверяли сей момент (на счет >4кБ ассемблерного кода)?

Не проверял. Мои программы пока меньше 4 кБ...
vazz
Не могу найти/понять информацию про стек. Вершина ОЗУ находится по адресу 0x1AFF. Когда я записываю в SP адрес, то я должен, к примеру, указать адрес 0x1AFF или младший байт слова по четному адресу 0x1AFE? И если кому не трудно, то дайте ссылку, где это регламентируется.
vazz
А еще непонятны примочки ассемблера типа "NAME main" и "PUBLIC main", что-то Сишным духом больно пахнут. Это вообще обязательно? Без указания PUBLIC тело основного цикла main не будет "видно" остальному коду? И обязательно ли его (main) объявлять с помощью NAME?
d7d1cd
Цитата(vazz @ Dec 30 2013, 23:55) *
Не могу найти/понять информацию про стек. Вершина ОЗУ находится по адресу 0x1AFF. Когда я записываю в SP адрес, то я должен, к примеру, указать адрес 0x1AFF или младший байт слова по четному адресу 0x1AFE? И если кому не трудно, то дайте ссылку, где это регламентируется.

Вершина стека (регистр SP) всегда должна иметь четный адрес. Если ты укажешь 0x1AFF - это будет не правильно, так как ты указываешь нечетный адрес. Если ты укажешь 0x1AFE, то это будет правильно, но слово (2 байта) по адресу 0x1AFE никогда стеком занято не будет. Алгоритм "работы" стека, например при вызове функции, такой:
1. Из вершины стека вычитается 2 (SP = SP - 2);
2. По адресу, указанному в вершине стека, записывается адрес возврата.

При выходе из стека происходит все наоборот:
1. По адресу, указанному в вершине стека, читается адрес возврата;
2. К вершине стека прибавляется 2 (SP = SP + 2).

Даже если ты помещаешь в стек один байт (PUSH.B R15), то все равно вершина стека изменяется на 2.

Цитата(vazz @ Dec 31 2013, 01:57) *
А еще непонятны примочки ассемблера типа "NAME main" и "PUBLIC main", что-то Сишным духом больно пахнут. Это вообще обязательно? Без указания PUBLIC тело основного цикла main не будет "видно" остальному коду? И обязательно ли его (main) объявлять с помощью NAME?

Первое. PUBLIC main означает то, что функция main является публичной, то есть должна быть видна в другом модуле. В моем проекте 2 ассемблерных файла. Первый главный. В нем сделан основной цикл программы. В этом цикле выполняются функции, которые реализованы во втором файле. Так вот во втором файле помимо реализации тела функции (например функция Copying), есть строка PUBLIC Copying. А в первом файле есть строка EXTERN Copying, которая означает, что функция Copying является внешней.

Второе. NAME main - это имя модуля. Никакого отношения к функции main NAME не имеет. После NAME можно написать что-то другое (дать другое имя модулю).
vazz
Цитата(d7d1cd @ Dec 31 2013, 10:25) *
Первое. PUBLIC main означает то, что функция main является публичной, то есть должна быть видна в другом модуле. В моем проекте 2 ассемблерных файла. Первый главный. В нем сделан основной цикл программы. В этом цикле выполняются функции, которые реализованы во втором файле. Так вот во втором файле помимо реализации тела функции (например функция Copying), есть строка PUBLIC Copying. А в первом файле есть строка EXTERN Copying, которая означает, что функция Copying является внешней.

Второе. NAME main - это имя модуля. Никакого отношения к функции main NAME не имеет. После NAME можно написать что-то другое (дать другое имя модулю).


Про стек большое спасибо за пояснения! По поводу директив ассемблера, которых в IAR в избытке - у меня создается четкое ощущение, что мне навязывают некую "полезную" с точки зрения IAR модель программирования. Я, как неприемлющий языки высокого уровня в системах где память измеряется в кБ, не могу пока этого понять (на языке высокого уровня я пишу ПО верхнего уровня под Win, Я НЕ ПРОТИВНИК Си, а даже наоборот). "Видимость" блока памяти для меня вообще непонятная вещь. У меня есть набор команд (MSP), которые позволяют работать с любой ячейкой памяти 64кБ без исключения, что значит "видимость/невидимость"? Блин, помогите как-то уложить это в голове. Это конкретно IAR так нагибает разработчиков даже в ассемблерном коде использовать приблуды "видимости", "декларирования"?

Ну к примеру, у меня есть самый простой кусок кода, который выдает IAR в начале создания проекта. Я убираю оттуда директивы NAME, PUBLIC и прочую "чушь" (может и не чушь, я просто пока понять этого не могу). Между концом основного цикла main и директивой END (конец программы) добавляю инструкцию #include <file>, в file размещаю свои подпрограммы, которые хочу вызывать как из цикла main, так и из подпрограмм прерываний (таблицу векторов будем счиать добавленной в проект и подпрограммы тоже). Так вот без всяких приблуд типа PUBLIC, EXTERN я не смогу вызывать подпрограммы из цикла main и прерываний?

Да наступит просветление! Иначе дальше не получается двигаться.. Попробовал почитать в IAR "Help -> Assebler User Guide", но что-то как-то вобщем......(
d7d1cd
Цитата(vazz @ Dec 31 2013, 14:13) *
Про стек большое спасибо за пояснения! По поводу директив ассемблера, которых в IAR в избытке - у меня создается четкое ощущение, что мне навязывают некую "полезную" с точки зрения IAR модель программирования. Я, как неприемлющий языки высокого уровня в системах где память измеряется в кБ, не могу пока этого понять (на языке высокого уровня я пишу ПО верхнего уровня под Win, Я НЕ ПРОТИВНИК Си, а даже наоборот). "Видимость" блока памяти для меня вообще непонятная вещь. У меня есть набор команд (MSP), которые позволяют работать с любой ячейкой памяти 64кБ без исключения, что значит "видимость/невидимость"? Блин, помогите как-то уложить это в голове. Это конкретно IAR так нагибает разработчиков даже в ассемблерном коде использовать приблуды "видимости", "декларирования"?

Ну к примеру, у меня есть самый простой кусок кода, который выдает IAR в начале создания проекта. Я убираю оттуда директивы NAME, PUBLIC и прочую "чушь" (может и не чушь, я просто пока понять этого не могу). Между концом основного цикла main и директивой END (конец программы) добавляю инструкцию #include <file>, в file размещаю свои подпрограммы, которые хочу вызывать как из цикла main, так и из подпрограмм прерываний (таблицу векторов будем счиать добавленной в проект и подпрограммы тоже). Так вот без всяких приблуд типа PUBLIC, EXTERN я не смогу вызывать подпрограммы из цикла main и прерываний?

Да наступит просветление! Иначе дальше не получается двигаться.. Попробовал почитать в IAR "Help -> Assebler User Guide", но что-то как-то вобщем......(

Сразу хочу дать совет: не пытайся понять все и сразу. Это просто невозможно. Все приходит постепенно.
Итак, "чушь". Если IAR вставляет какие-то директивы, значит они нужны. Если ты их убираешь и все работает, то значит конкретно сейчас они могут быть убраны, а в другой какой-то ситуации тебе просто необходимо будет их использовать. Согласись, по кой хрен разработчикам компилятора для ассемблера придумывать в нем что-то "ненужное".

По поводу "видимости\невидимости". Эти директивы придуманы для упрощения жизни программиста, а не для его "нагибания". Проект на ассемблере может быть очень большой и запутаться там можно только в путь. Ты говоришь, что создашь отдельные файлы со своими функциями, добавишь этот файл директивой include и будешь вызывать оттуда функции. А ты попробуй так сделать. Я попытался. Ничего не получилось. Проведи эксперимент и отпишись. С наступающим, кстати!
vazz
Цитата(d7d1cd @ Dec 31 2013, 17:38) *
и будешь вызывать оттуда функции. А ты попробуй так сделать. Я попытался. Ничего не получилось. Проведи эксперимент и отпишись.


Я провел эксперимент. Итак в основном файле проекта следующий код:

Код
; +---------------------------------------------------------------------------+
; |                                                                           |
; |                  Проект: <?> ПП: <?> МК: <?> F= <?> МГц                   |
; |                  Версия: <?> Дата: <?> Пред.версия: <?>                   |
; |                              Примечания: <?>                              |
; |                                Права: <?>                                 |
; |                                                                           |
; +---------------------------------------------------------------------------+
#include "msp430.h"                    ; файл описание камня
#include "cc430f5137_INT.inc"          ; файл с векторами прерываний
        ORG     h'E000                 ; начало ПЗУ
#include "user_SIGN.inc"               ; файл с версией ПО
#include "user_DATA.inc"               ; файл с константами пользователя
#include "user_INTP.inc"               ; файл с подпрограммами прерываний
#include "user_SUBP.inc"               ; файл с подпрограммами пользователя
init:
        DINT                           ; запрещаем прерывания
        MOV.W   #WDTPW+WDTHOLD,&WDTCTL ; останавливаем сторожевой таймер
        MOV     #h'23FE, SP            ; установка стэка (и для CC430F5133)
#include "cc430f5137_INIT.inc"         ; файл с инициализацией периферии
main:                                  ; начало основного цикла программы
;
        CLR.B   P1SEL                  ; конфигурируем порт 1
        MOV.B   #h'FF,P1DIR
        CLR.B   P1OUT
        CLR.B   P3SEL                  ; конфигурируем порт 2
        MOV.B   #h'FF,P3DIR
        CLR.B   P3OUT
loop1:
        call    #led_flash
        JMP     loop1
;
        JMP     main                   ; зацикливаем
        NOP
        END


В файле user_SUBP.inc код:

Код
led_flash:
        MOV.B     #d'0,P1OUT
        MOV.B     #b'01000000,P3OUT
        MOV.B     #b'00000001,P1OUT
        MOV.B     #d'0,P3OUT
        RET


При пошаговой отладке (либо кнопкой Step Into либо Autostep) светодиоды моргают.

Содержимое файла векторов прерываний и файла самих подпрограмм, обрабатывающих прерывания думаю приводить не особо нужно. Кстати в файле user_INTP.inc метка, после которой идет команда:

Код
; +---------------------------------------------------------------------------+
; |                вектор по сбросу (reset) - на инициализацию                |
; +---------------------------------------------------------------------------+
int_reset:
        NOP
        jmp     init


Так вот метка init присутствует в основном файле и при отладке все переходы идут без каких-либо Сишных наворотов типа PUBLIC и пр. Я не говорю, что подобный код будет работать во всех ситуациях, я в силу начала освоения MSP о таких ситуациях могу не знать. НО, очень хочется верить, что код не нужно будет захламлять C-style директивами в будущем. А как оформить подпрограммы и организовать "блочную" структуру каждый программист и сам в состоянии решить без лишней "видимости/невидимости" (по крайней мере мне лично так спокойней, когда я контролирую то, что пишу).

У МЕНЯ ЕЩЕ ВОПРОС)) Он как раз близок к тому, что описано выше, поэтому надеюсь получить еще один бесплатный опытный совет sm.gif Вопрос касается немаскируемых прерываний, которые как я понял в семействе MSP430x5xxx в отличие от своих предшественников разделены на два индивидуальных обработчика таких прерываний - системный и пользовательский. Выше я привел фрагмент обработчика (пустого пока) прерывания RESET, далее я ставлю следующий код:

Код
; +---------------------------------------------------------------------------+
; |                 вектор системных немаскируемых прерываний                 |
; +---------------------------------------------------------------------------+
int_nmi_sys:
        NOP
        RETI
; +---------------------------------------------------------------------------+
; |              вектор пользовательских немаскируемых прерываний             |
; +---------------------------------------------------------------------------+
int_nmi_user:
        NOP
        RETI
...


Верно ли я делаю, ставя после прерывания RESET команду перехода на метку init, а после немаскируемых прерываний - выход из прерывания "RETI"? Как я понял немаскируемые прерывания свидетельствуют об ошибках, таких как сбой генерации или, к примеру, ошибка при работе контроллера DMA? Это системные, а пользовательские какие ошибки сопровождают? (блин, целых два вопроса сразу, сорри)

Цитата(d7d1cd @ Dec 31 2013, 17:38) *
С наступающим, кстати!


Спасибо! И тебя! И всех MSP-водов тоже))
d7d1cd
А что за расширение файла .inc? Вот ты говоришь, что использовать PUBLIC, EXTERN и прочее - это захламление проекта. А числовые константы описывать как то так #b'01000000 это норма? Это первое. Второе: вставлять директиву include посреди кода - это со стороны смотрится... а точнее не смотрится вообще никак.
Ты уверен, что правильно указываешь вершину стека 0х23FE? У тебя адрес 0х23FE стеком занят не будет никогда. Про таблицу векторов прерываний: зачем вставляешь команду NOP? По поводу обработки немаскируемых прерываний: открываешь даташит на микроконтроллер и смотришь что может быть источником немаскируемого прерывания. Так же тебе надо изучить сигналы POR и PUC микроконтроллера.
Я думаю, что немаскируемое прерывание не может заканчиваться командой RETI. Ведь после этой команды процессор должен продолжить выполнение прерванного кода, но этот код (скорее всего) вызвал немаскируемое прерывание. В обработчике немаскируемого прерывания можно определить что вызвало его, в зависимости от этого (если надо) выполнить какой-то код (допустим сохранить данные в МС) и перезагрузить программу.
vazz
Цитата(d7d1cd @ Dec 31 2013, 19:32) *
А что за расширение файла .inc?


Привычка с прошлых проектов на других МК (уже и не помню когда первый раз такое расширение применил и почему)

Цитата(d7d1cd @ Dec 31 2013, 19:32) *
А числовые константы описывать как то так #b'01000000 это норма? Это первое.


Тут как бы согласен, сам я так никогда числа не писал, но в IAR -> Assembler User Guide указано следующее:

Цитата
The following types of number representation are supported:

Integer type Example

Binary 1010b, b'1010
Octal 1234q, q'1234
Decimal 1234, -1, d'1234
Hexadecimal 0FFFFh, 0xFFFF, h'FFFF


Если из этих вариантов исключить привычное 0xFFFF, то для унификации применяеть суффикс системы исчисления либо в начале "<suf>'" либо в конце "XXXX<suf>". Но, к примеру если шестнадцатиричное число равно FFFF, то его надо записывать либо h'FFFF, либо 0FFFFh. Короче из-за добавления нуля ("ассоциируется" с заимствованием дополнительного байта, которого нет) мои рельсы съехали в сторону суффикса с апострофом. Короче это личный бзик в мозгу.

Цитата( @ Dec 31 2013, 19:32) *
Второе: вставлять директиву include посреди кода - это со стороны смотрится... а точнее не смотрится вообще никак.


Хм... ну не знаю что лучше - перегружать основной файл проекта всякими векторами и данными о версии ПО или аккуратно вставить эти процедуры и данные в то место памяти, где им самое место... Без обид, на вкус и цвет как говорится.

Цитата(d7d1cd @ Dec 31 2013, 19:32) *
Ты уверен, что правильно указываешь вершину стека 0х23FE? У тебя адрес 0х23FE стеком занят не будет никогда.


Это я понял, что одно слово между стеком и остальной памятью будет пустовать, пусть пока так, главное на этапе экспериментов то, что "не заползает ни на кого". Марафет вплоть до байта - позже, когда уверенно буду "рулить" этим камнем.

Цитата(d7d1cd @ Dec 31 2013, 19:32) *
Про таблицу векторов прерываний: зачем вставляешь команду NOP?


Тоже пока затрудняюсь объяснить wink.gif

Цитата(d7d1cd @ Dec 31 2013, 19:32) *
По поводу обработки немаскируемых прерываний: открываешь даташит на микроконтроллер и смотришь что может быть источником немаскируемого прерывания.


Ты прав конечно.

Цитата(d7d1cd @ Dec 31 2013, 19:32) *
Так же тебе надо изучить сигналы POR и PUC микроконтроллера.


И с системой сброса и с системой организации питания - первым делом, как без этого.

Цитата(d7d1cd @ Dec 31 2013, 19:32) *
Я думаю, что немаскируемое прерывание не может заканчиваться командой RETI. Ведь после этой команды процессор должен продолжить выполнение прерванного кода, но этот код (скорее всего) вызвал немаскируемое прерывание.


Тут не уверен я. Думается, в стек при немаскируемом прерывании записывается адрес возврата, поэтому без RETI не обойтись. Покопаю про это поподробнее.

Цитата(d7d1cd @ Dec 31 2013, 19:32) *
В обработчике немаскируемого прерывания можно определить что вызвало его, в зависимости от этого (если надо) выполнить какой-то код (допустим сохранить данные в МС) и перезагрузить программу.


Эт да.. Самое приятное анализировать, когда азы уже прочно усвоены, а нубовские ошибки - редкое исключение. Скорее бы уже дойти до этого состояния)
d7d1cd
Цитата(vazz @ Dec 31 2013, 20:05) *
Тут не уверен я. Думается, в стек при немаскируемом прерывании записывается адрес возврата, поэтому без RETI не обойтись. Покопаю про это поподробнее.

Зачем тебе возвращаться из немаскируемого прерывания? Мне кажется тут один путь - начать выполнение программы с вектора сброса.
vazz
Цитата(d7d1cd @ Dec 31 2013, 20:20) *
Мне кажется тут один путь - начать выполнение программы с вектора сброса.


Ну если возникновение немаскируемого прерывания свидетельствует ТОЛЬКО о каком-либо сбое в работе МК, причем этот сбой может привести к непредсказуемой работе (в т.ч. "зависанию"), то да - тут только возврат в исходную точку, начиная с начальных предустановок и пр. Но я ж пока не знаю все случаи когда возникает немаскируемое прерывание. Кстати, а почему немаскируемое? (стыдно конечно) Потому что оно возникает независимо от состояния бита глобального разрешения прерываний (GIE)?
d7d1cd
Цитата(vazz @ Dec 31 2013, 20:29) *
Кстати, а почему немаскируемое? (стыдно конечно) Потому что оно возникает независимо от состояния бита глобального разрешения прерываний (GIE)?

Совершенно верно.
SM
Цитата(vazz @ Dec 31 2013, 20:05) *
Хм... ну не знаю что лучше - перегружать основной файл проекта всякими векторами и данными о версии ПО или аккуратно вставить эти процедуры и данные в то место памяти, где им самое место... Без обид, на вкус и цвет как говорится.


include придуманы для подключения файлов с описанием символьных констант, и т.п., необходимого на этапе компиляции. А для подключения файлов с полноценным кодом/данными - придуман редактор связей (линкер), и те самые public/extern - показывающие линкеру, что метка определена снаружи объектного модуля, и что определена внутри, но должна быть видимой снаружи.
при использовании include - компилятор компилирует КАЖДЫЙ РАЗ все полностью, что вы там наинклудили. А линковка - компилирует только измененный файл, а те, в которых изменений не было, не перекомпилирует. поэтому написание функций в разных файлах, объявление public/extern и сборка редактором связей предпочтительнее, чем включение кучи файлов по include в один файл "верхнего уровня". И, кстати, от исходного языка, С это, или АСМ, это не зависит. Делаете каждому файлу свой объектный модуль, и собираете их в единое целое линкером.

И, кстати, это, примерно так для любых архитектур, public/extern и связывание таким образом объявленных меток линкером. А не только MSP430. Как только Вы делаете два файла с кодом/данными, которые компилируются ПО ОТДЕЛЬНОСТИ, а не связаны через include, так сразу нужны объявления public/extern.
vazz
Цитата(SM @ Jan 1 2014, 13:36) *
public/extern - показывающие линкеру, что метка определена снаружи объектного модуля, и что определена внутри, но должна быть видимой снаружи.


Благодарю за разъяснения, я немного понимаю про объектное программирование, и про локальные и про глобальные данные/функции. Но все это не относится к ассемблеру - машинному коду. Линкер этот как раз не имеет никакого отношения к машинному коду и нужен только для объектного программирования. Поэтому мешать все в кучу не хочется.

Оффтоп: при программировании на ассемблере для нескольких 8-битных МК я ни разу не встречался с чем-то подобным, поэтому мне было трудно понять эту "фишку". Теперь (надеюсь) с этим все ясно, у кого есть желание применять подобный стиль - его право. Я предпочту все таки не мутить воду и располагать всем адресным пространством без каких-либо ширм и перегородок.
d7d1cd
Цитата(vazz @ Jan 1 2014, 14:14) *
Благодарю за разъяснения, я немного понимаю про объектное программирование, и про локальные и про глобальные данные/функции. Но все это не относится к ассемблеру - машинному коду. Линкер этот как раз не имеет никакого отношения к машинному коду и нужен только для объектного программирования. Поэтому мешать все в кучу не хочется.

Оффтоп: при программировании на ассемблере для нескольких 8-битных МК я ни разу не встречался с чем-то подобным, поэтому мне было трудно понять эту "фишку". Теперь (надеюсь) с этим все ясно, у кого есть желание применять подобный стиль - его право. Я предпочту все таки не мутить воду и располагать всем адресным пространством без каких-либо ширм и перегородок.

Линкер имеет отношение к любому коду. Поверь. А пользоваться или не пользоваться возможностями EXTERN и PUBLIC - это твое дело...
SM
Цитата(vazz @ Jan 1 2014, 14:14) *
Благодарю за разъяснения, я немного понимаю про объектное программирование, и про локальные и про глобальные данные/функции. Но все это не относится к ассемблеру - машинному коду. Линкер этот как раз не имеет никакого отношения к машинному коду и нужен только для объектного программирования. Поэтому мешать все в кучу не хочется.


Линкер к "объектному программированию" отношения никакого не имеет вообще !!! (Вы что вообще имели в виду то? нет такого понятия на самом деле, есть "объектно-ориентированное", но линкер и к нему непосредственного отношение не имеет).

Линкер имеет отношение к формированию АБСОЛЮТНО ЛЮБОГО кода, который загружается непосредственно внутрь МК из кода, сгенерированного транслятором ассемблера (или компилятором языка высокого уровня). Транслятор ассемблера преобразует текстовый файл с мнемониками инструкций в объектный модуль (расширение .R43, если я не ошибаюсь, в MSP430, а вообще бывает обычно .obj, .o). Далее, линкер (редактор связей) объединяет один или более таких модулей, и формирует на выходе файл, который может быть загружен в МК (для MSP430, если не ошибаюсь, принято расширение такого файла .D43). Без, так сказать, услуг линкера НЕТ СПОСОБА получить файл, который можно загрузить в МК! Хоть из одного исходника, хоть из нескольких. Если же Вы такой, с позволения сказать "фанат" ассемблера, давно бы пора разобраться, как, и при помощи каких шагов, из этих самых мнемоник ассемблера получается выходной код, готовый к загрузке в МК!

Так вот, еще раз, для находящихся в танке. public/extern - это механизм указания линкеру, как связать несколько объектных модулей, каждый из который сгенерирвоан транслятором ассемблера из своего исходного текста, в единое целое - загружаемый в МК модуль. А использование include вместо отдельной трансляции файлов с последующей линковкой - это, как минимум, плод полного незнания процесса формирования кода из исходных файлов. И этот механизм един практически для любой архитектуры любой разрядности. Пожалуй, единственный вариант, когда загружаемый код генерировался сразу транслятором ассемблера без линкера, это древние трансляторы начального уровня для i8080 (КР580ВМ80) и Z-80, которые и работали на этих же платформах, где не было накопителей, кроме магнитной ленты... Сейчас такой архаизм забыт, и забыт, скорее всего, навсегда.
vazz
По мере разбирательства пытаюсь читать CC430 Users Guide и описания конкретных моделей МК. Вот добрался до системы тактирования, и появилось пара вопросов:

В Users Guide про режим LPM0 сказано:

Цитата
CPU, MCLK are disabled.
ACLK is active. SMCLK optionally active (SMCLKOFF = 0).
DCO is enabled if sources ACLK or SMCLK (SMCLKOFF = 0).
DCO bias is enabled if DCO is enabled or DCO sources MCLK or SMCLK
(SMCLKOFF = 0).


Про MCLK в упоминании про DCO это просто опечатка? Вместо него там должно быть ACLK?

Вопрос 2:

Что вообще такое DCO bias? Где это смещение описано, не могу вкурить..

Вопрос №3:

В Users Guide про режимы LPM2 и LPM3:

Цитата
LPM2

CPU, MCLK are disabled.
ACLK is active. SMCLK is disabled.
DCO is enabled if sources ACLK.
FLL is disabled.

LPM3

CPU, MCLK are disabled.
ACLK is active. SMCLK is disabled.
DCO is enabled if sources ACLK.
FLL is disabled.


В Datasheet:

Цитата
LPM2

CPU is disabled
MCLK and FLL loop control and DCOCLK are disabled
DCO's dc-generator remains enabled
ACLK remains active

LPM3

CPU is disabled
MCLK, FLL loop control, and DCOCLK are disabled
DCO's dc-generator is disabled
ACLK remains active


Догадываюсь - верить надо Datasheet?
rezident
Цитата(vazz @ Jan 3 2014, 00:21) *
Про MCLK в упоминании про DCO это просто опечатка? Вместо него там должно быть ACLK?

Почему опечатка? В режиме LPM0 отключено только тактирование ядра. Ядро всегда от MCLK тактируется.
Цитата(vazz @ Jan 3 2014, 00:21) *
Вопрос 2:

Что вообще такое DCO bias? Где это смещение описано, не могу вкурить..

DCO это встроенный RC-генератор. DCO bias это истоник тока, "изображающий" из себя R через которое заряжается C.
Цитата(vazz @ Jan 3 2014, 00:21) *
Вопрос №3:

В Users Guide про режимы LPM2 и LPM3:

В Datasheet:

Догадываюсь - верить надо Datasheet?

В процитированном нет противоречий. "DCO is enabled if sources ACLK." переводится как "Работа DCO разрешена, если он является источником сигнала для ACLK."
У MSP430 три внутренних тактовых сигнала: MCLK, SMCLK и ACLK. M(ain)CLK тактирует ядро и некоторую часть периферии. S(ub)M(ain)CLK и ACLK могут тактировать периферию. SMCLK обычно более высокочастотный сигнал, чем ACLK, т.к. для ACLK типично используется выходной сигнал часового генератора 32кГц.
В свою очередь генераторами/источниками сигналов для всех трех CLK могут быть НЧ и/или ВЧ генераторы XT1/LFXT, XT2 и/или DCO и/или FLL и/или другой внешний тактовый сигнал. Подробности см. в User's Guide.
Такое разнообразие источников тактовых сигналов и генераторов позволяет очень гибко управлять энергопотреблением MSP430, что весьма выгодно отличает эти МК от, скажем, большинства Cortex-M, у которых в данный конкретный момент времени источник сигнала тактирования может быть только один, а все остальные внутренние сигналы тактирования являются производными от него.
vazz
Цитата(rezident @ Jan 3 2014, 00:03) *
Почему опечатка? В режиме LPM0 отключено только тактирование ядра. Ядро всегда от MCLK тактируется.


Не, я имел в виду то, что в LPM0 тактовый источник MCLK отключен, а далее пишется, что DCO задействуется, если является задающим для MCLK. Мне показалось это бессмыслицей.

Цитата(rezident @ Jan 3 2014, 00:03) *
DCO это встроенный RC-генератор. DCO bias это истоник тока, "изображающий" из себя R через которое заряжается C.


Вот спасибо, теперь про DCO bias стало не так страшно читать, смысл уловил.

За остальные пояснения тоже мэни сэнкс.

Цитата(rezident @ Jan 3 2014, 00:03) *
весьма выгодно отличает эти МК от, скажем, большинства Cortex-M, у которых в данный конкретный момент времени источник сигнала тактирования может быть только один, а все остальные внутренние сигналы тактирования являются производными от него.


Оффтоп: это с одной стороны радует (что у CORTEX попроще система тактирования), потому как LPC1788 на отладочной плате и программатор к нему лежат недалеко и мне необходимо и их освоить, т.к. проект требует совместного применения CC430 (в качестве элементов сети) и CORTEX-M3 + CC1101 (в качестве ведущего HOSTа), а с другой стороны является давящим напоминанием о необходимости освоения ARM.

Вычитал в Datasheet, что мин.потребляемый ток модуля RF1A в спящем режиме это 100мкА, это так? Больше никаких сведений о потреблении в спящих режимах не вижу, при этом в Datasheet на CC1101 есть данные о потреблении в спящем режиме и 35мкА и 0,5мкА.
rezident
Цитата(vazz @ Jan 3 2014, 03:09) *
Не, я имел в виду то, что в LPM0 тактовый источник MCLK отключен, а далее пишется, что DCO задействуется, если является задающим для MCLK. Мне показалось это бессмыслицей.

Процитированное вами предолжение является сложноподчиненным "DCO bias is enabled if DCO is enabled or DCO sources MCLK or SMCLK" -> DCO bias задействован, если задействован сам DCO или генератор DCO является источником тактового сигнала для MCLK или SMCLK.
Вновь я не наблюдаю противоречий.
Цитата(vazz @ Jan 3 2014, 03:09) *
Вычитал в Datasheet, что мин.потребляемый ток модуля RF1A в спящем режиме это 100мкА, это так? Больше никаких сведений о потреблении в спящих режимах не вижу, при этом в Datasheet на CC1101 есть данные о потреблении в спящем режиме и 35мкА и 0,5мкА.

Спящий режим спящему режиму рознь. Потребление зависит от многих факторов - в частности от того а) какая именно периферия включена и б) с какой скважностью и на какое время ядро просыпается, чтобы программа могла "оценить" свое собственное и окружающее состояние. Лень заглядывать в даташит незнакомого модуля, но предполагаю, что при 100мкА у него приемная часть включена и пассивно бдит за эфиром, а при 0,5мкА у модуля спит все, что только можно, и лишь только одни часы "тикают".
vazz
IAR почему-то ругается на команду CMP.B по отношению к регистру SYSRSTIV. Как я понял пространство под этот регистр в памяти - это 1 байт. Или все таки слово? И если он читается как слово, то старший байт при этом всегда равен 0x00?

Этот вопрос снят, прошу извинить, криво прочиатал Users Guide. Ответ: под регистр выделено слово в памяти.
vazz
Господин rezident, немного наслышан о тебе, как об опытном специалисте. Вот скажи мне как на духу, можно ли из DCO в сочетании с FLL добиться достойной стабильности в выдержке временных интервалов или лучше сразу оставить эти недежды, подцепить часовой кварц и не морочить себе голову? Как при этом пострадает потребление (если вообще пострадает)? Возможно при этом еще чем-то приходится жертвовать (кроме копеек на кварц)?
d7d1cd
Цитата(vazz @ Jan 4 2014, 00:37) *
Господин rezident, немного наслышан о тебе, как об опытном специалисте. Вот скажи мне как на духу, можно ли из DCO в сочетании с FLL добиться достойной стабильности в выдержке временных интервалов или лучше сразу оставить эти недежды, подцепить часовой кварц и не морочить себе голову? Как при этом пострадает потребление (если вообще пострадает)? Возможно при этом еще чем-то приходится жертвовать (кроме копеек на кварц)?

Я конечно не опытный специалист. Точнее я неопытный не специалист rolleyes.gif Однако я думаю, что от DCO нельзя ждать стабильности, ведь его частота зависит от окружающей температуры. Подключение часового кварца, как я думаю, почти не повлияет на энергопотребление, если его использовать в качестве хронометра. Ведь все время проц будет "спать" в режиме LPM3 и "большое" потребление будет только при возникновении прерывания. Я знаю устройство на MSP (промышленное конечно), в котором кроме всего есть часы реального времени. Так вот от батареи 3 вольта эти часы правильно функционируют гарантированно 1 год.

P.S. Да поправит меня rezident или другой опытный специалист biggrin.gif
vazz
Цитата(d7d1cd @ Jan 4 2014, 12:59) *
Я знаю устройство на MSP (промышленное конечно), в котором кроме всего есть часы реального времени. Так вот от батареи 3 вольта эти часы правильно функционируют гарантированно 1 год.


Я сперва тоже подумывал про часы реального времени, т.к. необходимо архивировать данные за длительные промежутки времени. А потом решил, что точки на CC430 будут калиброваться от хоста по времени, а вот в нем уже придется заморочиться с RTC.

А на счет DCO и FLL спрашивал, потому как в Users Guide встретил "When the FLL operation is disabled, the DCO continues to operate at the current settings. Because it is not stabilized by the FLL, temperature and voltage variations influence the frequency of operation.", а потом меня что-то отвлекло и я ушел от этой темы, подумав что FLL каким-то образом помогает компенсировать влияние температуры и решил по ходу дела спросить у мудрых разработчиков.

А можно еще вопрос?))

Не могу я понять смысл взаимодействия с SVSM(L/H)DLYIFG. Что это за задержка? Смутно понял, что эта задержка нужна для устаканивания Vcore/Vcc при изменении этих самых Vcore/Vcc. А можно для тех кто в танке по простому в двух словах обрисовать сей механизм, если не трудно конечно. И как вычисляется эта задержка (зависит же и от температуры наверное и от уровня Vcore/Vcc..)?
d7d1cd
vazz, можно, как ты говоришь, оффтоп... Ты пишешь на ассемблере. Подскажи, как описать переменную (размером, например, 2 байта), расположенную по адресу 0х09FE. Чтобы потом, если я вдруг ошибусь и в тексте программы к этой переменной обращусь как к 1 байту (MOV.B например), компилятор поругал меня за это.
vazz
Цитата(d7d1cd @ Jan 4 2014, 14:39) *
Чтобы потом, если я вдруг ошибусь ..., компилятор поругал меня за это.


Наверное как-то так:

Код
#define var1_ (0х09FE)                  //объявляем переменную var1
DEFCW(var1,var1_)
d7d1cd
Цитата(vazz @ Jan 4 2014, 15:48) *
Наверное как-то так:
Код
#define var1_ (0х09FE)                  //объявляем переменную var1
DEFCW(var1,var1_)

Я тоже так попробовал сделать (только для объявления байта надо писать DEFC, для слова DEFW). Если var1 - это просто переменная, то все хорошо. Но у меня в программе есть массивы. Я попробовал таким образом описать адрес первого элемента массива. При обращении в коде к первому элементу массива все хорошо, а вот при обращении к остальным компилятор выдает предупреждение:
Код
// var1 - это у нас массив 5-ти однобайтных чисел
MOV.B   #5, &var1     // Запись байта в первый элемент массива. Тут все отлично!
MOV.W   #5, &var1     // Запись слова в первый элемент массива. Тут компилятор говорит об ошибке. Все как надо!
MOV.B   #5, &var1 + 1     // Запись байта во второй элемент массива. И вот тут предупреждение

Кроме того, как я понял, конструкцией вида DEFC(W) описываются регистры специального назначения. А для пользовательских переменных есть директивы DS8, DS16 и т. д. Как только сделать то, что хочется?...
rezident
Цитата(vazz @ Jan 4 2014, 01:37) *
можно ли из DCO в сочетании с FLL добиться достойной стабильности в выдержке временных интервалов или лучше сразу оставить эти недежды, подцепить часовой кварц и не морочить себе голову?

RC-генератор никогда не отличался особой стабильностью. Его частота зависит от температуры и напряжения питания. И хотя за счет различных ухищрений добились стабильности DCO в единицы процентов во всем диапазоне рабочих температур, но до стабильности даже плохонького кварцевого генератора ему как до Луны пешком. Вообще все погрешности описаны в datasheet конкретного кристалла. Для СС430F5137 в таблице DCO Frequency на стр. 52 указано типовое значение температурного дрейфа DCO величиной 0,1%/°C и дрейф от изменения напряжения питания (опять же типовое значение) 1,9%/V.
С FLL тут вообще мимо. FLL поддерживает среднее значение частоты DCO на периоде разрядности модулятора. Причем в MSP430 FLL "цифровая", а не аналоговая. Т.е. поддержание среднего значения заданной частоты происходит за счет пропуска импульсов более высокой тактовой частоты. Так, что для "связных" дел использование FLL вообще не стоит даже и планировать. FLL может пригодиться для подстройки частоты DCO, но не для постоянной работы в качестве источника тактовой частоты.
Цитата(vazz @ Jan 4 2014, 01:37) *
Как при этом пострадает потребление (если вообще пострадает)?

Потребление генератора опять же нужно смотреть в datasheet, таблица Crystal Oscillator, XT1, Low-Frequency Mode на стр.50.
Цитата(vazz @ Jan 4 2014, 01:37) *
Возможно при этом еще чем-то приходится жертвовать (кроме копеек на кварц)?

Основное отличие (если конечно не рассматривать точность поддержания частоты) RC-генераторов (DCO, REFO, VLO) от кварцевых (XT1/LFXT, XT2) состоит в быстродействии включения в рабочий режим. DCO готов к работе уже через 6мкс. Для XT1/XT2 с высокочастотным кварцем время готовности после запуска/включения составляет под сотню мс. Для XT1/LFXT с часовым кварцем - порядка 500мс и даже до 1с (с дерьмовеньким noname кварцем). С другой стороны в типичном применении часовой кварц и не выключают. Ибо генератор LFXT потребляет не более 0,5мкА.
Опять же типовым hint для MSP430 является подстройка частоты DCO от LFXT с часовым кварцем. Для этого у СС430F5137 есть возможность внутренне подключить ACLK к CCI2B таймера TimerA0 и с помощью него измерить отношение частоты SMCLK (тактируемого от DCO) к частоте ACLK (тактируемого от часового генератора). Другие варианты подстройки частоты DCO - использование REFO и FLL. Но вы сами должны понимать, что REFO это такой же генератор RC-типа и соответсвенно он может давать погрешность до 3,5% во всем рабочем температурном диапазоне, см. таблицу Internal Reference, Low-Frequency Oscillator (REFO) в datasheet СС430F5137.

Цитата(vazz @ Jan 4 2014, 15:02) *
я ушел от этой темы, подумав что FLL каким-то образом помогает компенсировать влияние температуры

Никаким образом не помогает компенсировать темепературу! FLL это не генератор, а Frequency Locked Loop - устройство, поддерживающее на выходе среднюю частоту на периоде с разрядностью собственного модулятора. В качестве опоры/эталона FLL использует частоту от внешнего тактового генератора. Соответственно долговременная стабильность выходной частоты DCO, управляемого FLL, не может быть лучше стабильности частоты внешнего генератора. А кратковременная стабильность на периоде модулятора вообще хреновая, т.к. пропуски импульсов FLL вызывают джиттер (дрожание фазы) выходной частоты.
Цитата(vazz @ Jan 4 2014, 15:02) *
А можно для тех кто в танке по простому в двух словах обрисовать сей механизм, если не трудно конечно. И как вычисляется эта задержка (зависит же и от температуры наверное и от уровня Vcore/Vcc..)?

Признаюсь честно, что у меня был только один проект на кристалле, имеющем эту самую систему SVS (MSP430F5438A). Но я SVS не использовал и поэтому все возможности ее не исследовал, обойдясь типовыми/рекомендуемыми значениями регистров, и, запретив генерацию прерываний событий от SVS. Через пару месяцев планируется доработка этого проекта, вот тогда возможно и дойдут руки до использования SVS. laughing.gif
Вообще про работу SVS с графиками и времянками описано в разделе 2.2 PMM Operation в CC430 Family User's Guide Rev.E. - slau259e.pdf
vazz
Цитата(d7d1cd @ Jan 4 2014, 16:19) *
Как только сделать то, что хочется?...


Я не крутой программер (я больше схемотехник), поэтому я пораскинул тем скудным багажом опыта, который приобрел и ничего лучше в голову не пришло, как применить индексный режим адресации. Т.е. в одном из регистров ЦПУ хранишь начальный адрес своего array, а с помощью другого регистра делаешь смещение. Ну ты это и сам понимаешь наверное, sorry.

d7d1cd, rezident спасибо парни! бывают же отзывчивые люди, бескорыстно делящиеся опытом. Побольше бы таких - глядишь Родина наша не была бы в хвосте сектора радиоаппаратостроения и производства отчечественных РЭК)

rezident, спасибо за развернутые ответы, прям как литературу читаешь и балдеешь, все по-русски и с конкретными цифрами) Единственное по поводу SVS(M) - я наверное запрещу прерывания по возвращению уровней напряжения в удовлетворительное состояние дабы тоже пока не заморачиваться с этим, а вот при снижении ниже плинтуса надо бы наверное хоть подмаргнуть пользователю (если есть чем), что мол "барахлит чо-то". Мне кажется этот мониторинг сделан по большей части, чтобы отловить "неверное" соотношение частота/напряжение ядра (например, когда напряжение Vcore снижено до минимума, а частота выжимается слишком большая).

А можно еще поспрашивать?

Так сказать вопрос опять же для опытных. Я тут подбираюсь к начальной инициализации всех узлов на борту. И вот думаю.. А как по феншую принято проводить начальную настройку MSP430, вернее в каком порядке. Я вот как думаю (и если я недальновидно думаю, то очень прошу меня поправить на начальном этапе):

1. Останов WDT. (приоритет высший, т.к. дается 32мс на раздумья)
2. Настройка системы сброса.
3. Настройка системы питания.
4. Настройка системы тактирования.
5. Инициализация всей периферии, в т.ч. настройка тактирования, прерываний и питания каждого из периферийных модулей (по началу планирую все отключать, а потом брать этот шаблон и в новом проекте включать только то, что нужно, не вспоминая как отключать остальной функционал).

Или может после WDT надо сперва систему тактирования настроить? Вобщем кто в какой последовательности делает, учитывая свой опыт?

И попутно вопрос, т.к. порылся и нашел в закромах кварцы на 32.768кГц, которые шли в наборе вместе с отладочными модулями EM430. Они изначально не впаяны на платы, это возможно с чем-то связано? Типа попробуйте сначала с DCO помучиться, а когда надоест сами впаяете? Ничего ж страшного не будет, если я впаяю их прямо сейчас на свое штатное место, конденсаторы на вх/вых гены никакие не нужны как я понял, всё внутри предусмотрено.
SM
Цитата(d7d1cd @ Jan 4 2014, 16:19) *
А для пользовательских переменных есть директивы DS8, DS16 и т. д. Как только сделать то, что хочется?...


Объявить его по DSn в своей отдельной секции данных (после rseg MY_SECT_NAME), а секцию - уже расположить по заданному адресу.
rezident
Цитата(vazz @ Jan 4 2014, 21:08) *
а вот при снижении ниже плинтуса надо бы наверное хоть подмаргнуть пользователю (если есть чем), что мол "барахлит чо-то". Мне кажется этот мониторинг сделан по большей части, чтобы отловить "неверное" соотношение частота/напряжение ядра (например, когда напряжение Vcore снижено до минимума, а частота выжимается слишком большая).

SVS аппартно-программный модуль и нужен в основном для правильного функционирования "железа". Т.е. когда процессы меняются быстро и что-то может из-за этого заглючить. Задействовать SVS для мониторинга величины питания батарейки, чтобы потом подморгнуть или нарисовать индикацию пользователю, не имеет смысла - для этого (при медленном изменении величины) больше подходит АЦП, который унунтре имеется. У него еще и внутренний вход мультиплексора для измерения напряжения собственного питания предусмотрен.
Цитата(vazz @ Jan 4 2014, 21:08) *
Я вот как думаю (и если я недальновидно думаю, то очень прошу меня поправить на начальном этапе):

1. Останов WDT. (приоритет высший, т.к. дается 32мс на раздумья)
2. Настройка системы сброса.
3. Настройка системы питания.
4. Настройка системы тактирования.
5. Инициализация всей периферии, в т.ч. настройка тактирования, прерываний и питания каждого из периферийных модулей (по началу планирую все отключать, а потом брать этот шаблон и в новом проекте включать только то, что нужно, не вспоминая как отключать остальной функционал).

Вполне нормальный/допустимый порядок. Тут еще кое-что от нюансов применения зависит.
Во-первых, следует помнить, что дефолтное состояние (default state) всей периферии MSP430 после сброса и/или включения питания позволяет ему нормально работать вообще без инициализации питания и тактирования (кроме настройки функций пинов конечно же).
Тут нюансы состоят в том: нужно ли вам обрабатывать и определять причины (ре)старта, например, было ли включение питания или была перезагрузка по WDT или от bootloader или какого-то иного источника прерываний? Как быстро вам нужно инициализировать все периферию: если очень быстро, то имеет смысл вначале настроить систему тактирования и питания для работы на более высокой частоте. Если быстро не обязательно, то можно вначале функции пинов настроить, чтобы на выходах было заранее определенное состояние и что-либо висящее снаружи не потребляло много в этот момент, когда на выходах "плавающие" уровни.
Во-вторых, нюанс языка программирования: ASM или ЯВУ типа Си? На ASM можно успеть инициализировать и до срабатывания WDT. А если Си, то по-хорошему отключать WDT нужно не в main, а в функции _low_level_init, которая вызывается еще до main. Потому, что если в программе будут большие глобальные массивы, то процедура очистки глобальных переменных (по стандарту в Си все глобальные переменные должны быть инициализированы нулями или конкретными значениями) не успеет все выполнить до срабатывания WDT и main у вас не стартует вообще никогда.
В-третьих, некоторые параметры инциализации могут зависеть от текущих пользовательских настроек. Поэтому процедура инициализации должна предусматривать не только собственно начальную инициализацию, но и реинициализацию с другими (заданными) параметрами. Например, параметры настройки UART или время перехода в режим энергосбережения с гашением индикатора и отключением связи или еще что-то такое же. Причем весьма желательно, чтобы реинициализация одного модуля не влияла на работоспособность других модулей. Что в случае с системой тактирования - задача довольно нетривиальная.
В общем начальный выбор ваш вполне верный, а дальше думаю вы "допилите" в соответствии со своими собственными нюансами. Только советую не лениться и сразу продумать и выделить HAL (Hardware Application Level), а также предусмотреть возможность реинициализации всех модулей. Да, не скрою, что это может занять довольно много времени. Но зато потом вы получите бонусы от того, что вас минуют многие "головняки" с работой периферии и вам не придется начинать писать все заново "с низов" cool.gif
vazz
Цитата(rezident @ Jan 4 2014, 20:48) *
сразу продумать и выделить HAL (Hardware Application Level), а также предусмотреть возможность реинициализации всех модулей.


Точняк! Надо распределить ПЗУ на сектор своего "загрузчика", а остальную часть ПЗУ поделить пополам, одну половинку - под "горячее", вторую - под бэкап. Я конечно еще не добрел, но думается что MSP430 сам себя шить может? Одна половина ПЗУ будем служить пространством под выполняемое прикладное ПО, а вторая - для переноса первой половины перед обновлением ПО по радиоканалу. В случае потери связи во время сеанса обновления - делаем бэкап без потери работоспособности изделия smile3009.gif
d7d1cd
Цитата(SM @ Jan 4 2014, 20:45) *
Объявить его по DSn в своей отдельной секции данных (после rseg MY_SECT_NAME), а секцию - уже расположить по заданному адресу.

А можно примерчик... И сразу вопрос: а если я в сегменте CODE буду располагать константы, то место, занятое константами, кодом занято не будет?
SM
У меня сейчас IAR не установлен под 430. так что сорри, скриншотов не дам. Давно было. А по коду - кажется вот так:


rseg DATA0:DATA, 01234h
или
ASEGN DATA0:DATA
ORG 01234h

my_data: DS8 16


а далее дело линкера - он секцию на указанный адрес забросит.

Если в любой секции типа RSEG/ASEG будут константы, то их место не займется кодом никогда. Линкер объединяет все где либо найденные куски одинаковых секций в последовательность кода/данных. Исключение - COMMON секции, их линкер ставит на один и тот же физический адрес, позволяя по-разному использовать одну и ту же область памяти (например разные подпрограммы могут использовать одну и ту же область данных каждая по-своему). Но таким свойством обладают только COMMON-сегменты.

d7d1cd
Цитата(SM @ Jan 4 2014, 21:36) *
У меня сейчас IAR не установлен под 430. так что сорри, скриншотов не дам. Давно было. А по коду - кажется вот так:


rseg DATA0:DATA, 01234h
или
ASEGN DATA0:DATA
ORG 01234h

my_data: DS8 16


а далее дело линкера - он секцию на указанный адрес забросит.

Если в любой секции типа RSEG/ASEG будут константы, то их место не займется кодом никогда. Линкер объединяет все где либо найденные куски одинаковых секций в последовательность кода/данных. Исключение - COMMON секции, их линкер ставит на один и тот же физический адрес, позволяя по-разному использовать одну и ту же область памяти (например разные подпрограммы могут использовать одну и ту же область данных каждая по-своему). Но таким свойством обладают только COMMON-сегменты.


Сделал как советуете. Создаю место для переменной размером в 2 байта. Однако если я пытаюсь отправить в my_data не слово, а байт (что как бы ошибка), то компилятор мне ничего не говорит... А ведь тут ошибка.
SM
Какая же это ошибка. Доступ к любому отдельному байту слова не ошибка, а фича sm.gif
Тут исключения только отдельные регистры железа, к которым нельзя физически так обращаться в силу каких-то внутренних особенностей реализации
d7d1cd
Цитата(SM @ Jan 4 2014, 22:00) *
Какая же это ошибка. Доступ к любому отдельному байту слова не ошибка, а фича sm.gif

То есть, получается так, что я задумывал использовать my_data как хранилище слова (о чем ясно указал - DS16), однако при написании кода я ошибся и обратился к этому слову как к байту. Моя программа в этом случае будет работать не правильно, а компилятор все видит и молчит? Тут все ложится на программиста? Нет средств для контроля?
SM
Цитата(d7d1cd @ Jan 4 2014, 22:04) *
однако при написании кода я ошибся и обратился к этому слову как к байту.


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

Цитата(d7d1cd @ Jan 4 2014, 22:04) *
Нет средств для контроля?

Есть конечно. Сделать эту часть кода на языке высокого уровня, в котором контроль типов более конкретный.


PS
Смысл в указании DS8/16/32 - чтобы линкер расположил переменную по адресу с корректным выравниваением, чтобы, например, слово, не попало на нечетный адрес. И больше ни для чего
vazz
А у меня еще один интересный вопрос: можно ли как-то программно прочитать серийный номер МК? Не DeviceID (типа 0x5137 для CC430F5137), а натуральный физический серийник
SM
А вот это ищите в даташите. В некоторых MSP430 есть TLV (Device Descriptor) Structures - там поля lot/wafer ID, wafer X position, wafer Y position, test results - вот их можно с натягом считать неким unique ID.
d7d1cd
Спасибо за помощь. Но все таки есть метод, позволяющий в какой-то мере отслеживать ошибки, связанные с неправильным обращением к создаваемым переменным. И это касается не только размера этой переменной. Это еще чтение и запись. Для этого надо использовать директивы SFRB, SFRW и SFRTYPE. Есть еще SFRL, но почему то эта директива не работает. Наверное она работает с 32-х разрядными микроконтроллерами... Кому надо (новичкам в программировании на ассемблере) привожу пример:
Код
SFRB    AAA = 0x0201                  ; Переменная ААА размером 1 байт по адресу 0х0201
SFRW    BBB = 0x0202                  ; Переменная ВВВ размером 2 байта по адресу 0х0202
SFRTYPE CCC WORD, READ, WRITE = 0x0208; Переменная ССС размером 2 байта (WORD), с возможностью
                                      ; чтения (READ) и записи (WRITE) по адресу 0х0208

main2:  
        MOV     #10, AAA              ; Компилятор ругается (что и требовалось): Accessing SFR using incorrect size
        MOV.B   #10, AAA              ; Теперь все хорошо :)
        
        MOV.B   AAA, BBB              ; Здесь недостаток использования SFR, ведь байт можно переслать в слово, однако ругань
        MOV     #BBB, CCC             ; Перемещение в ССС адреса BBB (0x0202)
        MOV     BBB(R12), CCC         ; Использование ВВВ как массива (R12 - индекс массива)
        MOV     #12, &BBB+2           ; Занесение числа 12 во 2 элемент массива. Здесь компилотор предупреждает: Suspicious sfr expression
                                      ; Нужно обратить внимание, что здесь обязательно
                                      ; использование абсолютного режима адресации. Использование относительного режима
                                      ; адресации приводит к неправильному выполнению кода:
        MOV     #12, BBB+2            ; Помещаем число 12 во 2 элемент массива, однако число 12 попадает по адресу 0х1304, то
                                      ; есть на 0х1100 дальше. Почему так, не знаю...

Был тут еще вопрос по размеру кода при программировании на ассемблере в версии IAR с ограничением на размер программы. Я использовал готовую прошивку (размером больше 4-х кбайт) и попробовал запустить ее на отладку. Увы, IAR мне сказал, что есть ограничение на размер и идите лесом...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.