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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> АЦП MSP430F149, Чего я неправильно делаю?
Atridies
сообщение Jun 30 2009, 08:24
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468



Доброго времени суток!

Хочу измерить температуру. Инициализирую АЦП (в момент первоначальной настройки периферии):

ADC12CTL0 = 0x0000+REFON+REF2_5V+MSC+SHT01;
ADC12CTL1 = 0x0000+ADC12SSEL1+ADC12DIV0+SHP+CONSEQ0;

ADC12MCTL0 = 0x10; // SREF=001
ADC12MCTL1 = 0x11; // SREF=001
ADC12MCTL2 = 0x12; // SREF=001
ADC12MCTL3 = 0x13; // SREF=001
ADC12MCTL4 = 0x9B; // SREF=001
ADC12MCTL5 = 0x1A;
ADC12MCTL6 = 0x14; ADC12MCTL7 = 0x95;
ADC12IE = 0x00B0;

Потом запускаю преобразование следующим кодом:

ADC12CTL1 = 0x5000+SHP+ADC12SSEL1+ADC12DIV0;
ADC12CTL0 = 0x0900+REFON+REF2_5V+ADC12ON+ENC;
ADC12CTL0 |= 0x0001;

Прерывание:

#pragma vector=ADC12_VECTOR
__interrupt void ADC(void)
{
if(ADC12IV == 0x000E)
{
// Обработка
}
}

Проблема в том, что у меня при входе в прерывание регистры ADC12IV и ADC12IFG - уже в нулях (хотя до этого они устанавливались).
Работаю пошагово с кристаллом через JTAG: он даже не дает установить вручную ADC12IFG - сразу сбрасывает.
Что я делаю не так? Заранее спасибо.
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Jun 30 2009, 08:36
Сообщение #2


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

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



в качестве совета. В IDE обычно всегда есть хедеры со всеми константами, не надо делать так:
ADC12CTL0 |= 0x0001;
ADC12MCTL0 = 0x10;
ADC12CTL1 = 0x5000+SHP+ADC12SSEL1+ADC12DIV0;
и пр.

Ваш код пока не смотрел, ибо докипод рукой нет, а на память не помню. Если резидент не опередит, что обычно бывает smile.gif smile.gif то скажу в чем проблема к вечеру.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 30 2009, 08:52
Сообщение #3


Беспросветный оптимист
******

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



А без разных лазаний по регистрам житагами работает?
В доке сказано, что IV сбрасывается при первом чтении, а IFG - при обращении к соответствующим регистрам MEM
Может, вы это самое и наблюдаете?


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Atridies
сообщение Jun 30 2009, 09:35
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468



Елы-палы. Взял запустил процессор вообще без JTAG - блин, работает...

Да, я иногда неиспользую названия битов, порой это даже информативнее.

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

Спасибо за помощь!
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Jun 30 2009, 11:04
Сообщение #5


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

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



АЦП работает и с джитагом
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 30 2009, 11:18
Сообщение #6


Беспросветный оптимист
******

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



Цитата(jorikdima @ Jun 30 2009, 15:04) *
АЦП работает и с джитагом

АЦП-то может и работает, а вот с прерываниями могут разные фокусы происходить


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 30 2009, 11:32
Сообщение #7


Гуру
******

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



Цитата(MrYuran @ Jun 30 2009, 14:18) *
АЦП-то может и работает, а вот с прерываниями могут разные фокусы происходить
Если открыто окно отладчика с регистрами АЦП - то да. Но точно такие же чудеса будут происходить и с таймерами (TAIV, TBIV), и с UART - вообще с любой периферией, значение регистров которой изменяется чтением.


--------------------
На любой вопрос даю любой ответ
"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
Atridies
сообщение Jul 1 2009, 17:32
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468



Цитата(Сергей Борщ @ Jun 30 2009, 15:32) *
Если открыто окно отладчика с регистрами АЦП - то да. Но точно такие же чудеса будут происходить и с таймерами (TAIV, TBIV), и с UART - вообще с любой периферией, значение регистров которой изменяется чтением.


Ух ты, вот оно что ! Теперь ясно...
Go to the top of the page
 
+Quote Post
Allregia
сообщение Aug 2 2009, 10:12
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Теперь я запутался.
Проц 169.
Задача:
а) оцифровать 3 канала по внешнему "пинку"
б) оцифровывать все время 3 канала по таймеру-В.

