|
помогите разобраться, прерывания на C для msp430 |
|
|
|
Apr 11 2007, 19:50
|
Группа: Новичок
Сообщений: 11
Регистрация: 25-02-05
Пользователь №: 2 883

|
Перехожу с асма на С...Не могу понять почему из цикла вылетает после прерывания
Текст основной проги
void main( void ) {
initmain();
while (1)
{ if (Flag_ADC==1) {Chan_ADC1 = Chan_ADC1+ADC_Sample1;Flag_ADC=0 }; } }
Прерывание
#pragma vector=ADC_VECTOR __interrupt void ADC12ISR (void)
{ _BIC_SR(GIE);//general interrupt disable
ADC_Sample1=ADC12MEM0; Flag_ADC=1; _BIS_SR(GIE);//general interrupt able P1OUT ^= 0x02; // Toggle P1.0 using exclusive-OR
}
Заанее благодарен
|
|
|
|
|
 |
Ответов
(1 - 11)
|
Apr 11 2007, 20:01
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Dustinthewind @ Apr 11 2007, 18:50)  Не могу понять почему из цикла вылетает после прерывания Как минимум убрать строки Код _BIC_SR(GIE);//general interrupt disable _BIS_SR(GIE);//general interrupt able Ибо при входе в прерывание прерывания запрещаются автоматически а при выходе также автоматически разрешаются. Во-вторых (если мне не изменяет память), в прерывании надо читать ADC12IV. Иначе вы получали повторную генерацию прерывания и попадали в него сразу после _BIS_SR(GIE);, т.е. до выхода из обработчика и в конце концов переполняли стек. И еще маленький совет: вместо _BIS_SR(GIE), _BIC_SR(GIE) можно использовать функции __enable_interrupt() и __disable_interrupt(), которые делают то же самое но не нуждаются в комментариях.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 12 2007, 10:11
|
Группа: Новичок
Сообщений: 11
Регистрация: 25-02-05
Пользователь №: 2 883

|
Спасибо за совет. Увы, не помогло.
|
|
|
|
|
Apr 12 2007, 10:48
|
Группа: Новичок
Сообщений: 11
Регистрация: 25-02-05
Пользователь №: 2 883

|
Да, вылетат после первого прерывания из цикла while. Отлаживаю на собранном макете. По шагам пробовал. Схема работы такая- входим в цикл, возникает прерывание и больше мы в цикл не попадаем...только повторяются прерывания...
Текст инициализации
#include <glob_var.h>
void initmain(void) { unsigned int i; WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 |= XT2OFF; // XT2 = HF XTAL //èíèöèàëèçàöèÿ ãåíåðàòîðà do { IFG1 &= ~OFIFG; // Clear OSCFault flag for (i = 0xFF; i > 0; i--); // Time for flag to set } while ((IFG1 & OFIFG) == OFIFG); // OSCFault flag still set? BCSCTL2 |= SELM1+SELS; // MCLK = LFXT2 (safe)
//èíèöèàëèçàöèÿ UART P3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXD ME1 |= UTXE0 + URXE0; // Enable USART0 TXD/RXD UCTL0 |= CHAR; // 8-bit character UTCTL0 |= SSEL1; // UCLK = SMCLK UBR00 = 0x05; // 5MHz 1MHz UBR10 = 0x00; // 5MHz 1MHz UMCTL0 = 0x00; // 5MHz 1MHz modulation UCTL0 &= ~SWRST; // Initialize USART state machine IE1 |= URXIE0; // Enable USART0 RX interrupt
//èíèöèàëèçàöèÿ ÀÖÏ
P6SEL = 0x0F; // Enable A/D channel inputs ADC12CTL0 = ADC12ON+MSH+SHT0_0+REFON+REF2_5V;//multiple, sample x 16; Vref=2>5V ADC12CTL1 = CONSEQ_1+ADC12SSEL_0+SHP+SHS_1+CSTARTADD_0;//non-repeat sequence, SMCLK, sampling timer, Timer_A, ADC12MEM0 start ADC12MCTL0 = INCH_0; // ref+=AVcc, channel = A0 ADC12MCTL1 = INCH_1+EOS; // ref+=AVcc, channel = A1 ADC12IE = 0x02; // Enable ADC12IFG.1 static unsigned int time_start; for (time_start=0; time_start<=30000; time_start++); ADC12CTL0 |= ENC; // Enable conversions ADC12CTL0 |= ADC12SC; // Start conversion
//èíèöèàëèçàöèÿ òàéìåðà À
TACTL = TASSEL_2; //SMCLK source CCR0 = ADC_period; CCTL1 = OUTMOD_2; //compare, PWM toggle/reset CCR1 = ADC_period-1; TACTL |= MC0; //start Up to CCR0
P1DIR |= 0x01; // Set P1.0 to output direction; for debugger P1DIR |= 0x02; // Set P1.1 to output direction; for debugger
_BIS_SR(GIE);//general interrupt
}
комменты не пропислись, но думаю и так понятно
|
|
|
|
|
Apr 12 2007, 14:45
|
Группа: Новичок
Сообщений: 11
Регистрация: 25-02-05
Пользователь №: 2 883

|
Естественно я пробовал уже с точками остановки. Некоторые навыки программирования все же есть -на ассемблере на msp430 носимый регистратор ЭКГ разрабатывал. Попробую медленно и с самого начала-) Будем разбираться-) Спасибо Вам за помощь.
|
|
|
|
|
Apr 12 2007, 19:36
|
Группа: Новичок
Сообщений: 11
Регистрация: 25-02-05
Пользователь №: 2 883

|
С ADC12IV Вы оказались правы. При инициализации АЦП настраивался на опрос двух каналов и не происходило обнуление флагов прерывания при чтении. Добавил чтение ворого канала. Теперь заработало близко к необходимому. Но осталась небольшая проблемка- если смотреть на осциллографе, то частота инверсии порта P1.0 в прерывании не совпадает с частотой инверсии порта p1.1 в цикле (в цикле меньше примерно на треть). Хотя по логике вроде бы должны совпадать. Вот исправленный текст прерывания и цикла.
#pragma vector=ADC_VECTOR __interrupt void ADC12ISR (void)
{
Flag_ADC=1; ADC_Sample1=ADC12MEM0; ADC_Sample2=ADC12MEM1; P1OUT ^= 0x02; // Toggle P1.0 using exclusive-OR ADC12CTL0 |= ENC; // Enable conversions
}
Цикл
while (1)
{ if (Flag_ADC==1) {Chan_ADC1 = Chan_ADC1+ADC_Sample1;Flag_ADC=0;P1OUT ^= 0x01;} }
|
|
|
|
|
Apr 13 2007, 11:08
|
Группа: Новичок
Сообщений: 11
Регистрация: 25-02-05
Пользователь №: 2 883

|
Да, volatile. Пробовал запрещать. Ну да ладно- маленькая практика стоит большой теории-)...поковыряюсь- пойму... Спасибо Вам за помощь еще раз. Если вдруг будут нужны консультации по биомедицинской электронике- постараюсь помочь.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|