реклама на сайте
подробности

 
 
> помогите разобраться, прерывания на C для msp430
Dustinthewind
сообщение Apr 11 2007, 19:50
Сообщение #1





Группа: Новичок
Сообщений: 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

}

Заанее благодарен
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
Сергей Борщ
сообщение Apr 11 2007, 20:01
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
Dustinthewind
сообщение Apr 12 2007, 10:11
Сообщение #3





Группа: Новичок
Сообщений: 11
Регистрация: 25-02-05
Пользователь №: 2 883



Спасибо за совет.
Увы, не помогло.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 12 2007, 10:28
Сообщение #4


Гуру
******

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



Цитата(Dustinthewind @ Apr 12 2007, 09:11) *
Спасибо за совет.
Увы, не помогло.
Поехали дальше. Вылетает после первого же прерывания? У вас есть внутрисхемный отладчик? Вы можете пройти по шагам до вылета несколько раз и засечь какая команда вызывает "вылет"? Другие прерывания не разрешены? Покажите текст initmain();


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Dustinthewind
сообщение Apr 12 2007, 10:48
Сообщение #5





Группа: Новичок
Сообщений: 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

}

комменты не пропислись, но думаю и так понятно
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 12 2007, 12:57
Сообщение #6


Гуру
******

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



Цитата(Dustinthewind @ Apr 12 2007, 09:48) *
Схема работы такая- входим в цикл, возникает прерывание и больше мы в цикл не попадаем...только повторяются прерывания...
А попробуйте поставить точку останова внутри цикла и сделать run. Я думаю дело в том, что пока вы по шагам проходите прерывание успевает возникнуть следующее и вы снова попадаете в его обработку.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Dustinthewind
сообщение Apr 12 2007, 14:45
Сообщение #7





Группа: Новичок
Сообщений: 11
Регистрация: 25-02-05
Пользователь №: 2 883



Естественно я пробовал уже с точками остановки. Некоторые навыки программирования все же есть -на ассемблере на msp430 носимый регистратор ЭКГ разрабатывал. Попробую медленно и с самого начала-)
Будем разбираться-)
Спасибо Вам за помощь.
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Apr 12 2007, 16:10
Сообщение #8


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



Цитата(Dustinthewind @ Apr 12 2007, 15:45) *
на ассемблере на msp430 носимый регистратор ЭКГ разрабатывал.

Опа!! А я сейчас разрабатываю ))
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 12 2007, 17:15
Сообщение #9


Гуру
******

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



Цитата(Dustinthewind @ Apr 12 2007, 13:45) *
Естественно я пробовал уже с точками остановки.
Тогда еще раз обратите внимание на мое замечание про чтение ADC12_IV. Похоже, попадая в прерывание вы не сбрасываете источник прерывания, поэтому после выхода попадаете в него снова. Я постараюсь завтра или в выходные внимательно просмотреть ваш код (давно не работал с 430, многое приходится вспоминать), если вдруг найдете ошибку раньше - отпишите.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Dustinthewind
сообщение Apr 12 2007, 19:36
Сообщение #10





Группа: Новичок
Сообщений: 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;} }
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 12 2007, 20:06
Сообщение #11


Гуру
******

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



Цитата(Dustinthewind @ Apr 12 2007, 18:36) *
Хотя по логике вроде бы должны совпадать.
Если бы было наоборот, то я бы предложил запрещать прерывания на время инверсии в основном цикле, хотя XOR у MSP430 операция атомарная - не помогло бы... А так затрудняюсь.... Flag_ADC объявлен как volatile?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Dustinthewind
сообщение Apr 13 2007, 11:08
Сообщение #12





Группа: Новичок
Сообщений: 11
Регистрация: 25-02-05
Пользователь №: 2 883



Да, volatile. Пробовал запрещать. Ну да ладно- маленькая практика стоит большой теории-)...поковыряюсь- пойму...
Спасибо Вам за помощь еще раз. Если вдруг будут нужны консультации по биомедицинской электронике- постараюсь помочь.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.01514 секунд с 7
ELECTRONIX ©2004-2016