|
|
  |
Таймер, На ассемблере |
|
|
|
Nov 7 2011, 17:06
|
Группа: Новичок
Сообщений: 8
Регистрация: 7-11-11
Пользователь №: 68 178

|
Всем доброго времени суток! Прошу помощи у знающих людей- начал разбираться с программированием МК. Пытаюсь разобраться с решением следующей задачки: у меня есть отладочная плата на основе MSP430F169, к ней припаяно 3 светодиода - на портах P1.0, P1.1, P3.4. Мне необходимо сделать таймер , который через определенное время включает первый диод, через еще какое-то время моргает вторым и через третий интервал времени включается третий. Важное замечание- задача должна быть реализована на ассемблере.. Читал документацию по МК и смотрел примеры от производителя. Если необходимо - могу выложить куски кода, полученные в результате моих попыток ( желаемого результата я так и не достиг)...Знающие любди, помогите пожалуйста?
|
|
|
|
|
Nov 8 2011, 04:38
|
Группа: Новичок
Сообщений: 8
Регистрация: 7-11-11
Пользователь №: 68 178

|
Соседнюю тему читал, по алгоритму вопросов нет- сам пытался написать нечто подобное. Вопрос именно в реализации на ассемблере. Не могу корректно обрабатывать события по истичении нужного времени. Поэтому прошу пример ипомощи=(
|
|
|
|
|
Nov 8 2011, 18:24
|
Группа: Новичок
Сообщений: 8
Регистрация: 7-11-11
Пользователь №: 68 178

|
>>Если необходимо - могу выложить куски кода, полученные в результате моих попыток - я сразу написал ведь) CODE #include "msp430.h" ;------------------------------------------------------------------------------ ORG 01100h ; Program Start ;------------------------------------------------------------------------------ RESET mov.w #0A00h,SP ; Initialize stackpointer StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT SetupP1 bis.b #001h,&P1DIR ; P1.0 output SetupC0 mov.w #CCIE,&CCTL0 ; CCR0 interrupt enabled L1 mov.w #60000,&TACCR0 ; Wait mov.w #00010,R15 ; Delay to R15 L2 dec.w R15 ; Decrement R15 SetupTA mov.w #TASSEL_2+MC_1,&TACTL ; SMCLK, upmode mov.w #60000,&TACCR0 ; jnz L2 ; xor.b #001h,&P1OUT ; Toggle P1.0 jmp L1 ; ;----------------------------------------------------------------------------- ; Interrupt Vectors ;----------------------------------------------------------------------------- ORG 0FFFEh ; MSP430 RESET Vector DW RESET ; ORG 0FFECh ; Timer_A0 Vector END
Целью этой программы являлось мигание лампочкой на порту 1.0 после определенной (пока не тактированной) задержки. ПС: я ассемблер тока осваиваю и поэтому могут быть серьезные ляпы.
|
|
|
|
|
Nov 9 2011, 05:47
|
Группа: Новичок
Сообщений: 8
Регистрация: 7-11-11
Пользователь №: 68 178

