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.

[参考译文] TRF7960:TRF7960没有响应

Guru**** 2587365 points
Other Parts Discussed in Thread: MSP-EXP430F5529LP, TRF7960

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

https://e2e.ti.com/support/wireless-connectivity/other-wireless-group/other-wireless/f/other-wireless-technologies-forum/671021/trf7960-trf7960-does-not-respond

器件型号:TRF7960
主题中讨论的其他器件:MSP-EXP430F5529LP

您好!


我根据 TI 应用手册设计了一个使用 TRF7960的电路板。 为了进行测试、我使用 MSP-EXP430F5529LP。

我可以通过 MOSI 向 TRF7960发送数据。  但没有反应。


Screenshot_1

(单击放大)

这是示波器屏幕:

20180312_162542

(单击放大)

和代码:  

抱歉、我认为代码插入不能正常工作 



//
// MSP430F552x 演示- USCI_A0、SPI 3线主控多字节 RX/TX
//
说明:SPI 主控器与 SPI 受控器通信发送和接收
// 3个不同长度的消息。 SPI 主器件将在
等待使用 SPI 中断发送/接收消息时进入 LPM0模式//。
//在
开始 SPI 通信之前,SPI 主设备将在 LPM0模式下最初等待端口中断。
// ACLK = nA、MCLK = SMCLK = DCO 16MHz。
//
//
//////// MSP430F5529
// --------
// /|\| P2.0|->从器件芯片选择(GPIO)
// || |
// ---|RST
// | |
// | P3.3|->数据输出(UCA0SIMO)
// | |
// 按钮->|P1.1 P3.4|<-数据输入(UCA0SOMI)
// | |
// | P2.7|->串行时钟输出(UCA0CLK)
//

*********

#include 
#include 
#include 


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

#define 虚拟0xFF

#define SLAVE_SELECT_DIR P2DIR |= BIT0
#define CHIP_STATE_CONTROL 0x00
#define SLAVE_SELECT_LOW P2OUT &=~BIT0
#define SLAVE_SELECT_HIGH P2OUT |= BIT0
uint8_t temp = 0;
uint8_t command[2];



// 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]={0x55};
uint8_t MasterType1[type_1_length]={8、9};
uint8_t MasterType2[type_2_length]={'F'、'4'、'1'、'9'、'2'、 'b'};

