На аналоговый дифференциальный вход (D0- D0+) АЦП SD16_A подан сигнал с термодатчика, запитанного с внутреннего источника референсного напряжения. Другой вход (D4- D4+) подключен к источнику переменного напряжения. Изменения напряжения в диапазоне от +400 мВ до -200 мВ не оказывают никакого влияния на результат оцифровки показаний термодатчика, но изменения ниже -200 мВ дублируются в масштабе 1:6, искажая показания температуры на 70-130 градусов.
Ниже прилагается текст программы и фрагмент схемы.

Код
// MSP430x4270 - SD16_A, Continuous Conversion on a pair of Channels
#include <msp430x42x0.h>
#include "Types.h"
#include "UART.h"
#define NUM_AD_CHAN 2 // число каналов AD
#define NUM_SUM 64 // Число слагаемых
#define NUM_SUM_ORDER 6 // Число битов для сдвига к усреднению по накопленному числу слагаемых = log(2)(NUM_SUM)
unsigned short volatile Result[2], Res=0, ndx = 0; // Рез-т и # AD-хода
void main( void ) {
INT16U i;
INT08U ch_nr = 0;
unsigned long longAcc = 0;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
SCFI0 |= FN_2 + FLLD_8; // Set DCO operating range
SCFQCTL = 24; // (24+1) x 8 x 32768 = 6553600 Hz
FLL_CTL0 |= XCAP14PF + DCOPLUS; // DCO+ set so freq = xtal x D x ((N-1)+1)
for (i = 0; i < 10000; i++); // Delay for MCLC to stabilize
SD16CTL = SD16REFON + SD16SSEL0 + SD16DIV_3
+ SD16XDIV_0;// + SD16VMIDON; // до 819200 Hz
SD16CCTL0 |= SD16IE + SD16OSR_256; // Enable interrupt, OSR=256,
SD16INCTL0 |= SD16INTDLY_0 + SD16INCH_7; // Interrupt on 4th sample, chan 0
P1SEL = 0X00; // Инициализация входов
P2SEL = 0x00;
P1DIR = 0xFF;
P2DIR = 0xFF;
UART_Init(); // Настройка последовательного интерфейса
_EINT(); // Enable general interrupts
while (ndx < NUM_SUM) {
SD16CCTL0 |= SD16SC; // Запуск сигма-дельта АЦП
_BIS_SR(LPM0_bits); // Enter LPM0
longAcc += Res; // result is ready
if ( ndx == NUM_SUM - 1 ) {
SD16CCTL0 &= ~SD16SC; // Stop ADC
Result[ch_nr] = (unsigned short) (longAcc >> NUM_SUM_ORDER);
longAcc = 0;
if ( (SD16INCTL0 & 0x0007) == SD16INCH_0 ) //* Переключение входа
{
SD16INCTL0 &= ~SD16INCH_0; // off chan 0
SD16INCTL0 |= SD16INCH_4; // chan 4 on
ch_nr = 1; // Для многоканального режима
} else {
SD16INCTL0 &= ~SD16INCH_4; // off chan 4
SD16INCTL0 |= SD16INCH_0; // chan 0 on
UART_SendPacket ( NUM_AD_CHAN, Result); // Передача данных
ch_nr = 0; // Для многоканального режима
} ndx = 0;
} ndx++; } }
#pragma vector=SD16_VECTOR
__interrupt void SD16ISR(void) {
switch (SD16IV) {
case 2: // SD16MEM Overflow
break;
case 4: // SD16MEM0 IFG
Res = SD16MEM0; // Save result (clears IFG)
break; }
__bic_SR_register_on_exit(CPUOFF); }
#include <msp430x42x0.h>
#include "Types.h"
#include "UART.h"
#define NUM_AD_CHAN 2 // число каналов AD
#define NUM_SUM 64 // Число слагаемых
#define NUM_SUM_ORDER 6 // Число битов для сдвига к усреднению по накопленному числу слагаемых = log(2)(NUM_SUM)
unsigned short volatile Result[2], Res=0, ndx = 0; // Рез-т и # AD-хода
void main( void ) {
INT16U i;
INT08U ch_nr = 0;
unsigned long longAcc = 0;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
SCFI0 |= FN_2 + FLLD_8; // Set DCO operating range
SCFQCTL = 24; // (24+1) x 8 x 32768 = 6553600 Hz
FLL_CTL0 |= XCAP14PF + DCOPLUS; // DCO+ set so freq = xtal x D x ((N-1)+1)
for (i = 0; i < 10000; i++); // Delay for MCLC to stabilize
SD16CTL = SD16REFON + SD16SSEL0 + SD16DIV_3
+ SD16XDIV_0;// + SD16VMIDON; // до 819200 Hz
SD16CCTL0 |= SD16IE + SD16OSR_256; // Enable interrupt, OSR=256,
SD16INCTL0 |= SD16INTDLY_0 + SD16INCH_7; // Interrupt on 4th sample, chan 0
P1SEL = 0X00; // Инициализация входов
P2SEL = 0x00;
P1DIR = 0xFF;
P2DIR = 0xFF;
UART_Init(); // Настройка последовательного интерфейса
_EINT(); // Enable general interrupts
while (ndx < NUM_SUM) {
SD16CCTL0 |= SD16SC; // Запуск сигма-дельта АЦП
_BIS_SR(LPM0_bits); // Enter LPM0
longAcc += Res; // result is ready
if ( ndx == NUM_SUM - 1 ) {
SD16CCTL0 &= ~SD16SC; // Stop ADC
Result[ch_nr] = (unsigned short) (longAcc >> NUM_SUM_ORDER);
longAcc = 0;
if ( (SD16INCTL0 & 0x0007) == SD16INCH_0 ) //* Переключение входа
{
SD16INCTL0 &= ~SD16INCH_0; // off chan 0
SD16INCTL0 |= SD16INCH_4; // chan 4 on
ch_nr = 1; // Для многоканального режима
} else {
SD16INCTL0 &= ~SD16INCH_4; // off chan 4
SD16INCTL0 |= SD16INCH_0; // chan 0 on
UART_SendPacket ( NUM_AD_CHAN, Result); // Передача данных
ch_nr = 0; // Для многоканального режима
} ndx = 0;
} ndx++; } }
#pragma vector=SD16_VECTOR
__interrupt void SD16ISR(void) {
switch (SD16IV) {
case 2: // SD16MEM Overflow
break;
case 4: // SD16MEM0 IFG
Res = SD16MEM0; // Save result (clears IFG)
break; }
__bic_SR_register_on_exit(CPUOFF); }