请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:MSP-EXP430F5529LP 主题中讨论的其他器件:MSP430F5529
Bonjour、
JE drais 连接器、unmsp430F5529 en tant que maiter SPI a un MSP4302433 en vantant que esclave SPI。
JE PREND 滴注代码 CI 滴注口领器:
MSP430F55xx_USCI_SPI_standard_master.c
//******************************************************************************
// MSP430F552x Demo - USCI_A0, SPI 3-Wire Master multiple byte RX/TX
//
// Description: SPI master communicates to SPI slave sending and receiving
// 3 different messages of different length. SPI master will enter LPM0 mode
// while waiting for the messages to be sent/receiving using SPI interrupt.
// SPI Master will initially wait for a port interrupt in LPM0 mode before
// starting the SPI communication.
// ACLK = NA, MCLK = SMCLK = DCO 16MHz.
//
//
// MSP430F5529
// -----------------
// /|\ | P2.0|-> Slave Chip Select (GPIO)
// | | |
// ---|RST P1.5|-> Slave Reset (GPIO)
// | |
// | P3.3|-> Data Out (UCA0SIMO)
// | |
// Button ->|P1.1 P3.4|<- Data In (UCA0SOMI)
// | |
// | P2.7|-> Serial Clock Out (UCA0CLK)
//
// Nima Eskandari
// Texas Instruments Inc.
// April 2017
// Built with CCS V7.0
//******************************************************************************
#include <msp430.h>
#include <stdint.h>
#include <stdbool.h>
//******************************************************************************
// Example Commands ************************************************************
//******************************************************************************
#define DUMMY 0xFF
#define SLAVE_CS_OUT P2OUT
#define SLAVE_CS_DIR P2DIR
#define SLAVE_CS_PIN BIT0
/* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
* The slave will send example SlaveTypeX buffers in response.
*
* CMD_TYPE_X_MASTER are example commands the master sends to the slave.
* The slave will initialize itself to receive MasterTypeX example buffers.
* */
#define CMD_TYPE_0_SLAVE 0
#define CMD_TYPE_1_SLAVE 1
#define CMD_TYPE_2_SLAVE 2
#define CMD_TYPE_0_MASTER 3
#define CMD_TYPE_1_MASTER 4
#define CMD_TYPE_2_MASTER 5
#define TYPE_0_LENGTH 1
#define TYPE_1_LENGTH 2
#define TYPE_2_LENGTH 6
#define MAX_BUFFER_SIZE 20
/* MasterTypeX are example buffers initialized in the master, they will be
* sent by the master to the slave.
* SlaveTypeX are example buffers initialized in the slave, they will be
* sent by the slave to the master.
* */
uint8_t MasterType0[TYPE_0_LENGTH] = {0x11};
uint8_t MasterType1[TYPE_1_LENGTH]= {8, 9};
uint8_t MasterType2[TYPE_2_LENGTH] = {'F', '4' , '1' , '9', '2', 'B'};
uint8_t SlaveType0[TYPE_0_LENGTH] = {0};
uint8_t SlaveType1[TYPE_1_LENGTH] = {0};
uint8_t SlaveType2[TYPE_2_LENGTH] = {0};
//******************************************************************************
// General SPI State Machine ***************************************************
//******************************************************************************
typedef enum SPI_ModeEnum{
IDLE_MODE,
TX_REG_ADDRESS_MODE,
RX_REG_ADDRESS_MODE,
TX_DATA_MODE,
RX_DATA_MODE,
TIMEOUT_MODE
} SPI_Mode;
/* Used to track the state of the software state machine*/
SPI_Mode MasterMode = IDLE_MODE;
/* The Register Address/Command to use*/
uint8_t TransmitRegAddr = 0;
/* ReceiveBuffer: Buffer used to receive data in the ISR
* RXByteCtr: Number of bytes left to receive
* ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
* TransmitBuffer: Buffer used to transmit data in the ISR
* TXByteCtr: Number of bytes left to transfer
* TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
* */
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;
/* SPI Write and Read Functions */
/* For slave device, writes the data specified in *reg_data
*
* reg_addr: The register or command to send to the slave.
* Example: CMD_TYPE_0_MASTER
* *reg_data: The buffer to write
* Example: MasterType0
* count: The length of *reg_data
* Example: TYPE_0_LENGTH
* */
SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
/* For slave device, read the data specified in slaves reg_addr.
* The received data is available in ReceiveBuffer
*
* reg_addr: The register or command to send to the slave.
* Example: CMD_TYPE_0_SLAVE
* count: The length of data to read
* Example: TYPE_0_LENGTH
* */
SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
void SendUCA0Data(uint8_t val);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
uint8_t copyIndex = 0;
for (copyIndex = 0; copyIndex < count; copyIndex++)
{
dest[copyIndex] = source[copyIndex];
}
}
SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
//Copy register data to TransmitBuffer
CopyArray(reg_data, TransmitBuffer, count);
TXByteCtr = count;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
SLAVE_CS_OUT &= ~(SLAVE_CS_PIN);
SendUCA0Data(TransmitRegAddr);
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
SLAVE_CS_OUT |= SLAVE_CS_PIN;
return MasterMode;
}
SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count)
{
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
RXByteCtr = count;
TXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
SLAVE_CS_OUT &= ~(SLAVE_CS_PIN);
SendUCA0Data(TransmitRegAddr);
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
SLAVE_CS_OUT |= SLAVE_CS_PIN;
return MasterMode;
}
void SendUCA0Data(uint8_t val)
{
while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = val;
}
//******************************************************************************
// Device Initialization *******************************************************
//******************************************************************************
void initClockTo16MHz()
{
UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO
UCSCTL4 |= SELA_2; // Set ACLK = REFO
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
UCSCTL2 = FLLD_0 + 487; // Set DCO Multiplier for 16MHz
// (N + 1) * FLLRef = Fdco
// (487 + 1) * 32768 = 16MHz
// Set FLL Div = fDCOCLK
__bic_SR_register(SCG0); // Enable the FLL control loop
// Worst-case settling time for the DCO when the DCO range bits have been
// changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
// UG for optimization.
// 32 x 32 x 16 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle
__delay_cycles(500000);//
// Loop until XT1,XT2 & DCO fault flag is cleared
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
}
uint16_t setVCoreUp(uint8_t level){
uint32_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
//The code flow for increasing the Vcore has been altered to work around
//the erratum FLASH37.
//Please refer to the Errata sheet to know if a specific device is affected
//DO NOT ALTER THIS FUNCTION
//Open PMM registers for write access
PMMCTL0_H = 0xA5;
//Disable dedicated Interrupts
//Backup all registers
PMMRIE_backup = PMMRIE;
PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
SVSLPE | SVMHVLRIE | SVMHIE |
SVSMHDLYIE | SVMLVLRIE | SVMLIE |
SVSMLDLYIE
);
SVSMHCTL_backup = SVSMHCTL;
SVSMLCTL_backup = SVSMLCTL;
//Clear flags
PMMIFG = 0;
//Set SVM highside to new level and check if a VCore increase is possible
SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
//Wait until SVM highside is settled
while((PMMIFG & SVSMHDLYIFG) == 0)
{
;
}
//Clear flag
PMMIFG &= ~SVSMHDLYIFG;
//Check if a VCore increase is possible
if((PMMIFG & SVMHIFG) == SVMHIFG)
{
//-> Vcc is too low for a Vcore increase
//recover the previous settings
PMMIFG &= ~SVSMHDLYIFG;
SVSMHCTL = SVSMHCTL_backup;
//Wait until SVM highside is settled
while((PMMIFG & SVSMHDLYIFG) == 0)
{
;
}
//Clear all Flags
PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
SVMLVLRIFG | SVMLIFG |
SVSMLDLYIFG
);
//Restore PMM interrupt enable register
PMMRIE = PMMRIE_backup;
//Lock PMM registers for write access
PMMCTL0_H = 0x00;
//return: voltage not set
return false;
}
//Set also SVS highside to new level
//Vcc is high enough for a Vcore increase
SVSMHCTL |= (SVSHRVL0 * level);
//Wait until SVM highside is settled
while((PMMIFG & SVSMHDLYIFG) == 0)
{
;
}
//Clear flag
PMMIFG &= ~SVSMHDLYIFG;
//Set VCore to new level
PMMCTL0_L = PMMCOREV0 * level;
//Set SVM, SVS low side to new level
SVSMLCTL = SVMLE | (SVSMLRRL0 * level) |
SVSLE | (SVSLRVL0 * level);
//Wait until SVM, SVS low side is settled
while((PMMIFG & SVSMLDLYIFG) == 0)
{
;
}
//Clear flag
PMMIFG &= ~SVSMLDLYIFG;
//SVS, SVM core and high side are now set to protect for the new core level
//Restore Low side settings
//Clear all other bits _except_ level settings
SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
SVSMLRRL1 + SVSMLRRL2
);
//Clear level settings in the backup register,keep all other bits
SVSMLCTL_backup &=
~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
//Restore low-side SVS monitor settings
SVSMLCTL |= SVSMLCTL_backup;
//Restore High side settings
//Clear all other bits except level settings
SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 +
SVSMHRRL0 + SVSMHRRL1 +
SVSMHRRL2
);
//Clear level settings in the backup register,keep all other bits
SVSMHCTL_backup &=
~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
//Restore backup
SVSMHCTL |= SVSMHCTL_backup;
//Wait until high side, low side settled
while(((PMMIFG & SVSMLDLYIFG) == 0) &&
((PMMIFG & SVSMHDLYIFG) == 0))
{
;
}
//Clear all Flags
PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
);
//Restore PMM interrupt enable register
PMMRIE = PMMRIE_backup;
//Lock PMM registers for write access
PMMCTL0_H = 0x00;
return true;
}
bool increaseVCoreToLevel2()
{
uint8_t level = 2;
uint8_t actlevel;
bool status = true;
//Set Mask for Max. level
level &= PMMCOREV_3;
//Get actual VCore
actlevel = PMMCTL0 & PMMCOREV_3;
//step by step increase or decrease
while((level != actlevel) && (status == true))
{
if(level > actlevel)
{
status = setVCoreUp(++actlevel);
}
}
return (status);
}
void initGPIO()
{
//LEDs
P1OUT = 0x00; // P1 setup for LED & reset output
P1DIR |= BIT0 + BIT5;
P4DIR |= BIT7;
P4OUT &= ~(BIT7);
//SPI Pins
P3SEL |= BIT3 + BIT4; // P3.3,4 option select
P2SEL |= BIT7; // P2.7 option select
//Button to initiate transfer
P1DIR &= ~BIT1; // Set P1.1 to inpput direction
P1REN |= BIT1; // Enable P1.1 internal resistance
P1OUT |= BIT1; // Set P1.1 as pull-Up resistance
P1IES |= BIT1; // P1.1 Hi/Lo edge
P1IFG &= ~BIT1; // P1.1 IFG cleared
P1IE |= BIT1; // P1.1 interrupt enabled
}
void initSPI()
{
//Clock Polarity: The inactive state is high
//MSB First, 8-bit, Master, 3-pin mode, Synchronous
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL0 |= UCCKPL + UCMSB + UCMST + UCSYNC;
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 |= 0x20; // /2
UCA0BR1 = 0; //
UCA0MCTL = 0; // No modulation must be cleared for SPI
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCRXIE; // Enable USCI0 RX interrupt
SLAVE_CS_DIR |= SLAVE_CS_PIN;
SLAVE_CS_OUT |= SLAVE_CS_PIN;
}
//******************************************************************************
// Main ************************************************************************
// Send and receive three messages containing the example commands *************
//******************************************************************************
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
increaseVCoreToLevel2();
initClockTo16MHz();
initGPIO();
initSPI();
P1OUT &= ~BIT5; // Now with SPI signals initialized,
__delay_cycles(100000);
P1OUT |= BIT5; // reset slave
__delay_cycles(100000); // Wait for slave to initialize
P1OUT |= BIT0;
__bis_SR_register(LPM0_bits + GIE); // CPU off, enable interrupts
SPI_Master_ReadReg(CMD_TYPE_2_SLAVE, TYPE_2_LENGTH);
CopyArray(ReceiveBuffer, SlaveType2, TYPE_2_LENGTH);
SPI_Master_ReadReg(CMD_TYPE_1_SLAVE, TYPE_1_LENGTH);
CopyArray(ReceiveBuffer, SlaveType1, TYPE_1_LENGTH);
SPI_Master_ReadReg(CMD_TYPE_0_SLAVE, TYPE_0_LENGTH);
CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
SPI_Master_WriteReg(CMD_TYPE_2_MASTER, MasterType2, TYPE_2_LENGTH);
SPI_Master_WriteReg(CMD_TYPE_1_MASTER, MasterType1, TYPE_1_LENGTH);
SPI_Master_WriteReg(CMD_TYPE_0_MASTER, MasterType0, TYPE_0_LENGTH);
__bis_SR_register(LPM0_bits + GIE);
__no_operation();
return 0;
}
//******************************************************************************
// SPI Interrupt ***************************************************************
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
uint8_t uca0_rx_val = 0;
switch(__even_in_range(UCA0IV,4))
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
uca0_rx_val = UCA0RXBUF;
switch (MasterMode)
{
case TX_REG_ADDRESS_MODE:
if (RXByteCtr)
{
MasterMode = RX_DATA_MODE; // Need to start receiving now
//Send Dummy To Start
__delay_cycles(2000000);
SendUCA0Data(DUMMY);
}
else
{
MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer
//Send First
SendUCA0Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
}
break;
case TX_DATA_MODE:
if (TXByteCtr)
{
SendUCA0Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
}
else
{
//Done with transmission
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break;
case RX_DATA_MODE:
if (RXByteCtr)
{
ReceiveBuffer[ReceiveIndex++] = uca0_rx_val;
//Transmit a dummy
RXByteCtr--;
}
if (RXByteCtr == 0)
{
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
else
{
SendUCA0Data(DUMMY);
}
break;
default:
__no_operation();
break;
}
__delay_cycles(1000);
break;
case 4:break; // Vector 4 - TXIFG
default: break;
}
}
//******************************************************************************
// PORT1 Interrupt *************************************************************
// Interrupt occurs on button press and initiates the SPI data transfer ********
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
#else
#error Compiler not supported!
#endif
{
P4OUT ^= BIT7; // P1.0 = toggle
P1IFG &= ~BIT1; // P1.1 IFG cleared
P1IE &= ~BIT1;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
ET 代码 CI dessous pour l'esclave:
MSP430F243x_eusci_spi_standard_slave.c
//******************************************************************************
// MSP430FR243x Demo - eUSCI_A1, 4-Wire SPI Slave multiple-byte RX/TX
//
// Description: SPI slave communicates with SPI master sending and receiving
// 3 different messages of different length. SPI slave will enter LPM0
// while waiting for the messages to be sent/received using SPI interrupt.
//
// ACLK = NA, MCLK = DCO = 16MHz, SMCLK = MCLK / 2 = 8MHz
//
//
// MSP430FR2433
// -----------------
// /|\ | RST|<- Master's GPIO (To reset slave)
// | | |
// ---|RST P2.6|<- Data In (UCA1SIMO)
// | |
// | P2.5|-> Data Out (UCA1SOMI)
// | |
// | P2.4|<- Serial Clock In (UCA1CLK)
// | |
// | P3.1|<- Master's GPIO (UCA1STE)
//
// James Evans
// Texas Instruments Inc.
// May 2021
// Built with CCS v10.3
//******************************************************************************
#include <msp430.h>
#include <stdint.h>
//******************************************************************************
// Pin Config ******************************************************************
//******************************************************************************
#define LED_OUT P1OUT
#define LED_DIR P1DIR
#define LED0_PIN BIT0
//******************************************************************************
// Example Commands ************************************************************
//******************************************************************************
#define DUMMY 0xFF
/* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
* The slave will send example SlaveTypeX buffers in response.
*
* CMD_TYPE_X_MASTER are example commands the master sends to the slave.
* The slave will initialize itself to receive MasterTypeX example buffers.
* */
#define CMD_TYPE_0_SLAVE 0
#define CMD_TYPE_1_SLAVE 1
#define CMD_TYPE_2_SLAVE 2
#define CMD_TYPE_0_MASTER 3
#define CMD_TYPE_1_MASTER 4
#define CMD_TYPE_2_MASTER 5
#define TYPE_0_LENGTH 1
#define TYPE_1_LENGTH 2
#define TYPE_2_LENGTH 6
#define MAX_BUFFER_SIZE 20
/* MasterTypeX are example buffers initialized in the master, they will be
* sent by the master to the slave.
* SlaveTypeX are example buffers initialized in the slave, they will be
* sent by the slave to the master.
* */
uint8_t MasterType2 [TYPE_2_LENGTH] = {0};
uint8_t MasterType1 [TYPE_1_LENGTH] = {0, 0};
uint8_t MasterType0 [TYPE_0_LENGTH] = {0};
uint8_t SlaveType2 [TYPE_2_LENGTH] = {'A', 'B', 'C', 'D', '1', '2'};
uint8_t SlaveType1 [TYPE_1_LENGTH] = {0x15, 0x16};
uint8_t SlaveType0 [TYPE_0_LENGTH] = {12};
//******************************************************************************
// General SPI State Machine ***************************************************
//******************************************************************************
typedef enum SPI_ModeEnum{
IDLE_MODE,
TX_REG_ADDRESS_MODE,
RX_REG_ADDRESS_MODE,
TX_DATA_MODE,
RX_DATA_MODE,
TIMEOUT_MODE
} SPI_Mode;
/* Used to track the state of the software state machine*/
SPI_Mode SlaveMode = RX_REG_ADDRESS_MODE;
/* The Register Address/Command to use*/
uint8_t ReceiveRegAddr = 0;
/* ReceiveBuffer: Buffer used to receive data in the ISR
* RXByteCtr: Number of bytes left to receive
* ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
* TransmitBuffer: Buffer used to transmit data in the ISR
* TXByteCtr: Number of bytes left to transfer
* TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
* */
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;
/* Initialized the software state machine according to the received cmd
*
* cmd: The command/register address received
* */
void SPI_Slave_ProcessCMD(uint8_t cmd);
/* The transaction between the slave and master is completed. Uses cmd
* to do post transaction operations. (Place data from ReceiveBuffer
* to the corresponding buffer based in the last received cmd)
*
* cmd: The command/register address corresponding to the completed
* transaction
*/
void SPI_Slave_TransactionDone(uint8_t cmd);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
void SendUCA1Data(uint8_t val);
void SendUCA1Data(uint8_t val)
{
while (!(UCA1IFG & UCTXIFG)); // USCI_A1 TX buffer ready?
UCA1TXBUF = val;
}
void SPI_Slave_ProcessCMD(uint8_t cmd)
{
ReceiveIndex = 0;
TransmitIndex = 0;
RXByteCtr = 0;
TXByteCtr = 0;
switch (cmd)
{
// Send slave device ID (this device's ID)
case (CMD_TYPE_0_SLAVE):
SlaveMode = TX_DATA_MODE;
TXByteCtr = TYPE_0_LENGTH;
// Fill out the TransmitBuffer
CopyArray(SlaveType0, TransmitBuffer, TYPE_0_LENGTH);
// Send next byte
SendUCA1Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
break;
// Send slave device time (this device's time)
case (CMD_TYPE_1_SLAVE):
SlaveMode = TX_DATA_MODE;
TXByteCtr = TYPE_1_LENGTH;
// Fill out the TransmitBuffer
CopyArray(SlaveType1, TransmitBuffer, TYPE_1_LENGTH);
// Send next byte
SendUCA1Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
break;
// Send slave device location (this device's location)
case (CMD_TYPE_2_SLAVE):
SlaveMode = TX_DATA_MODE;
TXByteCtr = TYPE_2_LENGTH;
// Fill out the TransmitBuffer
CopyArray(SlaveType2, TransmitBuffer, TYPE_2_LENGTH);
// Send next byte
SendUCA1Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
break;
case (CMD_TYPE_0_MASTER):
SlaveMode = RX_DATA_MODE;
RXByteCtr = TYPE_0_LENGTH;
break;
case (CMD_TYPE_1_MASTER):
SlaveMode = RX_DATA_MODE;
RXByteCtr = TYPE_1_LENGTH;
break;
case (CMD_TYPE_2_MASTER):
SlaveMode = RX_DATA_MODE;
RXByteCtr = TYPE_2_LENGTH;
break;
default:
__no_operation();
break;
}
}
void SPI_Slave_TransactionDone(uint8_t cmd)
{
switch (cmd)
{
// Slave device ID was sent (this device's ID)
case (CMD_TYPE_0_SLAVE):
break;
// Slave device time was sent (this device's time)
case (CMD_TYPE_1_SLAVE):
break;
// Slave device location was sent (this device's location)
case (CMD_TYPE_2_SLAVE):
break;
case (CMD_TYPE_0_MASTER):
CopyArray(ReceiveBuffer, MasterType0, TYPE_0_LENGTH);
break;
case (CMD_TYPE_1_MASTER):
CopyArray(ReceiveBuffer, MasterType1, TYPE_1_LENGTH);
break;
case (CMD_TYPE_2_MASTER):
CopyArray(ReceiveBuffer, MasterType2, TYPE_2_LENGTH);
break;
default:
__no_operation();
break;
}
}
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
uint8_t copyIndex = 0;
for (copyIndex = 0; copyIndex < count; copyIndex++)
{
dest[copyIndex] = source[copyIndex];
}
}
//******************************************************************************
// Device Initialization *******************************************************
//******************************************************************************
void initSPI()
{
// Clock polarity select: inactive state is high, MSB first
// 8-bit data, Synchronous, Slave mode, 4-pin SPI
UCA1CTLW0 = UCSWRST; // **Put eUSCI module in reset**
UCA1CTLW0 |= UCCKPL | UCMSB | UCSYNC |
UCMODE_2;
UCA1CTLW0 &= ~UCSWRST; // **Initialize eUSCI module**
UCA1IE |= UCRXIE; // Enable eUSCI0 RX interrupt
}
void initGPIO()
{
// Configure LEDs
LED_OUT &= ~LED0_PIN;
LED_DIR |= LED0_PIN;
// Configure eUSCI pins
P2SEL0 |= BIT4 | BIT5 | BIT6;
P2SEL1 &= ~(BIT4 | BIT5 | BIT6);
P3SEL0 |= BIT1;
P3SEL1 &= ~BIT1;
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
}
void initClockTo16MHz()
{
// Configure one FRAM waitstate as required by the device datasheet for MCLK
// operation beyond 8MHz _before_ configuring the clock system.
FRCTL0 = FRCTLPW | NWAITS_1;
__bis_SR_register(SCG0); // Disable FLL
CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
CSCTL0 = 0; // Clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_5; // Set DCO = 16MHz
CSCTL2 = FLLD_0 + 487; // set to fDCOCLKDIV = (FLLN + 1)*(fFLLREFCLK/n)
// = (487 + 1)*(32.768 kHz/1)
// = 16MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // Enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // FLL locked
CSCTL5 |= DIVM_0 | DIVS_1; // MCLK = DCOCLK = 16MHz,
// SMCLK = MCLK/2 = 8MHz
}
//******************************************************************************
// Main ************************************************************************
// Enters LPM0 and waits for SPI interrupts. The data sent from the master is *
// then interpreted and the device will respond accordingly *
//******************************************************************************
int main(void)
{
// Stop watchdog timer
WDTCTL = WDTPW | WDTHOLD;
// Initialize device
initClockTo16MHz();
initGPIO();
initSPI();
// Enter LPM0 w/interrupts enabled
__bis_SR_register(LPM0_bits + GIE);
__no_operation();
return 0;
}
//******************************************************************************
// SPI Interrupt ***************************************************************
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A1_VECTOR))) USCI_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
uint8_t uca1_rx_val = 0;
switch(__even_in_range(UCA1IV, USCI_SPI_UCTXIFG))
{
case USCI_NONE: break;
case USCI_SPI_UCRXIFG:
uca1_rx_val = UCA1RXBUF;
UCA1IFG &= ~UCRXIFG;
switch (SlaveMode)
{
case (RX_REG_ADDRESS_MODE):
ReceiveRegAddr = uca1_rx_val;
SPI_Slave_ProcessCMD(ReceiveRegAddr);
break;
case (RX_DATA_MODE):
// Store received byte
ReceiveBuffer[ReceiveIndex++] = uca1_rx_val;
RXByteCtr--;
if (RXByteCtr == 0)
{
// Done with reception
SlaveMode = RX_REG_ADDRESS_MODE;
SPI_Slave_TransactionDone(ReceiveRegAddr);
}
break;
case (TX_DATA_MODE):
if (TXByteCtr > 0)
{
// Send additional byte
SendUCA1Data(TransmitBuffer[TransmitIndex++]);
TXByteCtr--;
}
if (TXByteCtr == 0)
{
// Done with transmission
SlaveMode = RX_REG_ADDRESS_MODE;
SPI_Slave_TransactionDone(ReceiveRegAddr);
}
break;
default:
__no_operation();
break;
}
break;
case USCI_SPI_UCTXIFG:
break;
default: break;
}
}
reçu è re a bien effectuer et savoir quels ont ont les donn é es qui ont transmise et reçu è s é t é t é t é t é t é t é t é t é t é t é et souvernir é t é t é t é s é t é t é t é t é t é t é s
感谢 Vos Retours
Code composer Studio 的 Je travaille
感谢 Vos Retours
Code composer Studio 的 Je travaille