Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: MSPx2xx модуль АЦП10
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
KARLSON
Здравствуйте. Предлагаю сюда вносить все вопросы связанные с АЦП10 2-го семейства.
У меня вопрос такой.
Надо оцифровывать 2 канала P3.0 (A5) и P3.7(A7).
Хочу за одно вздёргивание бита ADC10SC получить 2 измерения. И что бы эти измерения скопировались в структуру АВ с помощью DTC.
Код
#include "msp430x21x2.h"

struct _AB
{
  unsigned int A2;
  unsigned int A1;
  unsigned int A0;
}AB;

void Pause (unsigned int time) { while (time-- > 0);}

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  P2SEL = BIT6 + BIT7;
  
// сброс флага "сбой генератора" и запрет прер-ия OFIE при не исправ-ти DC-генератора
  IE1 &= ~OFIE;
  IFG1 &= ~OFIFG;

  // предустановка желаемой частоты DCOCLK = 8MГц
  _BIC_SR(OSCOFF);              // включить генератор LFXT1
  DCOCTL = CALDCO_8MHZ;
  BCSCTL1 = CALBC1_8MHZ;
  BCSCTL1 |= XT2OFF + XTS + DIVA_0; // источник такт-ия MCLK и SMCLK - DCOCLK, MCLK = DCOCTL/1, SMCLK = DCOCTL/1
  BCSCTL3 = LFXT1S_2;
// инициализация LFXT1
  do  
  {
    IFG1 &= ~OFIFG;
    Pause(5000);
  }while (IFG1 & OFIFG);

  BCSCTL2 = SELM_3  //SELM_0  (0x00)   /* MCLK Source Select 0: DCOCLK */
                 +DIVM_0  
                 +DIVS_3;
  
  ADC10CTL1 =// INCH_5
            + INCH_7
          ///  + ADC10DIV_7
           + ADC10SSEL_2   // MCLK = 8МГц
            + CONSEQ_1
           ;
   ADC10CTL0 |= ADC10SHT_3
                     //  + MSC              
                      + ADC10ON;
  
  ADC10AE0 = BIT7
           + BIT5
            ;
  ADC10DTC0 |= ADC10CT;
  ADC10DTC1 = 2;
  ADC10SA = (unsigned int ) &AB.A2;
  
  ADC10CTL0 |= ENC;
  
  while (1)
  {
    ADC10CTL0 &= ~ENC;
    
    while (BUSY & ADC10CTL1);
    ADC10CTL0 |= ENC + ADC10SC;             // Start sampling

    _NOP();
    
  }

}


Но ничего не выходит. Измерения смотрю в Watch.
Измерять один канал у меня получается. Но не переконфигурировать же мне постоянно модуль.
Посоветуйте как его настроить?
rezident
Цитирую User's Guide
Цитата
22.2.6.2 Sequence-of-Channels Mode
A sequence of channels is sampled and converted once. The sequence begins with the channel selected
by INCHx and decrements to channel A0
. Each ADC result is written to ADC10MEM. The sequence stops
after conversion of channel A0.

То бишь в ADC10, в отличие от ADC12, нельзя сделать последовательность номеров каналов произвольной.
В свое время я пробовал использовать DTC в MSP430F1132 для оцифровки двух и/или трех каналов (A0-A1, A0-A2), но перенос данных преобразования почему-то получался неоднозначным. Данные от разных каналов сдвигались (циклически?) внутри выделенного буфера. Разбираться тщательно тогда не стал (время поджимало), сделал индивидуальный запуск одиночных преобразований с обработкой результата и (пере)запуском следующего после соответствующей реинициализации ADC10 прямо в прерывании от ADC10. В серии MSP430F2xx с ADC10 работать не приходилось, хотя вроде отличий быть не должно, т.к. данный модуль переехал из 1xx в 2xx без изменений.
bigal
Если покопаться в примерах применения
// MSP430F20x2 Demo - ADC10, DTC Sample A2-0, AVcc, Single Sequence, DCO
#include "msp430x20x2.h"

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
ADC10CTL1 = INCH_3 + CONSEQ_1; // A3/A2/A1, single sequence
// !!!! номера канала будет последовательно декрементироваться от 3 к нулевому нельзя указать произвольные
ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
ADC10DTC1 = 0x03; // 3 conversions
// 3 преобразования
ADC10AE0 |= 0x0E; // P1.3,2,1 ADC10 option select
P1DIR |= 0x01; // Set P1.0 output

for (;;)
{
ADC10CTL0 &= ~ENC;
while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active
ADC10SA = 0x200; // Data buffer start
// !!!адрес начала буфера куда запишеться результат!!!!!!!
P1OUT |= 0x01; // P1.0 = 1
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit
P1OUT &= ~0x01; // P1.0 = 0
}
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}
KARLSON
Я так и думал. Спасибо.
Так как у меня дальний вход это A7, то создавать из-за этого структуру с 8 2-х байтных переменных, это просто так не использовать 12 байт и так малой оперативки.
Alexander Petrov
Здравствуйте. Не получается запустить преобразование АЦП аппаратно при помощи Таймера0. Подскажите, если кто-то сталкивался с такой проблемой. Пробовал запускать программно из прерывания таймера - работает.
KARLSON
Что означает?:
Цитата(Alexander Petrov @ Jun 13 2011, 18:01) *
преобразование АЦП аппаратно при помощи Таймера0.

и
Цитата(Alexander Petrov @ Jun 13 2011, 18:01) *
запускать программно из прерывания таймера - работает.