Инициализирую АЦП:
Код
      
             ADC12CTL0   = 0;
             ADC12CTL1   = SHP  + ADC12DIV_1 + ADC12SSEL_2 + CONSEQ_1;  // start=SC, s/h=timer, clk from MCLK 1/2 = 4Mhz = 0.2uS, sequence.
           ADC12MCTL0  = SREF_1 + INCH_0;
           ADC12MCTL1  = SREF_1 + INCH_1;
           ADC12MCTL2  = SREF_1 + INCH_2 + EOS;
           ADC12IE   = 0;
           ADC12IFG  = 0;
           ADC12CTL0 = SHT0_1 + REF2_5V + REFON + ADC12ON  + ENC  + MSC;


Тестовый кусок кода:

Код
        
         ADC12CTL0 |= ADC12SC; // start single conversion
         while(1){
             LED_ON;
                 while((ADC12IFG & 0x07)!=0x07);
         LED_OFF;
                 ADC12IFG &=0x07;             // clear IRQ flags
                 DAC12_0DAT= ADC12MEM0; // вывожу оцифрованное для контроля в ЦАПы, жаль третьего нет:
                 DAC12_1DAT= ADC12MEM1;
    
         }


Таймер инициализировал так:
Код
        
              TBCTL   = TBSSEL_2 | TBCLR;   // XT2 Clock input (8Mhz)
              TBCCR0  = 500;                      // 16kHz output
              TBCCTL0 = CCIE;
              TBCTL   |= MC_1;


В таймере даю "пинок":
Код
#pragma vector=TIMERB0_VECTOR
     __interrupt void TIMERB0_interrupt(){
       LED2_TOGGLE;
       ADC12CTL0 |= ADC12SC;
     #endif


Все работает, но если в ините ADC12CTL0 я убираю MSC, то работать перестает. Я не понял, MSC это ведь только время S/H, без него по идее, должно быть просто меньше время общего преобразования?

Теперь вариант Б:
добавляю SHS_2 в АЦП:
Код
ADC12CTL1   = SHP  + ADC12DIV_1 + ADC12SSEL_2 + CONSEQ_1 + SHS_2;

таймер инициализирую так:
Код
        
              TBCTL   = TBSSEL_2 | TBCLR;   // XT2 Clock input (8Mhz)
              TBCCR0  = 500;                      // 16kHz output
              TBCCTL0 = OUTMOD_1;
              TBCTL   |= MC_1;



Получаю естессно фигвам.
Вопрос - чего я забыл еще включить ?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 3 2009, 12:03
Сообщение #10


Гуру
******

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



Пробегаю по диагонали, потому как в отпуске:
1) ADC12IFG &=0x07; // clear IRQ flags
Сбрасывает все флаги, кроме трех младших. Если я правильно понял, вы хотели наоборот.
2)
Цитата(Allregia @ Aug 2 2009, 13:12) *
Я не понял, MSC это ведь только время S/H, без него по идее, должно быть просто меньше время общего преобразования?
Нет. Это значит, что один "пинок" будет запускать либо каждое преобразование, либо всю серию до ячейки с ENC(преобразование следующего канала начнется сразу после окончания преобразорвания предыдущего).

3) Для постоянной оцифровки трех каналов у вас должна быть инициализация с CONSEQ = 3 (Repeat-sequence-of-channels). В прерывании таймера надо CONSEQ поставить в 1 (Sequence-of-channels), переставить CSTARTADD на группу тех трех каналов, которые вам надо оцифровать по "пинку", для последнегно канала этой группы разрешить прерывание. В прерывании вернуть CONSEQ и CSTARTADD, а также дернуть ADC12SC.
В таком варианте (насколько я понимаю описание) после прерывания таймера АЦП закончит последовательность трех постоянных каналов и перейдет к оцифровке "пинаемых". Если же вам надо начать преобразование "пинаемых" немедленно, то в прерывании таймера надо несколько поколдовать с ENC и CONSEQ (см. раздел Stopping Conversions).


--------------------
На любой вопрос даю любой ответ
"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
Allregia
сообщение Aug 3 2009, 14:16
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Цитата(Сергей Борщ @ Aug 3 2009, 15:03) *
Пробегаю по диагонали, потому как в отпуске:
1) ADC12IFG &=0x07; // clear IRQ flags
Сбрасывает все флаги, кроме трех младших. Если я правильно понял, вы хотели наоборот.



Да, конечно, я забыл испрвить - у меня там на самом деле стоит ADC12IFG =0;

