|
АЦП MSP430F149, Чего я неправильно делаю? |
|
|
|
Jun 30 2009, 08:36
|

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

|
в качестве совета. В IDE обычно всегда есть хедеры со всеми константами, не надо делать так: ADC12CTL0 |= 0x0001; ADC12MCTL0 = 0x10; ADC12CTL1 = 0x5000+SHP+ADC12SSEL1+ADC12DIV0; и пр. Ваш код пока не смотрел, ибо докипод рукой нет, а на память не помню. Если резидент не опередит, что обычно бывает  то скажу в чем проблема к вечеру.
|
|
|
|
|
Jul 1 2009, 17:32
|
Местный
  
Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468

|
Цитата(Сергей Борщ @ Jun 30 2009, 15:32)  Если открыто окно отладчика с регистрами АЦП - то да. Но точно такие же чудеса будут происходить и с таймерами (TAIV, TBIV), и с UART - вообще с любой периферией, значение регистров которой изменяется чтением. Ух ты, вот оно что ! Теперь ясно...
|
|
|
|
|
Aug 2 2009, 10:12
|
Профессионал
    
Группа: Свой
Сообщений: 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; Получаю естессно фигвам. Вопрос - чего я забыл еще включить ?
|
|
|
|
|
Aug 3 2009, 12:03
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Aug 3 2009, 14:16
|
Профессионал
    
Группа: Свой
Сообщений: 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 из программы. Но(!), я думал что есть возможность запускать преобразование без прерывания таймера а аппаратно (не хочется терять время на обработчик таймерного прерывания), и вот это-то у меня пока и не получилось.
|
|
|
|
|
Aug 3 2009, 14:39
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Allregia @ Aug 3 2009, 20:16)  Я наверное не очень обьяснил, "пинок" - это было чисто для проверки, а мне надо постоянно оцифровывать только 3 канала 0-1-2, но запуск осуществлять по таймеру В (чтобы не получиь джиттер). Остальное цитировать не буду, т.к. все ваши непонятки от того, что вы невнимательно прочитали раздел, посвященный ADC12, в User's Manual. А конкретные непонятки у вас в функционировании узле выборки-хранения, который обведен на блок-схеме. Поясните точнее, что вы хотите: а) полностью контролировать и длительность выборки и периодичность каждого преобразования? б) контролировать только периодичность каждого преобразвоания? в) контролировать только периодичность преобразований всей группы? В зависимости от этого и советы будут точнее.
Эскизы прикрепленных изображений
|
|
|
|
|
Aug 3 2009, 15:10
|
Профессионал
    
Группа: Свой
Сообщений: 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 перед кадой серией - это что, надо делать программно? Т.е. сделать так, чтобы ежиножды настроив АЦП и Таймер, запуск серии происходил все время автоматически аппаратно по таймеру нельзя, без софта?
|
|
|
|
|
Aug 3 2009, 15:54
|
Гуру
     
Группа: Свой
Сообщений: 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 может быть небольшой облом-с.  Для чтения ADC12MEMx в произвольный момент времени тактовая ADC12CLK должна быть обязательно синхронна тактовой частоте ядра. Т.е. ADC12CLK должен тактироваться от MCLK или другого CLK, синхронного ему.
|
|
|
|
|
Aug 4 2009, 07:40
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(rezident @ Aug 3 2009, 18:54)  Т.е. вы хотите оцифровать последовательность каналов и с периодом 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МГц. Устраивает? 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 может быть небольшой облом-с.  Для чтения ADC12MEMx в произвольный момент времени тактовая ADC12CLK должна быть обязательно синхронна тактовой частоте ядра. Т.е. ADC12CLK должен тактироваться от MCLK или другого CLK, синхронного ему. Ядро у меня от тех-же 8мгц MCLK кормится, так что с этим проблем не будет.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|