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

 
 
> Измерение напряжения с помощью АЦП, 16 битное SD16_A
chainikru
сообщение Apr 9 2012, 10:58
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 5-12-11
Пользователь №: 68 682



Добрый день. Хочу поставить индикатор на регулятор мощности, для этого я хочу дополнить регулятор MSP430F2013 на аналоговые входы которого я буду подавать уменьшенный сигнал и измеряя напряжение с помощью АЦП выводить его значение в процентах. Для этого сделал для отлатки устройство с регулируемым напряжением до 0.59 вольт . Как я понял для написания пограммы надо сделать таблицу соответствия напряжения его цифрвому коду в АЦП .
Вот моя программа для этой цели где результат преобразования напряжения хранится в ChA0results:
#include <msp430x20x3.h>

/* Arrays to store SD16 conversion results */
/* NOTE: arrays need to be global to */
/* prevent removal by compiler */
static unsigned int ChA0results = 0x00;

static unsigned int ch_counter=0;

void main(void)
{

volatile unsigned int i; // Use volatile to prevent removal
// by compiler optimization

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL2 |= DIVS_3; // SMCLK/8

SD16CTL = SD16REFON + SD16SSEL_1; // 1.2V ref, SMCLK
SD16INCTL0 = SD16INCH0; // Set channel A0+/-
SD16CCTL0 |= SD16SNGL + SD16UNI + SD16IE;
// Single conv, 256OSR, unipolar,
// enable interrupt
SD16INCTL0 |= SD16INTDLY_0; // Interrupt on 4th sample
SD16AE = SD16AE0; // P1.0 A0+, A0- = VSS

for (i = 0; i < 0x3600; i++); // Delay for 1.2V ref startup

while(1)
{
SD16CCTL0 |= SD16SC; // Set bit to start conversion
_BIS_SR(LPM0_bits + GIE); // Enter LPM0
}
}

#pragma vector = SD16_VECTOR
__interrupt void SD16ISR(void)
{
switch (SD16IV)
{ case 2: // SD16MEM Overflow
break;

case 4: // SD16MEM0 IFG

switch(ch_counter)
{
case 0:
ChA0results = SD16MEM0; // Save CH0 results (clears IFG)
SD16AE &= ~SD16AE0; // Disable external input A0+, A0
SD16INCTL0 &= ~SD16INCH_0; // Disable channel A0+/-
ch_counter++;

SD16AE = SD16AE0; // Reset external input to A0+/-
SD16INCTL0 = SD16INCH_0; // Reset channel observed
break;
}

_BIC_SR_IRQ(LPM0_bits); // Exit LPM0

}
}
Но у меня проблема с недопонимание работы этого АЦП. Я подаю напряжение на канал A0 и вижу результат на SD16MEM0 он его благополучно заносит в ChA0results. Но эти значени при каждом перезапуске программы разные. Подскажите пожалуйста как решить эту проблему и составить таблицу:для
0.59В-"результат преобразования" , 0.531В- , 0.472В- , 0.413В- , 0.354В- , 0.295В- , 0.236В- , 0.177В- , 0.118В- , 0.059В.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
chainikru
сообщение Apr 10 2012, 09:33
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 5-12-11
Пользователь №: 68 682



Цитата(MrYuran @ Apr 10 2012, 08:53) *
Нормально.
Я, кажется, понял.
Вам надо просто несколько фиксированных уровней?
Так это ещё проще.
Забиваете формулу в макрос, и даже считать ничего не придется в рантайме. Константы сосчитаются на этапе компиляции.


Вы имеете ввиду написать чтото наподобие этого (но так что то не хочет работать) ?

Код
#include  <msp430x20x3.h>

