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.

[参考译文] MSP430G2553:16位 SPI 帧 RX/TX U

Guru**** 2551110 points
Other Parts Discussed in Thread: MSP430G2553

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/806466/msp430g2553-16-bit-spi-frame-rx-tx-u

器件型号:MSP430G2553

您好!  

我能否使用以下示例演示代码通过 MSP430G2553发送/接收16位 SPI 帧?

此演示代码来自适用于 MSP430G2553器件的 TI CCS 云资源。

//
// MSP430G2xx3演示- USCI_A0、SPI 3线制主器件多字节 RX/TX
//
//说明:SPI 主设备与 SPI 从设备通信发送和接收
// 3条不同长度的消息。 SPI 主器件将进入 LPM0模式
//等待使用 SPI 中断发送/接收消息时。
// SPI 主设备将在之前的 LPM0模式中最初等待端口中断
//开始 SPI 通信。
// ACLK = nA、MCLK = SMCLK = DCO 16MHz。
//
//
// MSP430G2553
//------------
///|\| P2.0|->从器件芯片选择(GPIO)
//|||
//--|RST P1.5|->从器件复位(GPIO)
//||
//| P1.2|->数据输出(UCA0SIMO)
//||
//按钮-|P1.3 P1.1|<-数据输入(UCA0SOMI)
//||
//| P1.4|->串行时钟输出(UCA0CLK)
//
// Nima Eskandari
// Texas Instruments Inc.
// 2017年4月
//使用 CCS V7.0构建
//

#include
#include

//
//示例命令(Example Commands Commands
//

#define 虚拟0xFF

#define SLAVE_CS_OUT P2OUT
#define SLAVE_CS_DIR P2DIR
#define SLAVE_CS_PIN BIT0

/* CMD_TYPE_X_SLAVE 是主设备发送到从设备的示例命令。
*从属方将发送示例 SlaveTypeX 缓冲区进行响应。
*
* CMD_TYPE_X_MASTER 是主器件发送到从器件的示例命令。
*从器件将初始化自身以接收 MasterTypeX 示例缓冲区。
***/

#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 是在主设备中初始化的示例缓冲区,它们将是
*由主器件发送到从器件。
* SlaveTypeX 是在从器件中初始化的示例缓冲区,它们将是
*由从器件发送到主器件。
***/

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 SlaveType2 [type_2_length]={0};
uint8_t SlaveType1 [type_1_length]={0};
uint8_t SlaveType0 [type_0_length]={0};

//
//通用 SPI 状态机
//

typedef 枚举 SPI_ModeEnum{
IDLE_MODE、
TX_REG_ADDRESS_MODE、
RX_REG_ADDRESS_MODE、
TX_DATA_MODE、
RX_DATA_MODE、
TIMEOUT_MODE
} SPI_Mode;

/*用于跟踪软件状态机的状态*/
SPI_Mode MasterMode = IDLE_MODE;

/*要使用的寄存器地址/命令*/
uint8_t TransmitRegAddr = 0;

/* ReceiveBuffer:用于在 ISR 中接收数据的缓冲区
* RXByteCtr:剩余要接收的字节数
* ReceiveIndex:ReceiveBuffer 中要接收的下一个字节的索引
* TransmitBuffer:用于在 ISR 中传输数据的缓冲区
* TXByteCtr:剩余要传输的字节数
* TransmitIndex:要在 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 写入和读取函数*/

//对于从属设备,写入*reg_data 中指定的数据
*
* reg_addr:要发送到从器件的寄存器或命令。
*示例:CMD_TYPE_0_MASTER
**REG_DATA:要写入的缓冲区
*示例:MasterType0
* count:* reg_data 的长度
*示例:type_0_length
***/
SPI_Mode SPI_Master_WriteReg (uint8_t reg_addr、uint8_t * reg_data、uint8_t count);

/*对于从器件,读取从器件 REG_addr 中指定的数据。
*接收到的数据在 ReceiveBuffer 中可用
*
* reg_addr:要发送到从器件的寄存器或命令。
*示例:CMD_TYPE_0_SLAVE
* count:要读取的数据长度
*示例:type_0_length
***/
SPI_Mode SPI_Master_ReadReg (uint8_t reg_addr、uint8_t count);
void CopyArray (uint8_t *源、uint8_t * dest、uint8_t count);
void SendUCA0Data (uint8_t val);

void CopyArray (uint8_t *源、uint8_t *目标、uint8_t 计数)

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;

//将寄存器数据复制到 TransmitBuffer
CopyArray (reg_data、TransmitBuffer、count);

TXByteCtr =计数;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;

Slave_CS_OUT &=~(SLAVE_CS_PIN);
SendUCA0Data (TransmitRegAddr);

_bis_SR_register (CPUOFF + GIE);//输入 LPM0、带中断

SLAVE_CS_OUT |= SLAVE_CS_PIN;
返回 MasterMode;

SPI_Mode SPI_Master_ReadReg (uint8_t reg_addr、uint8_t count)

MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
RXByteCtr =计数;
TXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;

Slave_CS_OUT &=~(SLAVE_CS_PIN);
SendUCA0Data (TransmitRegAddr);

_bis_SR_register (CPUOFF + GIE);//输入 LPM0、带中断

SLAVE_CS_OUT |= SLAVE_CS_PIN;
返回 MasterMode;

void SendUCA0Data (uint8_t val)

while (!(IFG2 & UCA0TXIFG));// USCI_A0 TX 缓冲器准备就绪?
UCA0TXBUF = val;

//
//设备初始化
//

空 initClockTo16MHz()

IF (CALBC1_16MHz=0xFF)//如果校准常数被擦除

while (1);//请勿加载,陷阱 CPU!!

DCOCTL = 0;//选择最低 DCOx 和 MODx 设置
BCSCTL1 = CALBC1_16MHz;//设置 DCO
DCOCTL = CALDCO_16MHz;

空 initGPIO()

//LED
P1OUT = 0x00;//针对 LED 和复位输出设置 P1
P1DIR |= BIT0 + BIT5 + BIT6;

//SPI 引脚
P1SEL = BIT1 + BIT2 + BIT4;
P1SEL2 = BIT1 + BIT2 + BIT4;

//按钮启动传输
P1DIR &=~(BIT3);
P1OUT |= BIT3;// P1.3上拉
P1REN |= BIT3;// P1.3上拉/下拉电阻使能
P1IE |= BIT3;// P1.3中断被启用
P1IES |= BIT3;// P1.3高/低边沿
P1IFG &=~BIT3;// P1.3 IFG 被清零

空 initSPI()

//时钟极性:无效状态为高电平
//MSB 优先、8位、主器件、3引脚模式、同步
UCA0CTL0 |= UCCKPL + UCMSB + UCMST + UCSYNC;
UCA0CTL1 |= UCSSEL_2;// SMCLK
UCA0BR0 |= 0x20;///2
UCA0BR1 = 0;//
UCA0MCTL = 0;// SPI 必须清除无调制
UCA0CTL1 &=~UCSWRST;//**初始化 USCI 状态机**
IE2 |= UCA0RXIE;//启用 USCI0 RX 中断

SLAVE_CS_DIR |= SLAVE_CS_PIN;
SLAVE_CS_OUT |= SLAVE_CS_PIN;

//
//主要内容
//发送和接收三条包含示例命令*******的消息
//

int main (空)

WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器

initClockTo16MHz();
initGPIO();
initspi();

P1OUT &=~BIT4;//现在 SPI 信号已初始化、
_DELAY_CYCLES (100000);
P1OUT |= BIT5;//复位从器件
_DELAY_CYCLES (100000);//等待从器件初始化

P1OUT |= BIT0;

_bis_SR_register (LPM0_bits + GIE);// CPU 关闭、启用中断

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);

//
// SPI 中断
//

#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector=USCIAB0RX_vector
_interrupt void USCIA0RX_ISR (void)
#Elif defined (_GNU_)
void __attribute__((interrupt (USCIAB0RX_vector)) USCIA0RX_ISR (void)
其他
错误编译器不受支持!
#endif

IF (IFG2 & UCA0RXIFG)

uint8_t uca0_rx_val = UCA0RXBUF;
开关(主模式)

案例 TX_REG_ADDRESS_MODE:
IF (RXByteCtr)

MasterMode = RX_DATA_MODE;//需要立即开始接收
//发送虚拟到开始
_DELAY_CYCLES (2000);
SendUCA0Data (虚拟);

其他

MasterMode = TX_DATA_MODE;//继续转换发送缓冲区中的数据
//首先发送
SendUCA0Data (TransmitBuffer[TransmitIndex++]);
TXByteCtr --;

中断;

案例 TX_DATA_MODE:
IF (TXByteCtr)

SendUCA0Data (TransmitBuffer[TransmitIndex++]);
TXByteCtr --;

其他

//传输完成
MasterMode = IDLE_MODE;
_BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0

中断;

RX_DATA_MODE case:
IF (RXByteCtr)

ReceiveBuffer[ReceiveIndex++]= uca0_Rx_val;
//发送虚拟
RXByteCtr---;

IF (RXByteCtr = 0)

MasterMode = IDLE_MODE;
_BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0

其他

SendUCA0Data (虚拟);

中断;

默认值:
__no_operation();
中断;

_DELAY_CYCLES (50);


//
//端口1中断
//按下按钮时发生中断并启动 SPI 数据传输****
//

#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector=Port1_vector
_interrupt void Port_1 (void)
#Elif defined (_GNU_)
void __attribute__((interrupt (Port1_vector))) Port_1 (void)
其他
错误编译器不受支持!
#endif

P1OUT |= BIT6;
P1IFG &=~BIT3;// P1.3 IFG 被清零
P1IE &=~BIT3;
//启动
_BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出 LPM0

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Shashankk

    该演示可以发送16位数据。 因为 TX 缓冲区是8位、所以它将发送两次。

    此致
    Gary