|
эта программа написана на основе примера с сайта, ссылку на который вы мне дали. и документирование по модулям я тоже читал. Так и не нашел четкой формулировки " для запуска таймера нужно вот это, по прохождению интервального времени нужно вот это". Лан спасибо. пойду читать дальше.(
|
|
|
|
|
Nov 9 2011, 20:21
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Itachi @ Nov 9 2011, 10:47)  эта программа написана на основе примера с сайта, ссылку на который вы мне дали. Когда вы модифицируете чужой исходник, выкидывая из него строки, то желательно при этом понимать, что именно произойдет в результате ваших действий. Вот исходник который вы покоцали. Найдите шесть отличий. CODE ;********************************************************************** #include <msp430x14x.h> ;------------------------------------------------------------------------------ ORG 01100h ; Program Start ;------------------------------------------------------------------------------ RESET mov.w #0A00h,SP ; Initialize stackpointer StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT SetupP1 bis.b #001h,&P1DIR ; P1.0 output SetupC0 mov.w #CCIE,&CCTL0 ; CCR0 interrupt enabled mov.w #20000,&CCR0 ; SetupTA mov.w #TASSEL_2+MC_1,&TACTL ; SMCLK, upmode ; Mainloop bis.w #CPUOFF+GIE,SR ; CPU off, interrupts enabled <=== здесь разрешаются прерывания nop ; Required for debugger ; ;------------------------------------------------------------------------------ TA0_ISR; Toggle P1.0 <=== это метка функции обработчика прерывания TIMERA0_VECTOR ;------------------------------------------------------------------------------ xor.b #001h,&P1OUT ; Toggle P1.0 <== это reti ; <== и это функция обработки прерывания ; ;----------------------------------------------------------------------------- ; Interrupt Vectors ;----------------------------------------------------------------------------- ORG 0FFFEh ; MSP430 RESET Vector DW RESET ; ORG 0FFECh ; Timer_A0 Vector DW TA0_ISR ; <== здесь указывается адрес функции обработки прерывания, который вы выкинули END
Кроме того, в вашем примере в цикл mainloop попали команды инициализации таймера. Хотя инициализировать его достаточно всего один раз. Еще раз предлагаю вам взять карандаш и нарисовать блок-схему вашего алгоритма на бумаге. Поверьте на слово ЭТОТ способ гораздо эффективнее, чем перемешивание некой "каши" в голове.
|
|
|
|
|
Nov 10 2011, 03:23
|
Группа: Новичок
Сообщений: 8
Регистрация: 7-11-11
Пользователь №: 68 178

|
Спасибо за комментарии. С блок-схемой проблем нет. С реализацией чего-либо подобного на любом другом языке тоже.
Проблема у меня в том что я не понимаю как работает алгоритм на ассемблере. Когда я взял за основу этот алгоритм - я сначала просто попробовал изменить значение в регистре CCR0 и поменял xor на активацию лампочки (перенес ее из начала программы). По моим представлениям лампочка должна была загореться через определенный интервал времни.
ну и в дальнейшем я начал комментировать и выкидывать различные куски, замечая что независимо от них происходит одно и то же
|
|
|
|
|
Nov 10 2011, 07:24
|
Группа: Новичок
Сообщений: 8
Регистрация: 7-11-11
Пользователь №: 68 178

|
rezident уже советовал это. Сегодня попробую. Спасибо.
|
|
|
|
|
Nov 10 2011, 10:49
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Itachi @ Nov 10 2011, 08:23)  Проблема у меня в том что я не понимаю как работает алгоритм на ассемблере. Извините за занудство, но у вас проблемы и с терминологией тоже.  Ассемблер это язык программирования (один из языков). А алгоритм это описание последовательности действий, которая может быть изложена на каком-нибудь языке программирования. У вас недопонимание инструкций ассемблера? Или принципов работы периферийных модулей MSP430? В первом случае тем более имеет смысл рисовать алгоритм на бумаге, положив под руку справочник по ассемблеру. Во-втором, нужно внимательно читать User's Guide. Если не очень владеете английским, то есть переводы руководства на русском языке. Книги издательства Додека. Раньше они были в электронном виде в библиотеке Компэла, но теперь там остался только последний перевод руководства по серии MSP430x2xx. Конкретно по таймеру можете глянуть там, т.к. данный модуль устроен одинаково во всех сериях MSP430. Ну или на gaw.ru первоначальный перевод руководства гляньте. Отдельно хочу предупредить, что в переводах имеются ошибки! Так что использовать переводные руководства как справочники крайне не рекомендуется. Конкретно в "Книге «Семейство микроконтроллеров MSP430x2xx»" есть ошибка как раз в описании регистров модуля Таймер А. В главе 12. Таймер A есть раздел 12.3. Регистры Таймер А. Так вот описание значений бита CAP дано с точностью наоборот. В переводе Цитата CAP Бит 8 Режим работы блока захвата/сравнения. 0 Режим захвата 1 Режим сравнения а в оригинальном руководстве Цитата CAP Bit 8 Capture mode 0 Compare mode 1 Capture mode Аналогичная ошибка перевода есть в описании Таймер B.
|
|
|
|
|
Nov 10 2011, 12:48
|
Группа: Новичок
Сообщений: 8
Регистрация: 7-11-11
Пользователь №: 68 178

