Может кто-нибудь имел с ними дело. DRDY ведет себя странно. По datasheet должен быть преимущественно в 1 и сбрасываться в ноль, когда данные готовы, а у меня все наоборот. Слишком часто для готовности данных шпарит импульс по DRDY. AD7714 передает один байт 0x05 когда я выплеваваю dummy байты.
MCLK подается 1 МГц от SMCLK; BUFFER становлен в 0; CS на время передачи устанавливается в 0;
STANDBY установлен в 1; SYN в 1; POL в 1. Необходимо проводить измерение 16 разрядов с A1-A2.
#include "msp430x16x.h"
#define CS 0x01 // P1.0
#define DRDY 0x02 // P1.1
#define MCLK 0x04 // P1.2
#define BUFFER 0x08 // P1.3
#define STBY 0x10 // P1.4
#define MRESET 0x20 // P1.5
#define SYN 0x40 // P1.6
#define POL 0x80 // P1.7
#define TIMER_READY (0x02)
#define TX_ENABLE (0x08) // разрешение передачи
#define RX_ENABLE (0x10) // разрешение приема
unsigned int FLAGS;
unsigned int cmd_counter;
unsigned char COMMANDS[] = {0x14, // регистр режима
0x20, // калибровка
0x24, // верхний фильтр
0x80, // конфиг
0x34, // нижний фильтр
0x32, // конфиг
0x5c, // чтение из регистра данных
0x5c, // dummy
0x5c, // dummy
0x5c, // dummy
0x5c}; // dummy
unsigned char RX_BUFFER[20];
unsigned int rx_counter;
void TX_Char(unsigned int c);
void Send_Data(unsigned int data);
void Sleep(unsigned int ms);
void Set_DCO(void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog
Set_DCO();
BCSCTL2 |= SELM_1 + DIVS_2; // MCLK = DCO, SMCLK = DCO/4,
WDTCTL = WDT_MDLY_8;
TBCCTL0 = CCIE; // CCR0 interrupt enabled
TBCCR0 += 1000;
TBCTL = TBSSEL_2 + MC_2; // SMCLK, contmode
P5DIR = 0x2e;
P5SEL |= 0x2e; // ноги SPI, SMCLK на улицу через 49 ногу
U1CTL = CHAR + SYNC + MM + SWRST; // 8-bit, SPI, Master
U1TCTL = SSEL1 + STC + CKPL; // Polarity, SMCLK, 3-wire
U1BR0 = 0x40; // SPICLK =
U1BR1 = 0x00;
U1MCTL = 0x00;
ME2 |= USPIE1; // Module enable
U1CTL &= ~SWRST; // SPI enable
IE2 |= URXIE1 + UTXIE1; // RX and TX interrupt enable
P1OUT = 0xff;
P1DIR = MRESET + CS;
P1DIR &= ~DRDY;
P1IES |= DRDY; // 1->0
P1IFG = 0; // сбросить флаги прерываний
IE1 |= WDTIE;
_BIS_SR(GIE);
cmd_counter = 0;
rx_counter = 0;
while(1){ // двух секундный цикл
P1OUT &= ~MRESET;
Sleep(1);
P1OUT |= MRESET;
//инициировать передачу
P1OUT &= ~CS;
FLAGS |= TX_ENABLE;
IFG2 |= UTXIFG1; // вызвать прерывание
for(int i = 0; i< 100; i++)
{// 65-мс цикл
// установить буфер приема в начало
rx_counter = 0;
Sleep(65);
}
// к настоящему моменту все должно быть уже принято и передано
P1IE &= ~DRDY; // прерывание RXD выкл.
FLAGS &= ~(TX_ENABLE + RX_ENABLE);
}
}
void Sleep(unsigned int ms)
{ //функция орагнизует задержку в ms миллисекунд
FLAGS &= ~TIMER_READY;
TBCCTL0 = CCIE;
TBCCR0 += ms*1000;
while (!(FLAGS & TIMER_READY));
TBCCTL0 &= ~CCIE;
FLAGS &= ~TIMER_READY;
}
#pragma vector=PORT1_VECTOR
__interrupt void port_isr(void)
{ // данные АЦП готовы
_NOP();
P1IFG = 0; // сбросить флаг прерывания
P1OUT &= ~CS; // инициировать передачу для приема
FLAGS |= TX_ENABLE + RX_ENABLE;
cmd_counter = sizeof(COMMANDS)-3;
IFG2 |= UTXIFG1; // вызвать прерывание
}
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B (void)
{
FLAGS |= TIMER_READY;
}
#pragma vector=USART1RX_VECTOR
__interrupt void SPI1_rx (void)
{
if (FLAGS & RX_ENABLE)
{
if (rx_counter > sizeof(RX_BUFFER)-1) rx_counter = 0;
RX_BUFFER[rx_counter++] = RXBUF1;
_NOP();
}
}
#pragma vector=USART1TX_VECTOR
__interrupt void SPI1_tx (void)
{
if(FLAGS & TX_ENABLE)
{
TXBUF1 = COMMANDS[cmd_counter];
cmd_counter++;
if(cmd_counter > sizeof(COMMANDS)-1){
// все команды переданы
cmd_counter = 0;
FLAGS &= ~TX_ENABLE; // запретить передачу
P1OUT |= CS;
P1IE |= DRDY; // ждем прерывание о готовности данных вкл.
}
}
_NOP();
}
-
- Хошь пример на Паскале? - Vladimir Ljaschko(14.06.2008 13:29)