This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5510 控制ADS1299!

Other Parts Discussed in Thread: ADS1299, MSP430F5510

大家好,我目前 通过3线模式SPI 控制ADS1299. 

1, 希望通过通过键盘输入某一指令,然后SPI读取ADS1299 的寄存器值,比如从00H开始连续读取15个寄存器的值。最后通过USB发送给电脑TERMINAL。

目前遇到的问题是:如果只是读取一个寄存器,比如00H,或者01H。 都可以得到正确的寄存器值。但是读取一个以上就不能得到正确的值。往往都是0.  我个人判断是Sclk的问题。但不完全清楚。

我目前的code如下所示: 希望得到大家的指点。谢谢。

//******************************************************************************
// MSP430F5510: ReadRegV5.0 use USB_API and driverlib
//
// Description: Read Reg from ADS1299_0 and send to PC
//
// Problem:
//
// Jerry.
// 08/06/16
//******************************************************************************

#include <string.h>
#include "driverlib.h"

#include "USB_config/descriptors.h"
#include "USB_API/USB_Common/device.h"
#include "USB_API/USB_Common/usb.h" // USB-specific functions
#include "USB_API/USB_CDC_API/UsbCdc.h"
#include "USB_app/usbConstructs.h"

#include "hal.h"

// function definition
void MySPIinit (void); // SPI init
void send_spi_rreg(void);
void power_up(void);

#define *** 500000 // sclk
#define MAX_STR_LENGTH 64

// Holds the new addition to the string
char pieceOfString[MAX_STR_LENGTH] = "";

// Holds the outgoing string
char outString[MAX_STR_LENGTH] = "";

// Global flags set by events
volatile uint8_t bCDCDataReceived_event = FALSE; // Indicates data has been rx'ed without an open rx operation

uint8_t returnValue = 0x00;

// Reg from ADS1299
uint8_t Chip_Reg[1] = {0};
uint8_t rreg[3];

char TxString,RxString;

int i,j;

//****************************************************************************************************************//
//********************************* ======== main ========********************************************************//
//****************************************************************************************************************//
void main (void)
{
WDT_A_hold(WDT_A_BASE); // Stop watchdog timer

__disable_interrupt(); // Disable global interrupts
// Minumum Vcore setting required for the USB API is PMM_CORE_LEVEL_2 .
PMM_setVCore(PMM_CORE_LEVEL_2);
USBHAL_initPorts(); // Config GPIOS for low-power (output low)
USBHAL_initClocks(8000000); // Config clocks. MCLK=SMCLK=FLL=8MHz; ACLK=REFO=32kHz
MySPIinit(); // Init the SPI
__enable_interrupt(); // Enable interrupts globally. and this is very important

USB_setup(TRUE, TRUE); // Init USB & events; if a host is present, connect

// set P1.1 for /DRDY0
GPIO_setAsInputPinWithPullUpResistor( GPIO_PORT_P1, GPIO_PIN1 ); // setup P1.1 as input

power_up();

while (1)
{
// Check the USB state and directly main loop accordingly
switch (USB_getConnectionState())
{
case ST_ENUM_ACTIVE:
// If true, some data is in the buffer; begin receiving a cmd
if (bCDCDataReceived_event)
{
// Add bytes in USB buffer to the string
USBCDC_receiveDataInBuffer((uint8_t*)pieceOfString,
MAX_STR_LENGTH,
CDC0_INTFNUM); // Get the next piece of the string

//******************************************************************************************************************
// if put the if loop below outside the if loop above, the sending process will go forever(see ReadRegV3.0).
// Compare to string #1, and respond
if (!(strcmp(pieceOfString, "r")))
{
send_spi_rreg();
}
bCDCDataReceived_event = FALSE;
//******************************************************************************************************************
}
break;

case ST_PHYS_DISCONNECTED:
case ST_ENUM_SUSPENDED:
case ST_PHYS_CONNECTED_NOENUM_SUSP:
__bis_SR_register(LPM3_bits + GIE);
_NOP();
break;
case ST_ENUM_IN_PROGRESS:
default:;
}
} // while(1)
} // main()**********************************************************************************************************//

void power_up(void)
{
// ADS1299 power up*************************************************************************//
GPIO_setOutputHighOnPin(GPIO_PORT_P6, GPIO_PIN0); // /RESET high
__delay_cycles(4000000);//1 second delay
GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN0); // /RESET low
__delay_cycles(100);//at least two cycles delay
GPIO_setOutputHighOnPin(GPIO_PORT_P6, GPIO_PIN0); // /RESET high
//Wait for slave to initialize
__delay_cycles(100); // at least 18clk delay
// Finish power up **************************************************************************//
}

void send_spi_rreg(void)
// 1. This command sends RREG opcode to the ADS1299 to read register values
{
uint8_t i;

GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);//ensable /CS0
GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN2); //disable /CS1

//Initialize data values for rreg command
rreg[2] = 0x00; //read 1 bytes
rreg[1] = 0x20; //read regster from addr 00h
rreg[0] = 0x11; //send sdatac opcode first

for (i=0; i<3; i++)
{
//USCI_A1 TX buffer ready?
while(!USCI_A_SPI_getInterruptStatus(USCI_A1_BASE,
USCI_A_SPI_TRANSMIT_INTERRUPT));

//Transmit Data to slave
USCI_A_SPI_transmitData(USCI_A1_BASE, rreg[i]);
__delay_cycles(32);
}

