|
Помоните новичку! |
|
|
|
May 21 2009, 13:33
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Только осваиваю MSP, задавал вопросы тут рядом, в теме о длительности цикла. С тем вроде понятно. но помогите плиз, посмотрите - где у меня тут ошибка? Пытаюсь помигать светодиодом по прерыванию от Таймера A: CODE #include "defs.h" #include "ports.h" //#include "display.h" //----------------------------------------------- #pragma vector=TIMERA0_VECTOR __interrupt void timera0_interrurpt(){ LED_BAT1_TOGGLE; #ifndef DEBUG WDTCTL = WDTPW + WDTCNTCL; #endif } //----------------------------------------------- #pragma vector=TIMERB0_VECTOR __interrupt void timerb0_interrupt(){ //LED_BAT1_TOGGLE; //LEDS_ON; _NOP(); LEDS_OFF; #ifndef DEBUG WDTCTL = WDTPW + WDTCNTCL; #endif } //------------------------------------------------ void SwitchToHighClock(void){ // XT1=ON, XT2=ON, MLCK=XT2, SMCLK=XT2, ACLK=XT1 int i; BCSCTL1 = 0; // Turn on XTL2 do{ IFG1 &= ~OFIFG; //clear OFIFG for (i=0x0F; i>0; i--) _NOP(); } while( (IFG1 & OFIFG)!=0); BCSCTL2 = SELM1+SELS; // MCLK = XTL2, /1, SMCLK=XT2, /1, IntRes DCO __bic_SR_register(SCG1); // Turn on SMCLK } void SwitchToLowClock(void){ // XT1=ON, XT2=OFF, MLCK=XT1, SMCLK=OFF, ACLK=XT1 int i; BCSCTL1 = 0x80; // Turn off XTL2 do{ IFG1 &= ~OFIFG; //clear OFIFG for (i=0x0F; i>0; i--) _NOP(); } while( (IFG1 & OFIFG)!=0); BCSCTL2 = SELM1+SELM0 + SELS; // MCLK = XTL1, /1, SMCLK=XT2, /1, IntRes DCO __bis_SR_register(SCG1); // Turn off SMCLK } void SetClock(){ __bic_SR_register(OSCOFF); // turn ON clock generator SwitchToLowClock(); } //-- void InitTimers(){ // Timer A TACTL = TASSEL_2+MC_1+ID_3; // XT2 Select (8Mhz), Up to CCR0, divide by 8 to get 1Mhz TACCR0 = 62500-1; // Interrunt every 1/16 Sec TACCTL0 = CCIE; TAR = 0; TACTL |=TAIE; // Timer B TBCTL = TBSSEL_1 + MC_1; // ACLK Clock input TBCCTL0 = CCIE; TBCCR0 = 3333; // ~ 0.1 Sec @ 32.768kHz XT1 TBR=0; //TBCTL |= TBIE; } //================================================================================ ======== void main( void ){ //int i; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer // Clock init SetClock(); SwitchToHighClock(); //initPorts(); P2DIR = 0xFF; P3DIR = 0x0B; P4DIR = 0x03; P5DIR = 0x7F; DDIR = 0xFF; InitTimers(); __enable_interrupt(); while(1){ WDTCTL = WDTPW + WDTCNTCL; } } } Таймер B я там подготовил к такой-же процедуре, но пока его прерывание не включено. В чем проблема - оно мигает, но на обоих фронтах есть глитч. Т.е. переходит из 0 в 1 потом примерно через 2.3мс переходит из 1 на половину уровня, еще через 3.7мс возвращяется к 1. Если не образать внимание на глитч, то период примерно правильный. Но (!) - почему-то на совсем другом порту, который я не трогаю, возникают импульсы с периодом как у моего светодиода, и длительностью - как у глитча. Какого?! Подскажите - что я не заметил или не знаю ?
Причина редактирования: Уменьшение видимого размера цитаты исходника.
|
|
|
|
|
May 21 2009, 16:06
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Allregia @ May 21 2009, 19:33)  Подскажите - что я не заметил или не знаю ? Подсказываю. Вы неправильно работаете с таймером. Во-первых, нужно сначала инициализировать его и только потом запускать. И во время работы обнулять TAR нельзя. Для этого бит TACLR в TACTL имеется. Т.е. ваша инициализация должна выглядеть так. Код // Timer A TACTL = TASSEL_2|ID_3|TACLR; // XT2 Select (8Mhz), Up to CCR0, divide by 8 to get 1Mhz TACCR0 = 62500-1; // Interrunt every 1/16 Sec TACCTL0 = CCIE; TACTL |= MC_1; Во-вторых, вы разрешаете два прерывания от TimerA, но обработчик прерывания только один вектор обрабатывает (от TACCR0). Команда Код TACTL |=TAIE; ненужная потому, что бит TAIE разрешает прерывание от переполнения таймера, а вы его не используете и функцию обработчика по вектору от переполнения прерывания (TIMERA1_VECTOR) не разместили . Вот поэтому-то (отсутствие обработчика прерывания) видимо и происходит ваш глитч. Кстати, WDT в вашем случае сбрасывать не обязательно, т.к. вы его запретили первой командой в main Код WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
|
|
|
|
|
May 21 2009, 18:38
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(rezident @ May 21 2009, 19:06)  Во-вторых, вы разрешаете два прерывания от TimerA, но обработчик прерывания только один вектор обрабатывает (от TACCR0). Команда Код TACTL |=TAIE; ненужная потому, что бит TAIE разрешает прерывание от переполнения таймера, а вы его не используете и функцию обработчика по вектору от переполнения прерывания (TIMERA1_VECTOR) не разместили . Вот поэтому-то (отсутствие обработчика прерывания) видимо и происходит ваш глитч. Вот блин, и на старуху бывает проруха... Я что-то подобное и предполагал, что вызывается переход на несуществующий обработчик, только не мог понять откуда оно берется. В эмуляторе видел что программа рестартует. Огромное спасибо, это моя невнимательность и доверчивость - кусок инициализации таймеров я скопировал с чужой программы. Только непонятно - как она работает? А ведь работает. Кстати в той же программе они клок переключают тоже без ожидания (о чем мы в теме рядом говорили). "Как же он работал в очистке?"(с)Собачье Сердце. Цитата Кстати, WDT в вашем случае сбрасывать не обязательно, т.к. вы его запретили первой командой в main Код WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer Это просто на будущее, когда вотчдог будет работать. Еще раз спасибо, пойду теперь с АЦП разбираться, там тоже наворочено всего...
Причина редактирования: Излишнее цитирование.
|
|
|
|
|
May 21 2009, 21:44
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(rezident @ May 22 2009, 00:29)  Для себя принял такое правило, если не идет борьба за каждый байт (случалось и такое), то я инициализирую все вектора прерываний, имеющиеся в кристалле. Хотя бы один NOP в обработчик вставляю. При отладке будет проще отловить такой конфуз как вызов неиспользуемого прерывания. № меня к счастью 1611, у него памяти более чем достаточно для этого устройства. Правда, играюсь я пока со 148-м (есть готовая платка от другогоприбора я ее как макет использую). Про инициализицию всего - мысль хорошая. А можно набраться наглости, и попросить полный список? А то я начну составлять- обязательно что-то пропущу по неопытности с этим проциком.
|
|
|
|
|
May 21 2009, 22:42
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Allregia @ May 22 2009, 03:44)  А можно набраться наглости, и попросить полный список? А то я начну составлять- обязательно что-то пропущу по неопытности с этим проциком. Дык в хедерах от TI (в IAR они тоже включены) весь список векторов имеется  Вот фрагмет из msp430x14x.h Код /************************************************************ * Interrupt Vectors (offset from 0xFFE0) ************************************************************/
#define PORT2_VECTOR (1 * 2u) /* 0xFFE2 Port 2 */ #define USART1TX_VECTOR (2 * 2u) /* 0xFFE4 USART 1 Transmit */ #define USART1RX_VECTOR (3 * 2u) /* 0xFFE6 USART 1 Receive */ #define PORT1_VECTOR (4 * 2u) /* 0xFFE8 Port 1 */ #define TIMERA1_VECTOR (5 * 2u) /* 0xFFEA Timer A CC1-2, TA */ #define TIMERA0_VECTOR (6 * 2u) /* 0xFFEC Timer A CC0 */ #define ADC12_VECTOR (7 * 2u) /* 0xFFEE ADC */ #define USART0TX_VECTOR (8 * 2u) /* 0xFFF0 USART 0 Transmit */ #define USART0RX_VECTOR (9 * 2u) /* 0xFFF2 USART 0 Receive */ #define WDT_VECTOR (10 * 2u) /* 0xFFF4 Watchdog Timer */ #define COMPARATORA_VECTOR (11 * 2u) /* 0xFFF6 Comparator A */ #define TIMERB1_VECTOR (12 * 2u) /* 0xFFF8 Timer B CC1-6, TB */ #define TIMERB0_VECTOR (13 * 2u) /* 0xFFFA Timer B CC0 */ #define NMI_VECTOR (14 * 2u) /* 0xFFFC Non-maskable */ #define RESET_VECTOR (15 * 2u) /* 0xFFFE Reset [Highest Priority] */
#define UART1TX_VECTOR USART1TX_VECTOR #define UART1RX_VECTOR USART1RX_VECTOR #define UART0TX_VECTOR USART0TX_VECTOR #define UART0RX_VECTOR USART0RX_VECTOR #define ADC_VECTOR ADC12_VECTOR Кстати, в IAR EW есть два вида заголовочных файлов: msp430x....h это от производителя (TI), а io430x....h это от IAR. Я предпочитаю хедеры от TI использовать.
|
|
|
|
|
May 22 2009, 04:57
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(rezident @ May 21 2009, 20:06)  Кстати, WDT в вашем случае сбрасывать не обязательно, т.к. вы его запретили первой командой в main Код WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer А после команды WDTCTL = WDTPW + WDTCNTCL; он начинает щёлкать, причем при тактировании от 8МГц - очень быстро. Может, он и сбрасывает
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
May 22 2009, 08:06
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(rezident @ May 22 2009, 00:29)  Для себя принял такое правило, если не идет борьба за каждый байт (случалось и такое), то я инициализирую все вектора прерываний, имеющиеся в кристалле. Хотя бы один NOP в обработчик вставляю. Ну или так. Под отладчиком сразу видно, что произошло что-то. Код #pragma vector=COMPARATORA_VECTOR __interrupt void StayHere6() { for (;;); }
--------------------
Уходя, оставьте свет...
|
|
|
|
|
May 22 2009, 17:12
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата А в той программе случайно не было обработчика прерывания OFIFG? Неа. А с таймерами я разобрался, большое всем спасибо.
|
|
|
|
|
May 23 2009, 07:54
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Allregia @ May 23 2009, 13:23)  Еще небольшой вопрос: Мне надо некоторые параметры, буквально десяток байт,периодически (раз в 5 минут) запоминать в энергонезависимой памяти (небольшой лог). Но как я понял, в МСП430 нет ЕЕПРОМ а есть только флеш (256 байт в 1611), в которую нельзя писать произвольные данные. Т.е. каждый раз надо все стирать. Как вы решаете подобные вопросы? Да, чтобы обновить хотя бы бит, надо стирать весь сегмент. На то она и флешь. Там для этого специально выделено два сегмента (в новых моделях их, вроде уже больше) для этих целей - в одном лежит текущая копия данных, при необходимости обновить - данные с обновлениями пишутся в другой сегмент, а текущий стирается. В следующий раз - то же самое, только сегменты меняются местами. Не очень удобно, может показаться, но написав один раз код, он работает без проблем. С EEPROM'ом тоже не все так безоблачно - для надежного хранения надо там и контрольные суммы делать, а то и копии резервные держать и т.д. Возни тоже хватает. Следует только обратить внимание на два момента: - ресурс флеши - гарантируется, AFAIR, 10 000 циклов стирания;
- время стирания сегмента - оно может окзаться неприемлимо большим (десятки миллисекунд, точно не скажу, забыл, под рукой данных нет). Хотя запись слова производится довольно быстро - ставил эксперимент еще на F149 - там выходило что-то порядка 100-125 мк.
Цитата(Allregia @ May 23 2009, 13:23)  P.S. Или не морочить себе голову и прилепить снаружи 24хх или 96хх ? Это уже вам виднее.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 23 2009, 09:23
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Allregia @ May 23 2009, 10:23)  Но как я понял, в МСП430 нет ЕЕПРОМ а есть только флеш (256 байт в 1611), в которую нельзя писать произвольные данные. Т.е. каждый раз надо все стирать. Как вы решаете подобные вопросы? Если параметров немного, можно писать циклически, постепенно заполняя сегмент. При достижении конца сегмента - стирать. Хотя можно и не ограничиваться одним сегментом, наверняка пустых много.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
May 23 2009, 10:11
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(dxp @ May 23 2009, 10:54)  С EEPROM'ом тоже не все так безоблачно - для надежного хранения надо там и контрольные суммы делать В ЕЕПРОМ типа 24хх/96хх это уже все внутри. Именно за счет избыточности (Хеминга) там и достигаются огромные (по сравнению с флеш) значения endurance. Цитата , а то и копии резервные держать и т.д. Возни тоже хватает. Следует только обратить внимание на два момента: - ресурс флеши - гарантируется, AFAIR, 10 000 циклов стирания;
- время стирания сегмента - оно может окзаться неприемлимо большим (десятки миллисекунд, точно не скажу, забыл, под рукой данных нет). Хотя запись слова производится довольно быстро - ставил эксперимент еще на F149 - там выходило что-то порядка 100-125 мк.
Это уже вам виднее.  Видимо придется, у ЕЕПРОМ ресурс минимум на порядок больше, типично - на два порядка (1М), а иногда и на три (10М).
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|