Код в студию. настройка ацп и код настройки таймера и код прерывания таймера.
Alexander Petrov
Цитата(KARLSON @ Jun 14 2011, 01:04) *
Что означает?:

и

Код в студию. настройка ацп и код настройки таймера и код прерывания таймера.



Нужен запуск преобразования АЦП от таймера при SHSx = 01, чтобы обойтись без прерывания.

void initADC (void)
{
ADC10AE0 = 0x06;
ADC10AE1 = 0x00;
ADC10DTC0 = 0x0C;
ADC10DTC1 = 48;
ADC10SA = 0x0540;

ADC10CTL0 = 0x28F8;
ADC10CTL1 = 0x241A;
ADC10CTL0 |= 0x0002;
}


void initTimer0 (void)
{
TACCR0 = 124;
TACCR1 = 100;
TACTL = 0x0214;
TACCTL1 = 0x0040;
}
rezident
Alexander Petrov, раз уж вы пишете программу на языке высокого уровня (Си), то почему бы вам не воспользоваться стандартными символьными обозначениями битов MSP430? Вы думаете у кого-то возникает страстное желание разбираться с вашими 16-иричными константами, сопоставляя их битам регистров? sad.gif
По поводу вашей программы могу предположить, что у вас таймер попросту не запускается. Потому что вы неправильно его инициализируете. Обратите внимание в User's Manual на описание бита TACLR
Цитата
TACLR Bit 2 Timer_A clear. Setting this bit resets TAR, the clock divider, and the count direction. The TACLR bit is
automatically reset and is always read as zero.

При установке этого бита таймер сбрасывается и останавливается потому, что. обнуляются биты MCx. Добавьте в конце после инициализации всех регистров таймера команду для его запуска, включив режим Up mode.
Код
TACTL |= MC0;

Кстати, сообщите потом удалось ли вам "победить" Data Tranfer от модуля ADC10? Я когда-то давно попробовал его использовать, но забросил, т.к. не смог сходу получить однозначности при переносе данных преобразования от разных каналов. Данные как-то странным образом сдвигались, не попадая в соответствующие им ячейки памяти SRAM. Я уже выше писал, что разбираться не стал и потом больше повода не возникало. Но некая неудовлетворенность от непоняток осталась rolleyes.gif
Alexander Petrov
Цитата(rezident @ Jun 15 2011, 23:15) *
Alexander Petrov, раз уж вы пишете программу на языке высокого уровня (Си), то почему бы вам не воспользоваться стандартными символьными обозначениями битов MSP430? Вы думаете у кого-то возникает страстное желание разбираться с вашими 16-иричными константами, сопоставляя их битам регистров? sad.gif
По поводу вашей программы могу предположить, что у вас таймер попросту не запускается. Потому что вы неправильно его инициализируете. Обратите внимание в User's Manual на описание бита TACLR

При установке этого бита таймер сбрасывается и останавливается потому, что. обнуляются биты MCx. Добавьте в конце после инициализации всех регистров таймера команду для его запуска, включив режим Up mode.
Код
TACTL |= MC0;

Кстати, сообщите потом удалось ли вам "победить" Data Tranfer от модуля ADC10? Я когда-то давно попробовал его использовать, но забросил, т.к. не смог сходу получить однозначности при переносе данных преобразования от разных каналов. Данные как-то странным образом сдвигались, не попадая в соответствующие им ячейки памяти SRAM. Я уже выше писал, что разбираться не стал и потом больше повода не возникало. Но некая неудовлетворенность от непоняток осталась rolleyes.gif


rezident, по поводу остановки таймера при установке бита TACLR вы не правы - таймер сбрасывается и продолжает работать с нуля.

а по поводу DTC эффект сдвига действительно наблюдался. Однако до момента останова данные поападают на свои места (т.е. при первом останове они нормально расположены, а далее могут сдвигаться). Мне удавалось наблюдать нормальную работу, когда останов производился в обработчике прерывания АЦП.
KARLSON
Цитата(Alexander Petrov @ Jun 17 2011, 08:36) *
при установке бита TACLR вы не правы - таймер сбрасывается и продолжает работать с нуля.

Он не просто сбрасывается, а:
1) обнуляет регистр TAR
2) обнуляет делитель
3) сбрасывает признак направления счёта

И перепишите код, в место чисел названия бит. Помощь поступит быстрее)))
rezident
Цитата(Alexander Petrov @ Jun 17 2011, 09:36) *
rezident, по поводу остановки таймера при установке бита TACLR вы не правы - таймер сбрасывается и продолжает работать с нуля.

Ну я же не отсебятину, а цитату из User's Guide привел. Вы опровергаете данные UG? Т.е. там содержиться ошибка? Срочно напишите в тех.поддержку TI! А то они, бедняги, уже лет 10 выпускают кристаллы, не зная о таком существенном баге sm.gif
Цитата(Alexander Petrov @ Jun 17 2011, 09:36) *
а по поводу DTC эффект сдвига действительно наблюдался. Однако до момента останова данные поападают на свои места (т.е. при первом останове они нормально расположены, а далее могут сдвигаться). Мне удавалось наблюдать нормальную работу, когда останов производился в обработчике прерывания АЦП.

Спасибо за информацию. То что сдвиг происходит при останове дебаггером оно понятно. Дебаггер DTC не управлялет. Но видимо все равно необходимо модуль DTC реинициализировать при каждом его запуске.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.