Chip_Reg[0] = USCI_A_SPI_receiveData(USCI_A1_BASE); //send just the 00h register which is the chip's ID

USBCDC_sendDataInBackground(Chip_Reg,1,CDC0_INTFNUM,1);

GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0); //disable /CS0

__delay_cycles(32);
}

/* SPI init*/
void MySPIinit(void)
{
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_P4,
GPIO_PIN0 + GPIO_PIN4 + GPIO_PIN5
);

//Initialize Master
USCI_A_SPI_initMasterParam param = {0};
param.selectClockSource = USCI_A_SPI_CLOCKSOURCE_SMCLK;
param.clockSourceFrequency = UCS_getSMCLK();
param.desiredSpiClock = ***;
param.msbFirst = USCI_A_SPI_MSB_FIRST;
param.clockPhase = USCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT;
param.clockPolarity = USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW;
//param.clockPolarity = USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH; //change from HIGH to LOW in order to be the same with Bruce' code
returnValue = USCI_A_SPI_initMaster(USCI_A1_BASE, &param);

if(STATUS_FAIL == returnValue)
{
return;
}

//Enable SPI module
USCI_A_SPI_enable(USCI_A1_BASE);

//Wait for slave to init
__delay_cycles(100);

//Initialize and Setup DMA Channel 0
/*
* Configure DMA channel 0
* Configure channel for single transfer
* DMA transfers will be disabled and interrupt flag will be set after every
* 1 transfer
* Use DMA Trigger Source 21 (UCA1TXIFG)
* Transfer Byte-to-byte
* Trigger transfer on signal held high
*/
DMA_initParam param0 = {0};
param0.channelSelect = DMA_CHANNEL_0;
param0.transferModeSelect = DMA_TRANSFER_SINGLE;
param0.transferSize = 1;
param0.triggerSourceSelect = DMA_TRIGGERSOURCE_21;
param0.transferUnitSelect = DMA_SIZE_SRCBYTE_DSTBYTE;
param0.triggerTypeSelect = DMA_TRIGGER_HIGH;
DMA_init(&param0);
/*
* Configure DMA channel 0
* Use TxString as source
* Increment source address after every transfer
*/
DMA_setSrcAddress(DMA_CHANNEL_0,
(uint32_t)&TxString,
DMA_DIRECTION_INCREMENT);
/*
* Configure DMA channel 0
* Use SPI TX Buffer as destination
* Don't move the destination address after every transfer
*/
DMA_setDstAddress(DMA_CHANNEL_0,
USCI_A_SPI_getTransmitBufferAddressForDMA(USCI_A1_BASE),
DMA_DIRECTION_UNCHANGED);

//Initialize and Setup DMA Channel 1
/*
* Configure DMA channel 1
* Configure channel for single transfer
* DMA transfers will be disabled and interrupt flag will be set after every
* 1 transfer
* Use DMA Trigger Source 20 (UCA1RXIFG)
* Transfer Byte-to-byte
* Trigger transfer on signal held high
*/

DMA_initParam param1 = {0};
param1.channelSelect = DMA_CHANNEL_1;
param1.transferModeSelect = DMA_TRANSFER_SINGLE;
param1.transferSize = 1;
param1.triggerSourceSelect = DMA_TRIGGERSOURCE_20;
param1.transferUnitSelect = DMA_SIZE_SRCBYTE_DSTBYTE;
param1.triggerTypeSelect = DMA_TRIGGER_HIGH;
DMA_init(&param1);

/*
* Configure DMA channel 1
* Use SPI RX Buffer as source
* Don't move the source address after every transfer
*/
DMA_setSrcAddress(DMA_CHANNEL_1,
USCI_A_SPI_getReceiveBufferAddressForDMA(USCI_A1_BASE),
DMA_DIRECTION_UNCHANGED);
/*
* Configure DMA channel 1
* Use RxString as destination
* Increment destination address after every transfer
*/
DMA_setDstAddress(DMA_CHANNEL_1,
(uint32_t)&RxString,
DMA_DIRECTION_INCREMENT);

//Clear TxString && RxString
TxString = RxString = 0;
}

/*
* ======== UNMI_ISR ========
*/
#if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__)
#pragma vector = UNMI_VECTOR
__interrupt void UNMI_ISR (void)
#elif defined(__GNUC__) && (__MSP430__)
void __attribute__ ((interrupt(UNMI_VECTOR))) UNMI_ISR (void)
#else
#error Compiler not found!
#endif
{
switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG))
{
case SYSUNIV_NONE:
__no_operation();
break;
case SYSUNIV_NMIIFG:
__no_operation();
break;
case SYSUNIV_OFIFG:
UCS_clearAllOscFlagsWithTimeout(0);
SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT);
break;
case SYSUNIV_ACCVIFG:
__no_operation();
break;
case SYSUNIV_BUSIFG:
// If the CPU accesses USB memory while the USB module is
// suspended, a "bus error" can occur. This generates an NMI, and
// execution enters this case. This should never occur. If USB is
// automatically disconnecting in your software, set a breakpoint
// here and see if execution hits it. See the Programmer's
// Guide for more information.
SYSBERRIV = 0; // Clear bus error flag
USB_disable(); // Disable USB -- USB must be reset after a bus error
}
}