Цитата
2)
Нет. Это значит, что один "пинок" будет запускать либо каждое преобразование, либо всю серию до ячейки с ENC(преобразование следующего канала начнется сразу после окончания преобразорвания предыдущего).

3) Для постоянной оцифровки трех каналов у вас должна быть инициализация с CONSEQ = 3 (Repeat-sequence-of-channels). В прерывании таймера надо CONSEQ поставить в 1 (Sequence-of-channels), переставить CSTARTADD на группу тех трех каналов, которые вам надо оцифровать по "пинку", для последнегно канала этой группы разрешить прерывание. В прерывании вернуть CONSEQ и CSTARTADD, а также дернуть ADC12SC.
В таком варианте (насколько я понимаю описание) после прерывания таймера АЦП закончит последовательность трех постоянных каналов и перейдет к оцифровке "пинаемых". Если же вам надо начать преобразование "пинаемых" немедленно, то в прерывании таймера надо несколько поколдовать с ENC и CONSEQ (см. раздел Stopping Conversions).


Я наверное не очень обьяснил, "пинок" - это было чисто для проверки, а мне надо постоянно оцифровывать только 3 канала 0-1-2, но запуск осуществлять по таймеру В (чтобы не получиь джиттер).

Так что, CONSEQ = 3 (Repeat-sequence-of-channels) не нужно совершено - оно запусукает непрерывный процесс без участия таймера, поэтому я и ставлю CONSEQ_1 - однократныую оцифровку последовательности каналов. Вот если я эту оцифровку запускаю в прерывании таймера, сигналом ADC12SC - все работает.
Далее я могу использовать прерывание от последнего канала, или просто читать ADC12MEMx из программы.

Но(!), я думал что есть возможность запускать преобразование без прерывания таймера а аппаратно (не хочется терять время на обработчик таймерного прерывания), и вот это-то у меня пока и не получилось.
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 3 2009, 14:39
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Allregia @ Aug 3 2009, 20:16) *
Я наверное не очень обьяснил, "пинок" - это было чисто для проверки, а мне надо постоянно оцифровывать только 3 канала 0-1-2, но запуск осуществлять по таймеру В (чтобы не получиь джиттер).
Остальное цитировать не буду, т.к. все ваши непонятки от того, что вы невнимательно прочитали раздел, посвященный ADC12, в User's Manual. А конкретные непонятки у вас в функционировании узле выборки-хранения, который обведен на блок-схеме.
Поясните точнее, что вы хотите:
а) полностью контролировать и длительность выборки и периодичность каждого преобразования?
б) контролировать только периодичность каждого преобразвоания?
в) контролировать только периодичность преобразований всей группы?
В зависимости от этого и советы будут точнее.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Allregia
сообщение Aug 3 2009, 15:10
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Цитата(rezident @ Aug 3 2009, 17:39) *
Остальное цитировать не буду, т.к. все ваши непонятки от того, что вы невнимательно прочитали раздел, посвященный ADC12, в User's Manual. А конкретные непонятки у вас в функционировании узле выборки-хранения, который обведен на блок-схеме.
Цитата


Может я ошибаюсь, но помоему конретные непонятнки у меня больше с настройкой Таймера_В.
С АЦП - есть непонятнка с ENC, но об этом позже.

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


Попробую описать что я хочу:
1) Запрограммировать таймер_В допустим на 16кгц, без прерываний.
2) по этому таймеру запускать преобразование группы из 3-х каналов.

Сейчас я п.2 делаю в прерывании таймера (взвожу ADC12SC), а хотелось бы чтобы это было без прерывания, чисто аппаратно (если это возможно).
Т.е. "запустил и забыл" - далее в программе я когда хочу, читаю результаты в ADC12MEM0,1,2, зная что каждый канал оцифровывается с частотой 16кгц.
Но у меня таймер не запусакает АЦП.
Я настраиваю АЦП на запуск от "выход 0 таймера В" используя SHS_2 в ADC12CTL1.
Далее - таймер я настраиваю так, чтобы при достижении CCR0 выход 0 устанавливался в "1" (что должно запускать АЦП), а вот кто его сбрасывать в 0 будет - я пока не разобрался.