|
я написал именно то что хотел) я не понимаю как реализовать алгоритм .нарисованный на листочке/ на ассемблере. у меня прямо под рукой книга додэка. Мне не хватает информации о том что конкретно инициализирует таймер и как конкретно обрабатывать события. общие фразы типа таймер включается если значение регистра ccr0 не нулевое- не информативны. Меня интересует когда конкретно таймер начинает считать. И когда конкретно заканчивает (доходит до нужного значения) и как это окончание работы таймера обработать.
конкретные вопросы.
|
|
|
|
|
Nov 10 2011, 15:24
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Конкретные ответы. Цитата(Itachi @ Nov 10 2011, 17:48)  Меня интересует когда конкретно таймер начинает считать. Таймер А считает всегда при выполнении условий: - источник тактирования таймера, выбранный битами TASSELx в регистре TACTL, активный; - с помощью битов MCx в регистре TACTL выбран любой из режимов счета, отличный от MC_0. Цитата(Itachi @ Nov 10 2011, 17:48)  И когда конкретно заканчивает Никогда, пока выполняются оба перечисленных условия. Цитата(Itachi @ Nov 10 2011, 17:48)  (доходит до нужного значения) Это очевидно - один раз за (полу) период счета. (полу)Период счета в режимах MC_1 и MC_3 задается значением регистра CCR0. В режиме MC_1 с помощью CCR0 задается период, в режиме MC_3 - полупериод. В режиме MC_2 таймер считает до своего естественного переполнения (до 0xFFFF). Цитата(Itachi @ Nov 10 2011, 17:48)  и как это окончание работы таймера обработать. Вопрос формулирован некорректно, поэтому однозначного ответа дать не могу. Таймер считает всегда при выполнении двух условий. При счете инкрементируется (или инкрементируется/декрементируется в зависимости от выбранного режима) содержимое регистра TAR. При переходе состояния TAR к значению 0x0000 (при переполнении или при декрементном счете) устанавливается флаг TAIFG и может вызываться прерывание, если оно разрешено битом TAIE. В режиме сравнения (compare mode) при совпадении содержимого каждого из регистров CCRx со значением TAR происходят события, которые можно обрабатывать по-разному, в зависимости от того, как именно вам требуется. Событие совпадения CCRx и TAR вызывает установку флага CCIFG в регистре TACCTLx и вызов прерывания, если оно разрешено битом CCIE. Также это событие может вызывать изменение состояния выхода TAx, если выбран режим OUTMODx, отличающийся от OUTMOD_0. В режиме захвата (capture mode) при изменении сигнала на входе CCIx происходит "захват" значения TAR, которое записывается в соответствующий регистр CCRx. Вообще если проводить аналогию с аналоговой схемотехникой, то таймер это генератор сигнала пилообразной или треугольной формы. В режиме совпадения в таймере работают "компараторы", к одному из входов которого подключена эта "пила", а на втором устанавливается порог срабатывания в соответствии со значением регистра CCRx. В режиме захвата в регистрах CCRx фиксируется уровень "пилы" в момент стробирования по входу CCIx. Все это подробно описано в руководстве (User's Guide) и почему у вас не получается воспринять эту информацию мне не очень понятно
|
|
|
|
|
Nov 10 2011, 19:12
|
Группа: Новичок
Сообщений: 8
Регистрация: 7-11-11
Пользователь №: 68 178

|
спасибо за ответ. все это я уже читал. И пробовал. Потому и не получается воспринять, что то, что по моим представлениям должно работать, работает некорректно (опять же по моим представлениям, естественно).
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|