#define V_REF    1200ul     // опора в мВ
#define MAX_SCALE    0xffff // вся шкала АЦП
#define V_10   590          // V10 в  мВ
#define V_9    531          // V9 в мВ
#define V_8    472          // V8 в мВ
#define V_7    413          // V7 в мВ
#define V_6    354          // V6 в мВ
#define V_5    295          // V5 в мВ
#define V_4    236          // V4 в мВ
#define V_3    177          // V3 в мВ
#define V_2    118          // V2 в мВ
#define V_1    59           // V1 в мВ
#define V_0    0            // V0 в мВ
#define CODE(v)   (V_REF * v / MAX_SCALE)// макросы пересчета мВ в код АЦП

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
  P1DIR |= 0x01;                            // Set P1.0 to output direction
  SD16CTL = SD16REFON + SD16SSEL_1;         // 1.2V ref, SMCLK
  SD16INCTL0 = SD16INCH_1;                  // A1+/-
  SD16CCTL0 =  SD16UNI + SD16IE;            // 256OSR, unipolar, interrupt enable
  SD16AE = SD16AE2;                         // P1.1 A1+, A1- = VSS
  SD16CCTL0 |= SD16SC;                      // Set bit to start conversion

  _BIS_SR(LPM0_bits + GIE);
}


#pragma vector = SD16_VECTOR
__interrupt void SD16ISR(void)
{
if (SD16MEM0 < CODE(V_6))  P1OUT &= ~0x01;
  else
    P1OUT |= 0x01;
  
/*   P1OUT|= 0x08 + 0x10+0x40 + 0x80;
   P2OUT|= 0x80;
   if (CODE(V_8)< SD16MEM0 < CODE(V_9))
   P1OUT|= 0x04 + 0x08 + 0x10 + 0x20 + 0x80;
   P2OUT|= 0x80;
if (CODE(V_7)< SD16MEM0 < CODE(V_8))
   P1OUT|= 0x04 + 0x08 + 0x10 + 0x20 + 0x40 + 0x80;;
   P2OUT|= 0x80;  
if (CODE(V_6)< SD16MEM0 < CODE(V_7))
   P1OUT|= 0x04 + 0x08 + 0x10 + 0x80;  
if (CODE(V_5)< SD16MEM0 < CODE(V_6))
   P1OUT|= 0x04 + 0x10 + 0x20 + 0x40 + 0x80;
   P2OUT|= 0x80;  
if (CODE(V_4)< SD16MEM0 < CODE(V_5))
   P1OUT|= 0x04 + 0x10 + 0x20 + 0x80;
   P2OUT|= 0x80;
if (CODE(V_3)< SD16MEM0 < CODE(V_4))
   P1OUT|= 0x08 + 0x10+0x80;
   P2OUT|= 0x80;  
if (CODE(V_2)< SD16MEM0 < CODE(V_3))
   P1OUT|= 0x04 + 0x08 + 0x10 + 0x20;
   P2OUT|= 0x80;  
if (CODE(V_1)< SD16MEM0 < CODE(V_2))
   P1OUT|= 0x04 + 0x08 + 0x20 + 0x40;
   P2OUT|= 0x80;    
if (CODE(V_0)< SD16MEM0 < CODE(V_1))
   P1OUT|= 0x08 + 0x10;
if (SD16MEM0 < CODE(V_0))
   P1OUT|= 0x04 + 0x08 + 0x10 + 0x20 + 0x40 + 0x80;
   P2OUT|= 0x80;  */  
  
     _BIC_SR_IRQ(LPM0_bits);                // Exit LPM0    
}
    
}


в if (SD16MEM0 < CODE(V_6)) P1OUT &= ~0x01;
else
P1OUT |= 0x01; светодиод горит даже при отсутствии напряжения хотя елси вместо CODE(V_6) написать 0x7FFF //SD16MEM0 > 0.3V?, clears IFG то покра немерее яркость светодида меняется при изменении напряжения (почти выключается)

Сообщение отредактировал chainikru - Apr 10 2012, 10:07
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 29th July 2025 - 05:10
Рейтинг@Mail.ru


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