И еще - мне не совсем понятна фраза в даташите, про необходимость дергать ENC перед кадой серией - это что, надо делать программно? Т.е. сделать так, чтобы ежиножды настроив АЦП и Таймер, запуск серии происходил все время автоматически аппаратно по таймеру нельзя, без софта?
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 3 2009, 15:54
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Allregia @ Aug 3 2009, 21:10) *
Попробую описать что я хочу:
1) Запрограммировать таймер_В допустим на 16кгц, без прерываний.
2) по этому таймеру запускать преобразование группы из 3-х каналов.
Т.е. вы хотите оцифровать последовательность каналов и с периодом 1/16кГц=62,5мкс получать постоянно три готовых результата измерения без каких-либо манипуляций с АЦП, так? Это в принципе возможно, но нужно внимательно посмотреть на времена выборки. Достаточно ли их длительностей будет для оцифровки ваших сигналов?
Посчитаем. Максимальная тактовая у ADC12 - 6,3МГц. Каждое преобразование - 13 тактов ADC12CLK. 62,5мкс-13*3/6,3МГц=56,5мкс суммарно на все выборки или 56,5мкс/3=18,8мкс на каждую Для ваших сигналов достаточно такого времени выборки? Если да, то ближайшее подходящее значение таймера выборки-хранения SHT0/1=5 даст 96 тактов ADC12CLK или 15,2мкс на каждую выборку при тактовой ADC12CLK = 6,3МГц. Устраивает?
Тогда взводим биты MSC и SHP, биты SHSx и ISSH в зависимости от сигнала таймера, выбираем режим CONSEQ_3 и получаем повторяющуюся последовательность каналов с периодом запуска 1/16кГц и общим временем преобразования (96+13)*3=327 тактов ADC12CLK.
Вот только с произвольным считыванием результата без использования DMA может быть небольшой облом-с. laughing.gif Для чтения ADC12MEMx в произвольный момент времени тактовая ADC12CLK должна быть обязательно синхронна тактовой частоте ядра. Т.е. ADC12CLK должен тактироваться от MCLK или другого CLK, синхронного ему.
Go to the top of the page
 
+Quote Post
Allregia
сообщение Aug 4 2009, 07:40
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Цитата(rezident @ Aug 3 2009, 18:54) *
Т.е. вы хотите оцифровать последовательность каналов и с периодом 1/16кГц=62,5мкс получать постоянно три готовых результата измерения без каких-либо манипуляций с АЦП, так?


Именно!

Цитата
Это в принципе возможно, но нужно внимательно посмотреть на времена выборки. Достаточно ли их длительностей будет для оцифровки ваших сигналов?


Достаточно, проверил smile.gif

Цитата
Посчитаем. Максимальная тактовая у ADC12 - 6,3МГц. Каждое преобразование - 13 тактов ADC12CLK. 62,5мкс-13*3/6,3МГц=56,5мкс суммарно на все выборки или 56,5мкс/3=18,8мкс на каждую Для ваших сигналов достаточно такого времени выборки? Если да, то ближайшее подходящее значение таймера выборки-хранения SHT0/1=5 даст 96 тактов ADC12CLK или 15,2мкс на каждую выборку при тактовой ADC12CLK = 6,3МГц. Устраивает?

ADC12CLK у меня 4 Mhz = MCLK/2
Одно преобразование - 13*0.25uS=3.25uS.
Выборки я ставлю SHT0_1, т.е. 8 тактов - 8*0.25=2uS, зачем делать 96 тактов ?
Получается полное время преобразования 3-х каналов - 3*(3.25+2)=15.75uS
Впрочем, это сейчас неважно, могу и 96 тактов поставить.
Цитата
Тогда взводим биты MSC и SHP, биты SHSx и ISSH в зависимости от сигнала таймера,


Я пока не разобрался как сам таймер запрограммировать так, чтобы он запускал АЦП ?

Цитата
выбираем режим CONSEQ_3 и получаем повторяющуюся последовательность каналов с периодом запуска 1/16кГц и общим временем преобразования (96+13)*3=327 тактов ADC12CLK.


Может я конечно совсем тупой, но не понимаю - если CONSEQ_3, то это Repeat-sequence-of-channel, т.е. после преобразования последнего канала сразу начнется преобразование самого первого, и так по кругу, т.е. без участия в этой таймера вообще.

Поэтому я и ставил CONSEQ_1 - Sequence-of-channels.
Цитата
Вот только с произвольным считыванием результата без использования DMA может быть небольшой облом-с. laughing.gif Для чтения ADC12MEMx в произвольный момент времени тактовая ADC12CLK должна быть обязательно синхронна тактовой частоте ядра. Т.е. ADC12CLK должен тактироваться от MCLK или другого CLK, синхронного ему.


Ядро у меня от тех-же 8мгц MCLK кормится, так что с этим проблем не будет.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 17th June 2025 - 13:55
Рейтинг@Mail.ru


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