uint8_t useType0[type_0_length]={0};
uint8_t SlaveType1[type_1_length]={0};
uint8_t SlaveType2[type_2_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 中接收数据的缓冲区
* RXIndex ByteCtr:剩余要接收的字节数
*: 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;

//

*对于从设备,*//*将数据写入

到* reg_slave 命令:*。
* 示例:CMD_TYPE_0_MASTER
** REG_DATA:要写入的缓冲
区* 示例:MasterType0
* count:* reg_data
*的长度 示例:TYPE_0_LENGTH
*/






//*********
//设备初始化
//

void initClockTo16MHz()
{
UCSCTL3 |= SELREF_2; //设置 DCO FLL 基准= REFO
UCSCTL4 |= SE拉美 经济体系2; //设置 ACLK = REFO
_bis_SR_register (SCG0); //禁用 FLL 控制环路
UCSCTL0 = 0x0000; //设置可能的最低 DCOx、MODx
UCSCTL1 = DCORSEL_5; //选择 DCO 范围16MHz 操作
UCSCTL2 = FLLD_0 + 487; //将 DCO 乘法器设置为16MHz
//(N + 1)* FLLRef = Fdco
//(487 + 1)* 32768 = 16MHz
//设置 FLL Div = fDCOCLK
_BIC_SR_register (SCG0); //启用 FLL 控制环路

// DCO 范围位已经存在时、DCO 的最坏情况稳定时间
//已更改 n x 32 x 32 x f_MCLK / f_FLL_reference。 请参阅5xx 中的 UCS 一章
// UG 进行优化。
// 32 x 32 x 16 MHz/32、768Hz = 500000 = DCO 稳定的 MCLK 周期
_DELAY_CYCLES (50000);//
//循环直到 XT1、XT2和 DCO 故障标志被清除
操作
{
UCSCTL7 &=~(XT2OFFG + XT1LFOFFG + DCOFFG);//清除 XT2、XT1、DCO 故障标志
SFRIFG1 &=~OFIFG; //清除故障标志
} while (SFRIFG1&OFIFG); //测试振荡器故障标志
}

uint16_t setVCoreUp (uint8_t level){
uint32_t PMMRIE_BACKUP、SVSMHCTL_BACKUP、SVSMLCTL_BACKUP;

//增加 Vcore 的代码流已被修改为有效
//勘 误表 FLASH37。
//请参阅勘误表以了解特定器件是否受到影响
//不要更改此功能

//打开 PMM 寄存器进行写访问
PMMCTL0_H = 0xA5;

//禁用专用中断
//备份所有寄存器
PMMRIE_BACKUP = PMMRIE;
PMMRIE &=~(SVMHVLRPE | SVSHPE | SVMLVLRPE |
SVSLPE | SVMHVLRIE | SVMHIE |
SVSMHDLYIE | SVMLVLRIE | SVMLIE |
SVSMLDLYIE
);
SVSMHCTL_BACKUP = SVSMHCTL;
SVSMLCTL_BACKUP = SVSMLCTL;

//清除标志
PMMIFG=0;

//set SVM highside to new level and check if a VCORE increase is possible
SVSMHCTL = SVMHE | SVSHE |(SVSMHRRL0 *电平);

//等待 SVM 高侧稳定
while (((PMMIFG & SVSMHDLYIFG)=0)
{
;
}

//清除标志
PMMIFG &=~SVSMHDLYIFG;

//检查是否可以增加 VCORE
if ((PMMIFG & SVMHIFG)== SVMHIFG)
{
//->Vcc 对于 Vcore 增加来说太低
//恢复以前的设置
PMMIFG &=~SVSMHDLYIFG;
SVSMHCTL = SVSMHCTL_BACKUP;

//等待 SVM 高侧稳定
while (((PMMIFG & SVSMHDLYIFG)=0)
{
;
}

//清除所有标志
PMMIFG &=~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
SVMLVLRIFG | SVMLIFG |
SVSMLDLYIFG
);

//恢复 PMM 中断使能寄存器
PMMRIE = PMMRIE_BACKUP;
//锁定 PMM 寄存器以进行写访问
PMMCTL0_H = 0x00;
//返回:未设置电压
返回 false;
}

//set also SVS highside to new leve.(//将 SVS 高侧设置为新的水平。
//Vcc 足够高、足以使 Vcore 增加
SVSMHCTL |=(SVSHRVL0 *电平);

//等待 SVM 高侧稳定
while (((PMMIFG & SVSMHDLYIFG)=0)
{
;
}

//清除标志
PMMIFG &=~SVSMHDLYIFG;

//将 VCORE 设置为新的电平
PMMCTL0_L = PMMCOREV0 *电平;

//将 SVM、SVS 低电平侧设置为新的电平
SVSMLCTL = SVMLE |(SVSMLRRL0 *电平)|
SVSLE |(SVSLRVL0 *级别);

//等待 SVM、SVS 低电平侧稳定
while (((PMMIFG & SVSMLDLYIFG)=0)
{
;
}

//清除标志
PMMIFG &=~SVSMLDLYIFG;
//SVS、SVM 内核和高侧现在被设置为针对新的内核级别进行保护

//恢复低侧设置
//清除所有其他位_exbel_级别设置
SVSMLCTL &=(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 +
SVSMLRRL1 + SVSMLRRL2
);

//清除备份寄存器中的级别设置,保留所有其它位
SVSMLCTL_BACKUP &=
~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);

//恢复低电平侧 SVS 监视器设置
SVSMLCTL |= SVSMLCTL_BACKUP;

//恢复高侧设置
//清除除级别设置之外的所有其他位
SVSMHCTL &=(SVSHRVL0 + SVSHRVL1 +
SVSMHRRL0 + SVSMHRRL1 +
SVSMHRRL2
);

//清除备份寄存器中的级别设置,保留所有其它位
SVSMHCTL_BACKUP &=
~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);

//恢复备份
SVSMHCTL |= SVSMHCTL_BACKUP;

//等待高侧、低侧稳定
while ((((PMMIFG & SVSMLDLYIFG)=0)&&
((PMMIFG & SVSMHDLYIFG)=0))
{
;
}

//清除所有标志
PMMIFG &=~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG |
SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG
);

//恢复 PMM 中断使能寄存器
PMMRIE = PMMRIE_BACKUP;

//锁定 PMM 寄存器以进行写访问
PMMCTL0_H = 0x00;

返回 true;
}

bool increaseVCoreToLevel2()
{
uint8_t level = 2;
uint8_t actlevel;
bool status = true;

//为最大值设置掩码 电平
Level &= PMMCOREV_3;

//获取实际 VCORE
actlevel = PMMCTL0和 PMMCOREV_3;

//逐步增加或减少
while ((level!= actlevel)&&(status = true))
{
if (级别> actlevel)
{
状态= setVCoreUp (++actlevel);
}
}

返回(状态);
}

void initGPIO()
{
//LEDs
P1OUT = 0x00; //针对 LED 和复位输出的 P1设置
P1DIR |= BIT0 | BIT4;

P4DIR |= BIT7;
P4OUT &=~(BIT4);

P2OUT = 0x00;
P2DIR |= BIT0; // SS

//SPI 引脚
P3SEL |= BIT3 | BIT4; // P3.3、4选项选择
P2SEL |= BIT7; // P2.7选项选择

//按钮启动传输
P1DIR &=~BIT1; //将 P1.1设置为输入方向
P1REN |= BIT1; //启用 P1.1内部电阻
P1OUT |= BIT1; //将 P1.1设置为上拉电阻
P1IES |= BIT1; // P1.1高/低边沿
P1IFG &=~BIT1; // P1.1 IFG 清除
P1IE |= BIT1; //启用 P1.1中断
}

void UartInit(void){

//始终使用的 USCI 一章中列出的分步初始化过程
// F5xx 系列用户指南
UCA1CTL1 |= UCSWRST; //将 USCI 状态机复位
UCA1CTL1 |= UCSSEL_SMCLK;//使用 SMCLK 作为位时钟

//设置波特率
UCA1BR0 = 17;
UCA1BR1 = 0;
UCA1MCTL =(6 << 4)|(0 << 1)|(1);

P4SEL |= BIT4+BIT5; //将这些引脚配置为 TXD/RXD

UCA1CTL1 &=~UCSWRST; //使 USCI 退出复位状态
UCA1IE |= UCRXIE; //启用 RX 中断。 现在、当字节为时
// rcv'ed、将生成 USCI_A1矢量
。}

void UartSendChar (char ch)
{
while (!(UCTXIFG==(UCTXIFG & UCA1IFG))&&(((UCA1STAT & UCBUSY)=UCBUSY));
UCA1TXBUF =(ch & 0x1FF);
}

void UartSendString (char * str)
{
while (* str!= 0)
{
UartSendChar (* str);
STR++;
}
}

void SendUCA0Data (uint8_t val)
{
while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX 缓冲器就绪?
UCA0TXBUF = val;
}

void initSPI ()
{
UCA0CTL1 |= UCSWRST; //**将状态机复位**
UCA0CTL0 |= UCCKPH | UCMSB | UCMST | UCSYNC; //MSB 优先、8位、主器件、3引脚模式、同步
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 |= 8; // SPI 时钟频率= SMCLK / 8
UCA0BR1 = 0; //
UCA0MCTL = 0; //对于 SPI
SLAVE_SELECT_DIR、
SLAVE_SELECT_HIGH、
UCA0CTL1 &=~UCSWRST、不得清除调制; //**初始化 USCI 状态机**//UCA0IE

|= UCRXIE; //启用 USCI0 RX 中断
}

void SpiStartCondition (void) //Make the SCLK High
{
P2SEL &=~ BIT7;
P2DIR |= BIT7;
P2OUT |= BIT7; //make SCLK High
}

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

void SpiWriteSingle (uint8_t * pbuf、uint8_t length)
{
unsigned char i = 0;

Slave_select_low; //启动 SPI 模式

while (length > 0)
{
//地址/命令字位分布
//地址、写入、单个(前3位= 0)
*pbuf =(0x1f &*pbuf); //寄存器地址
对于(I = 0;I < 2;I++)
{

while (!(UCA0IFG & UCTXIFG)); // USCI_A0 TX 缓冲器就绪?
{
;
}
UCA0TXBUF =*pbuf; //以前发送到 TX、RX 的数据

while (UCA0STAT 和 UCBUSY)
{
;
}

温度= UCA0TXBUF;

pbuf++;
length--;
}
}
while (UCA0STAT 和 UCBUSY)
{
;
}

SLAVE_SELECT_HIGH; //停止 SPI 模式

}

void SpiReadSingle (uint8_t * pbuf、uint8_t number)
{
Slave_select_low; //启动 SPI 模式
while (数字> 0)
{
//地址/命令字位分布
*pbuf =(0x40 |*pbuf); //地址、读取、单个
*pbuf =(0x5f &*pbuf); //寄存器地址

while (!(UCA0IFG & UCTXIFG)) // USCI_B0 TX 缓冲器就绪?
{
;
}
UCA0TXBUF =*pbuf; //以前发送到 TX、RX 的数据

while (UCA0STAT 和 UCBUSY)
{
;
}

TEMP=UCA0RXBUF;

UCA0CTL1 |= UCSWRST; //**将状态机置于重置中**
UCA0CTL0 &=~UCCKPH;
UCA0CTL1 &=~UCSWRST;

SpiStartCondition();
P2SEL |= BIT7;

while (!(UCA0IFG & UCTXIFG)) // USCI_B0 TX 缓冲器就绪?
{
;
}
UCA0TXBUF = 0x00; //由虚拟 TX 写入启动的接收????

while (!(UCA0IFG & UCRXIFG)) // USCI_B0 RX 缓冲器准备好了吗?
{
;
}

_NOP();
_NOP();
*pbuf = UCA0RXBUF;
UartSendChar (* pbuf);
pbuf++;
编号--;

UCA0CTL0 |= UCCKPH;//恢复到原始时钟极性

}
while (UCA0STAT 和 UCBUSY)
{
;
}
SLAVE_SELECT_HIGH; //停止 SPI 模式
}


void Trf796xTurnRfOn (void){
命令[0]= CHIP_STACE_CONTROL;
COMMAN[1]= CHIP_STATE_CONTROL;
SpiReadSingle (&command[1]、1);
// command[1]&= 0x3F;
// command[1]|= 0x20;
// SpiWriteSingle (command、2);
}

void Trf796xInitialSettings (void)
{
uint8_t mod_control[4];

MOD_CONTRAIN[0]= 0x09;
MOD_CONTRAIN[1]= 0x21; // 6.78MHz、OOK 100%

SpiWriteSingle (mod_control、2);
}

void
Iso15693FindTag (void)
{
Trf796xTurnRfOn();

//Trf796xWriteIsoControl (0x02);

//激活 VCD 后,VCD 应至少等待1 ms
//在向发送第一个请求之前为字段供电
//确保 VICC 已准备好接收它。 (ISO15693-3)
// McuDelayMillisecond (1);

//flags =十六个插槽;

//buf[20]= 0x00;
// Iso15693Anticollersion (&buf[20]、0); //发送库存请求

// Trf796xTurnRfOff ();

// Trf796xResetIrqStatus();
//清除所有 IRQ
}



int main (void){
WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

increaseVCoreToLevel2();
initClockTo16MHz();
initGPIO();
initSPI();
UartInit();

P1DIR = 1<<0;
P4DIR = 1<<7;

P1OUT &=~BIT4; //现在初始化 SPI 信号,
//_delay_cycles (100000);
P1OUT |= BIT5; //重置从
器件//__delay_cycles (100000); //等待从机初始化

Trf796xInitialSettings();
Trf796xTurnRfOn();

UartSendString ("Start\r\n");
while (1){
//uart_print ("aa");
Trf796xTurnRfOn();

//SpiReadSingle (0x6C、1);




/*__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);
__no_operation();

P1OUT ^=(1<0);
_DELAY_CYCLES (10000000);
P4OUT ^(1<<7);

}
//


*********
// SPI 中断
//

#if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_)
#pragma vector=USCI_A0_vector
__interrupt void USCI_A0_ISR (void)
#Elif defined (__GNU__)
void __attribute__(interrupt (USCI_A1_vector))#USCI_A0

Compiler #a0_aid!
#endif
{
uint8_t uca0_rx_val = 0;
switch (_even_in_range (UCA0IV、4))
{
情况0:中断; //向量0 -无中断
案例2: //向量2 - RXIFG
UCA0_Rx_val = UCA0RXBUF;
开关(主模式)
{
案例 TX_REG_ADDRESS_MODE:
IF (RXByteCtr)
{
MasterMode = RX_DATA_MODE;//需要立即开始接收
//发送虚拟到开始
_DELAY_CYCLES (2000000);
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 (1000);
中断;
案例4:中断; //向量4 - TXIFG
默认值:中断
;}
//


*********
//端口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 (void)
#ele!

#endif
{
P4OUT ^= BIT7; // P1.0 =切换
P1IFG &=~BIT1; // P1.1 IFG 清除
P1IE &&~BIT1;
__BIC_SR_REGISTER_ON_EXIT (CPUOFF); //退出 LPM0
}