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:难以将 SPI I/F 作为主器件运行-- 4线接口,只能获得一个具有多字节 xfer 的中断

Guru**** 2618055 points

Other Parts Discussed in Thread: MSP430G2553, MSP-FET

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/671131/msp430g2553-difficulty-running-spi-i-f-as-master----4-wire-i-f-get-only-one-interrupt-with-multi-byte-xfer

器件型号:MSP430G2553
主题中讨论的其他器件:MSP-FET430UIFMSP430WAREMSP-FET

问题概要-- DSP 芯片运行 SPI I/F 的速度对于 G2553芯片来说太快、无法作为从器件处理 SPI 流量、因此在下降位置重新调整了 G2553代码、使其以 ~9600位/秒的悠闲速率作为 SPI 主器件(而不是将 DSP 作为从器件)工作  

尽可能地尝试、我只能获得一个多字符传输的第一个中断、并且在字节被放置在 ISR 中的 TXBUF 中之后、没有 SPI 时钟或 SOMI 时钟或位从端口发出、这是人们所期望的 (使用 SALEAE Pro Logic16分析仪检查 SPI I/F、以包含按预期工作的 SPI 使能信号。

相关事实: 我已确保 SMCLK 是指定的时钟、我已在《系列用户指南》、《产品审查指南》和勘误表文档(所有这些文档均已验证为最新版本)中详细介绍、查找缺少的任何初始化、时钟、 或控制信息、但不能找到任何"错误"、即使常识指出必须存在。 我找到了对 ME2 SFR 的引用根据 MSP-FET430UIF 去调试器屏幕、在调试模式下使用带有7.11.1构建链的 IAR 8.0、G2553不支持、并且该控制寄存器不显示-- 我认为我发现问题的原因是 SPI 外设未启用、但结果是"错误"。  此消息后面有两个代码块- G2553 SPI 主控初始化、带有 putstr (Put String)函数和 RX/TX ISR、以及 F28069 DSP 芯片的另一个 SPI 从器件块。  由于 G2553不能作为适当的主器件工作、因此应将重点放在该主器件上、而 DSP 代码仅作为完整性代码。  我是一名经验丰富的嵌入式固件开发人员、具有8位、16位和32位处理器经验、拥有摩托罗拉、TI、ST-Micro 和 Infineon 处理器代码、并通过 RS232、RS485、SPI 和 I2C 成功开发了多种接口、从未偶然发现过类似此类的头刮擦器。  哦!

症状: 端口的所有外观都没有实际运行-- TXBUF 被加载但没有传输 SPI 时钟或数据-- 就像移位寄存器输出端口引脚不运行或者不能运行一样、从而防止 TXBUF IFG 位被设置为下一个字节。

请帮助。

尊敬的、

Keith Abell

IntelliPower Inc.高级固件工程师

=================== MSP430G2553器件中的目标 SPI 主器件代码-初始化和 ISR /*

! μ@文件 ucb0_spi.c
*@作者 Keith Abell
*
*@简介 为处理器执行 UCB0 SPI 接口功能。
*
*目标: MSP430G2553器件
*

void 初始化 UCB0_SPI (void)
{
UCB0CTL1__SPI = UCSWRST; //禁用 UCB 外设
UCB0CTL0__SPI = UCMSB | UCMODE_2 | UCSYNC; // MSB 优先作为从器件、4引脚 STE 有源低电平、同步
// UCB0CTL0__SPI |= UCCKPH + UCCKPL; //目前,使用相位/极性= 00,数据 chg 在上升沿,捕获在后沿,时钟通常为低电平
UCB0CTL1__SPI |= UCSSEL_2; // SMCLK,启用。 USCI 逻辑保持在复位状态

UCB0CTL0__SPI |= UCMST; //或在主控模式控制位

// crystal_X2为16MHz,在另一个.h 文件
#define BAUDRATE ((crystal_X2/SPIbaudRATE))中定义 //将 BAUDRATE 舍入到近集整数中--使用 system_ModF_Proc.h 上的晶振和 SPIBAAUDRATE
UCB0BR0__SPI =(0xFF & AUDRATE)+1; //设置低阶波特率寄存器、舍入1
UCB0BR1__SPI =(0xFF &(BAUDRATE>>8)); //设置高阶波特率寄存器--- Buadrate =(256*hivalue)+lowvalue

UCB0CTL1__SPI &=~(无符号整型) UCSWRST; //启用 UCB 外设
USART_RX_INT_ENABLE;
// USART_TX_INT_ENABLE; //仅在准备发送消息时打开 TX 中断
返回; // Bye
} //初始化结束 UCB0_SPI

//注意:测试字符串在 main.c 中定义,并调用此例程来启动 xfer,方法是简单地使芯片启用并在 SPI RX 和 TX 中断上进行设置,方法是使用下面显示的宏设置相应的 IE2启用位...

void USART_putstr (char *字符串)
{
USART_TX_char_count = strlen (字符串);

if (USART_TX_CHAR_COUNT <= USART_TXBUFSIZE)
{
DSP_CE_ENABLE; //打开 SPI 使能与 DSP 通信
USART_TX_INT_ENABLE; //确保 TX 中断被启用--注意:一旦所有字符被传输,TX 中断将被 ISR 关闭
USART_RX_INT_ENABLE; // Ditto RX 中断
}
}





// USCIAB0RX 中断服务例程
#pragma vector = USCIAB0RX_vector
__interrupt void USCIAB0RX (void)
{
//这是一个 RX 中断

静态无符号字符 tempchar;
IF (IFG2 & UCB0RXIFG)
{
tempchar = UCB0RXBUF; //清除 UCB0RXIFG
temp_Rx_buffer[temp_Rx_idx+]= UCB0STAT__SPI;//将错误标志保存在循环缓冲器中
if (temp_Rx_idx ==(USART_RXBUFSIZE +1))
{
TEMP_Rx_idx = 0;
}
if (USART_Rx_char_count = USART_RXBUFSIZE)
{
返回;
}
if ( tempchar != SYN ) //不要存储同步空闲字符--只是空闲
{
USART_Rx_buffer[USART_Rx_write_index++]= tempchar; //存储接收到的字节并包括接收索引
if (USART_Rx_WRITE_INDEX =(USART_RXBUFSIZE + 1)) //如果写入索引刚刚递增超过缓冲区大小,则将其复位
{
USART_Rx_WRITE_INDEX = 0;
}
USART_Rx_char_count++; //收到 char、包括 count
switch (tempchar)
{
案例 STX:
mspData.StartOfMsgFlag = true; //接收到的消息的信号开始
中断;
案例 ETX:
mspData.RcvDSPmsgFlag = true; //接收到的消息的信号结束--将需要检查简单的校验和
USART_Rx_buffer[USART_Rx_WRITE_index+]=空; //在 ETX 之后将空填充到缓冲区中以进行字符串处理
如果(USART_Rx_WRITE_INDEX =(USART_RXBUFSIZE +1)//如果写入索引刚刚递增超过缓冲区大小,则将其复位
{
USART_Rx_WRITE_INDEX = 0;
}
中断;
默认值: //好的,不是特殊的字符,继续
中断;
}
}

}

// USCIAB0TX 中断服务例程
#pragma vector = USCIAB0TX_vector
__interrupt void USCIAB0TX (void)
{
IF (IFG2 & UCB0TXIFG)
{
//这是一个 TX 中断
如果(USART_TX_CHAR_COUNT > 0) //如果字符在缓冲区中则发送
{
UCB0TXBUF = mspData.msgStr[USART_TX_READ_index+];//加载 TX 寄存器、包括索引
if (USART_TX_READ_INDEX =(USART_TXBUFSIZE +1)) //如果索引的增量大于最大值,则复位为0
{
USART_TX_READ_INDEX = 0;
}
USART_TX_CHAR_COUNT--; //已发送字符、解码计数
//LedUPS1 (LED_RED);
// do _a_nop;
}
其他
{
// KRA edit --如果我们要进行传输以获得发送到 DSP 的命令的响应,则需要修改此项以发送默认字符(SYN)。 目前、只需关闭 TX INT enable
//即可 我正在尝试让消息传输作为主设备来工作,而不是那么担心接收和虚拟传输来从
//获取响应 DSP 作为从器件
// UCB0TXBUF = SYN; //缓冲区为空,发送同步--不会超时,除非 Masteer (DSP)向我们发送了一些东西
//并且我们已启用(spien1 HIGH)。
USART_TX_INT_DISABLE; //关闭 TX 中断
}
}
}===========================



FMS320F28069器件中的目标从器件代码-初始化和 ISR 的



/*! μ@文件 HAL_SPI_FLASH.c
* @作者 Keith Abell
* @简介 对连接到外部串行 SPI 闪存器件和 MSP430的 SPI 接口执行硬件访问级别控制。
*
*目标: TMS320F28069器件
*

// KRA 编辑--这个初始化例程现在将 DSP 设置为从器件-- 我们初始化 SPI 时钟子系统寄存
器、但由于// SPI 主设备位未设置、SPI 时钟将被忽略、并且仅取决于作为主设备的 G2553 SPI 时钟。
void init_hal_spi_flash (void)
{
unsigned int i;

flash_ce_disable; //取消选择 SPI 串行闪存(输出为高电平)
MSP430_CE_DISABLE; //取消选择 MSP430 (输出为高电平)
spiPort.rxWriteIndex = spiPort.rxReadIndex = spiPort.rxCharCount = 0;//刷新并准备 SPI 接收缓冲
区 WritPort.txeIndex = spiPort.rxReadIndex = spiPort.spiCharCount = 0;//刷新并准备 SPI 发送缓冲
区 spiPort.checkCount = 0;
spiESRCR.SpiSpiSpiET.SpiReadIndex = 0;SPICESCR.SpiRBIT.SpiSpiSpiSpiSpiSpiR //重置 DSP
EALLOW 上的 SPI 接口; //允许对寄存
器 PieVectTable.SPIRXINTA 的受保护访问=&spiaFlashReceiveIsr; //为接收
PieVectTable.SPITXINTA 设置中断例程=&spiaFlashTransmitIsr; //设置发送
EDIS 的中断例程; //禁止对寄存器
EALLOW 的受保护访问; //允许对寄存器
GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0的受保护访问; // SPI 使能0 -串行闪存、配置为 GPIO
GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0; //*启用上拉
GpioCtrlRegs.GPBDIR.bit.GPIO50 = 1; //使该引脚成为输出
GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 0; // SPI 使能1 -本地 MSP430实时时钟、配置为 GPIO
GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0; //*启用上拉
GpioCtrlRegs.GPADIR.bit.GPIO29 = 1; //使该引脚成为输出
GpioCtrlRegs.GPAPUD.bit.GPIO5=0; //*启用 GPIO5 (SPISIMOA)
GpioCtrlRegs.GPAQSEL1.bit.GPIO5=3; //异步输入 GPIO5 (SPISIMOA)
GpioCtrlRegs.GPADIR.bit.GPIO5 = 1; // SPISIMOA 是输出 GPIO
GpioCtrlRegs.GPAMUX1.bit.GPIO5=2; //将 GPIO5配置为 SPISIMOA
GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; //*启用 GPIO17 (SPISOMIA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; //异步输入 GPIO17 (SPISOMIA)
GpioCtrlRegs.GPADIR.bit.GPIO17 = 0; // SPISOMIA 为输入 GPIO
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; //将 GPIO17配置为 SPISOMIA
GpioCtrlRegs.GPAPUD.bit.GPIO18=0; //*启用 GPIO18 (SPICLKA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; //异步输入 GPIO18 (SPICLKA)
GpioCtrlRegs.GPADIR.bit.GPIO18 = 1; // SPICLKA 是一个输出 GPIO
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; //将 GPIO18配置为 SPICLKA
EDIS; //禁止对寄存器
SpiaRegs.SPICCR.bit.SPICHAR 的受保护访问 = 7; //选择8位字符输出(x + 1)
// KRA 编辑--我们将使用模式0 (Pol)、0 (Pha)--上升沿上的数据输出(无延迟)和上升沿上的样本数据
// KRA 编辑--针对00 pol / Pha 稳定-- 与串行闪存以及 MPS430G2553兼容的 POL/PhA 也被设定为0、0
SpiaRegs.SPICCR.bit.CLKPOLARITY = 0; //在上升沿
SpiaRegs.SPICTL.bit.CLK_PHASE 输入时、在下降时钟边沿上输出数据 = 0; //无延迟
SpiaRegs.SPICCR.bit.SPILBK 的正常 SPI 时钟方案 = 0; //禁用 SPI 环回模式
SpiaRegs.SPICTL.bit.master_slave = 0; // SPI 被配置为从器件,现在
SpiaRegs.SPICTL.bit.OVERRUNINTENA=0; //禁用接收器溢出标志位中断
SpiaRegs.SPICTL.bit.Talk = 1; //让 SPI 外设通信
SpiaRegs.SPIPRI.bit.free = 1; //仿真器断点不会干扰传输
// KRA 注释--可以通过更改 SYSCLKOUT (或90Mhz)的 LSPCLK 分频值来减慢 BRR 定义的波特率 通过将
LOSPCP 预分频器寄存器中的// LSPCLK 位更改为最大值7b、将4分频除以14、并在
//注意、LSPCLK 是驱动所有 SPI 和 SCI UART 器件进行波特率选择的基本时钟、必须采用这种方法 考虑
到//由于我们可以轻松地为 UART 生成9600波特的 SCI 时钟、在 LSPCLK 上除以4、但对于 SPI 为175K 位/秒
//速度"有点快"...我们将尽可能慢、但事实证明对于 G2553
//来说仍然太快了 90MHz/14 ~ 6.42MHz 的 LSPCLK 和(127+1)的 BITRATECONTROL 可产生50.22K 或~6278字节/秒
的 EALLOW 位速率;
CtrlRegs.LOSPP.ALL = 0x0007; //将 LSPCLK 的预分频器设置为12 (请参阅技术参考中的1.4.1.2)
(受保护寄存器) EDIS;
SpiaRegs.SPIBRR = BITRATECONTROL; //设置比特率
SpiaRegs.SPIFFTX.bit.SPIRST = 0; // SPI 发送和接收通道可以恢复
SpiaRegs.SPIFFTX.bit.SPIFFENA=1; //启用 SPI FIFO 增强
功能 SpiaRegs.SPIFFTX.bit.TXFIFO = 0; //清除 FIFO、复位指针、并保持在复位
SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1; //清除 TXFIFINT 标志
SpiaRegs.SPIFFTX.bit.TXFFIL = 1; //设置为零
SpiaRegs.SPIFFTX.bit.TXFFIENA=0; //目前,禁用 TX FIFO 中断--等到 Rdy 发送
到 Xmit SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0; //将 FIFO 复位为零并保持在 RESET
SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 1; //清除任何挂起的中断
SpiaRegs.SPIFFRX.bit.RXFFIENA=1; //启用 RX FIFO 中断
SpiaRegs.SPIFFRX.bit.RXFFIL = 1; // FIFO 在接收
到的 SpiaRegs.SPIFFCT.bit.TXDLY=0时产生中断; //位的 FIFO 发送没有延迟;
SpiaRegs.SPIFFTX.bit.SPIRST = 1; // SPI 发送和接收通道可以恢复
SpiaRegs.SPICTL.bit.SPIINTENA=1; //启用 SPI 中断
SpiaRegs.SPICCR.bit.SPISWRESET = 1; //从 Reset
SpiaRegs.SPIFFTX.bit.TXFIFO 中撤回 SPI = 1; //为正常操作释放 FIFO
SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1; //释放 FIFO 以便使用
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; //启用 PIE 块... 恰好在 PieCtrlRegs.PIEIER6.bit.INTx1
= 1的情况下; //启用 PIE 组6,INT 1
PieCtrlRegs.PIEIER6.bit.INTx2 = 1; //启用 PIE 组6,INT 2
IER |= M_INT6; // SPI block+
spiFlashData.currentCommand 的内核启用中断= flashNoOperation; //使 SPI 闪存状态机
spiFlashData.subState = 1; //预置为子状态1
spiFlashData.devicePresent = false; //预设、以便不存在器件
spiFlashData.commandComplete = false; //命令已完成,因为此时没有

pEventData->msp430Data.msgFail = NOTBUSY;
pEventData->msp430Data.lengthOfData = MAX_MSP430_string;
pEventData->msp430Data.MSP_WriteEventx = 0;psp430Data->msp430Data.Idx

= 0+;针对 MSP430的<MAX_I+=0+

pEventData->msp430Data.MSP430_ReadBuffer[i]= 0;
pEventData->msp430Data.MSP430_WriteBuffer[i]= 0;
}
对于(i = 0;i < FLASH_BUFSIZE;i++)
{
tempMspWrBuffer[i]= tempMspRdBuffer[i]= 0;
}
tmpMspRdIdx = tmpMspWrIdx = 0;
pEventData->SPI_Port_Busy = port_flash_Busy;
spiPort.rxCharCount = tspiPort.txWriteIndex = 0+
spiPort.checkCount

;<ePort = 0+= rspiReadSpiWriteIndex = 0+;<= 0+= rspiReadPort.SpiReadSpiReadPort.SpiSpiSpiPort = 0+;<= 0+= 0+= rspiReadSpiReadSpiReadSpiReadSpiPort =

spiPort.rxBuffer [i]= 0;
spiPort.txBuffer [i]= 0;
}
do _a_nop;
返回;
} // init_hal_spi_flash


__interrupt void spiaFlashTransmitIsr (void)
{//
静态无符号 int 延迟;
unsigned char tempData; //临时数据变量
if (pEventData->SPI_Port_BUSY =PORT_MSP430_BUSY)
{
if (pEventData->msp430Data.MSP_WriteIdx > MAX_MSP430_string)
{
pEventData->msp430Data.MSP_WriteIdx = 0; //将缓冲区指针打包
}
if (pEventData->msp430Data.xmitcnt!= 0)
{
tempData = pEventData->msp430Data.MSP430_WriteBuffer[pEventData->msp430Data.MSP_WriteIdx+]; //字符写入
if (tmpMspWrIdx > FLASH_BUFSIZE)
{
tmpMspWrIdx = 0;
}
tempMspWrBuffer[tmpMspWrIdx++]= tempData; //无条件保存从写入缓冲区中拉出/发送的每个 Tx 字符
tempData <<= 8; //将其向左移动
tempData &= 0xFF00; //关闭掩码无关
// 对于(delay = 0;delay < 8000;delay++){}; //等待一段时间
SpiaRegs.SPITXBUF = tempData; //将数据载入发送寄存器
pEventData->msp430Data.xmitcnt --; //减量计数,0时停止;
}
其他
{
SPI_TX_INT_DISABLE; //停止发送新字符
// MSP430_CE_DISABLE; //需要等待 FIFO 清除
}
}

// KRA edit --下面的代码只用于串行闪存操作!!! 此 ISR 结束后、MSP430和串行闪存的接收 ISR 会跟随
否则(pEventData->SPI_Port_BUSY =PORT_FLASH_BUSY)
{
IF (SpiaRegs.SPIFFTX.bit.TXFFST < 1) //确保 FIFO 中有空间(只有四个位置)
{
if (spiPort.txCharCount) //确定,缓冲区中是否还有字符...
{
tempData = spiPort.txBuffer [spiPort.txReadIndex++]; //是,加载数据,使左对齐并包括索引
tempData <<= 8; //将其向左移动
tempData &= 0xFF00;
SpiaRegs.SPITXBUF = tempData; //将数据载入发送寄存器
spiPort.txCharCount--; //字符已发送,因此计数递减
if (spiPort.txReadIndex >= FLASH_BUFSIZE) //检查我们是否在循环缓冲区的末尾...
{
spiPort.txReadIndex = 0; //重置索引(如果是)
} //缓冲区结束检查
}
else //确定,不剩余字符... //如果没有要发送的字符...
{
SPI_TX_INT_DISABLE; //关闭 TX 中断
} //缓冲区检查结束
} // FIFO 结束完全检查
}
SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1; //清除中断标志
PieCtrlRegs.PIEACK.bit.ACK6 = 1; //发出 PIE 确认
} //结束_interrupt void spiFlashTransmitIsr

__interrupt void spiaFlashReceiveIsr (void)
{
静态无符号 int 错误计数= 0; //将其设置为0以启动
unsigned char tempData; //读取数据临时数据变量
tempData = SpiaRegs.SPIRXBUF;
//无符号字符 tempMspWrBuffer[FLASH_BUFSIZE*2]、tempMspRdBuffer[FLASH_BUFSIZE*2];
//无符号 int tmpMspRdIdx = 0;

if (pEventData->SPI_Port_BUSY =PORT_MSP430_BUSY)
{
if (tmpMspRdIdx > flash_BUFSIZE)
{
tmpMspRdIdx = 0;
}
tempMspRdBuffer[tmpMspRdIdx++]= tempData; //无条件保存循环缓冲区中的每个接收字符
if (pEventData->msp430Data.msgFail == BUSYREAD) //这可能是写入期间的伪读取:chk 表示 SYN char @else
{
if (pEventData->msp430Data.MSP_ReadIdx =0) //我们是否正在等待 STX?
{
if (tempData == STX)
{
pEventData->msp430Data.MSP430_ReadBuffer[pEventData->msp430Data.MSP_ReadIdx+]= tempData;
}
否则、如果(tempData == SYN)//否、字符不是 STX...IDLE 字符?
{
//好的,假设我们一直在进行正确的通信--继续,但只针对如此多的字符...
if (errorcount++> MAX_MSP_RCVCHAR_ERR)
{
//好的,我们已经等了4毫秒才开始 response...it
Process_MSP_Rcv_error();
}
}
其他 //没有 STX 或 SYN 字符,读取计数仍为0...报告错误
{
//好的,不是 STX 或 SYN 同步字符——我们真的不是序列
Process_MSP_Rcv_error();
}
}
else //确定、我们有一个 STX 或者 IDX 仍然为0、检查 ETX 和填充字符
{
if (pEventData->msp430Data.MSP_ReadIdx < MAX_MSP430_string)
{
pEventData->msp430Data.MSP430_ReadBuffer[pEventData->msp430Data.MSP_ReadIdx+]= tempData;
if (tempData == ETX)
{
//好的,我们已经用缓冲区小于满的 ETX 终止,所以报告 OK,BUSYREAD 的末尾
pEventData->msp430Data.msgFail =确定;
pEventData->msp430Data.lengthOfData = pEventData->msp430Data.MSP_ReadIdx;// IDX 是字符计数
pEventData->msp430Data.MSP_ReadIdx = 0; //清除下一个 RCV 的读 idx
pEventData->msp430Data.MSP_WriteIdx = 0; //清除下一个 RCV 的写入 idx
//关闭 SPI 发送中断以关闭接收! 我们只是为了阅读字符而再次接受我们的支持!
SPI_TX_INT_DISABLE;
}
}
else //我们已填充接收缓冲区...rcv 错误
{
Process_MSP_Rcv_error();
}
}

do _a_nop;
}
否则(pEventData->msp430Data.msgFail == BUSYWRITE) // substate 应该= BUSYWRITE、因此应处理写入返回字节
{
if ( tempData != SYN ) //跳过此字符--垃圾,不需要保存或阅读“em”
{
// _asm (" ESTOP0"); //出于调试目的取消注释//未按预期工作...research
}
}
否则//我们不在 BUSYREAD 或 BUSYWRITE 中,我们不应该在 PORT_MSP430_BUSY 模式中!
{
//我们确实处于“丢失”的区域,因此总结了一个错误
_asm (" ESTOP0"); //取消注释以进行调试 //未按预期工作...研究
}
}

// KRA edit --下面的代码只用于串行闪存操作!!!

否则(pEventData->SPI_Port_BUSY =PORT_FLASH_BUSY) //如果我们不是闪存忙,请清除中断
{ //并返回
if (tmpFlashRdIdx > flash_BUFSIZE)
{
tmpFlashRdIdx = 0;
}
tempFlashRdBuffer[tmpFlashRdIdx++]= tempData; //无条件保存循环缓冲区中的每个接收字符
if (spiPort.rxCharCount < FLASH_BUFSIZE) //确保我们有空间,否则报告错误
{
spiPort.rxBuffer [spiPort.rxWriteIndex++]= tempData; //存储接收字节并递增接收索引
if (spiPort.rxWriteIndex >= FLASH_BUFSIZE) //检查我们是否在循环缓冲区的末尾...
{
spiPort.rxWriteIndex = 0; //重置索引(如果是)
} //缓冲区检查结束
spiPort.rxCharCount++; //字符已接收,因此增加计数
}
其他 //报告 SPI 闪存错误
{
pEventData->SPI_Port_Busy = PORT_FLASH_ERR; //报告 RCVERR
spiPort.rxCharCount = 0; //设置新的闪存接收
spiPort.rxWriteIndex = 0; // ditto
spiPort.rxReadIndex = 0; // ditto
SPI_TX_INT_DISABLE; //停止填料
}
}
else //哎呀! MSP 或闪存都不忙! 在缓冲区中填充字符以进行调试...
{
if (tmpFlashRdIdx > flash_BUFSIZE)
{
tmpFlashRdIdx = 0;
}
tempFlashRdBuffer[tmpFlashRdIdx++]= tempData; //无条件保存循环缓冲区中的每个接收字符
spiPort.rxCharCount = 0; //设置新的闪存接收
spiPort.rxWriteIndex = 0; // ditto
spiPort.rxReadIndex = 0; // ditto
SPI_TX_INT_DISABLE; //停止填料
_asm (" ESTOP0"); //未按预期工作...研究
}
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR = 1; //清除溢出标志
SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 1; //清除中断标志
PieCtrlRegs.PIEACK.bit.ACK6 = 1; //发出 PIE 确认
}//_中断结束 void spiFlashReceiveIsr

void process_MSP_Rcv_error (void)
{
//确定,清除接收--0 out IDX'es,报告失败 msgFail
pEventData->msp430Data.MSP_ReadIdx = 0; //清除读 idx
pEventData->msp430Data.MSP_WriteIdx = 0; //清除写入 idx
pEventData->msp430Data.msgFail =失败;
//最好关闭 SPI 发送中断以关闭接收!
SPI_TX_INT_DISABLE;
}

#endif

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

    您好、Keith、

    您是否在应用中使用了任何低功耗模式? 如果是、您将使用哪些?

    此外、我建议阅读 《MSP430 MCU 上 eUSCI 和 USCI 串行通信常见问题解决方案》的"一般"和"SPI"部分。

    此致、

    Caleb Overbay

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

    Caleb、

    不需要,我们的解决方案不需要任何低功耗模式--我们正在平稳运行,所以没有“gotchas”从一种电源模式切换到另一种电源模式。 对我的问题还有其他问题或意见吗?  我将查看您提供的链接的文档、以便了解我可以了解的内容。  我还下载了一个 CCS-6.1.2、能够下载并作为加载项安装 Grace 的一个版本、并且正在创建 SPI 主接口的测试版本、目的是查找项目代码中缺少的内容。  如果我在这两个方面都取得了突破、我将告诉您、并向您介绍需要更多帮助的最新信息。

    我有一个与 TI 或第三方 FAE 相关的相关问题、该问题位于奥兰治县(或靠近加利福尼亚州奥兰治) 如果问题持续了任何时间或时间、我可以在工作场所与我会面来解决问题...我正在尝试寻找一家 TI 销售办事处、该办事处可能会提供现场 FAE 帮助、作为一种额外的可能性。  您能否提供销售办事处电话号码?  凭借 Orange CTy/LA 地区的所有高科技、我无法想象该地区没有本地的 TI 资源。

    此致、

    Keith Abell

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

    我在您的代码中看不到任何明显不正确的内容。 如果可能、我希望看到一个精简代码集、其中仅包含重新创建问题所需的代码、以便我可以在我的末尾对此进行测试 我也不建议使用 Grace、因为 Grace 已被弃用、不再受支持。 相反、请参阅 MSP430Ware 中提供的示例、这些示例可在 TI Resource Explorer 中找到。 我认为最有用的例子是以下示例:
    dev.ti.com/.../

    此外、看起来您需要从 SMCLK 获取 SPI 模块。 您能否将 SMCLK 输出到引脚并验证其是否正确振荡?

    有关 TI FAE 支持的信息。 接收调试支持的最佳位置是在该论坛上。 我相信、我们将能够准确地确定导致问题的原因。 如果我们无法在论坛上解决问题、我们可以讨论其他可能性。

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

    Caleb、

    我可以设置代码以输出 SMCLK、但不确定是否需要根据我在 F28069 DSP 方面的经验进行以下假设。

    由于我可以向寄存器写入数据并在调试器中观察它们以在 TX ISR 中包含断点、因此有大量证据表明 SMCLK 正在运行。  我在 DSP 从设备代码中遇到这样的情况:我无法使端口进行初始化、只能发现我关闭了 SPIENABLEACLK (因为我在 SPI 端口 A 上、所以我需要关闭 SPIENABLEACLK)并使 BCLK 保持开启状态。  我将 CLKS 翻转为 ACLK ON、BCLK OFF、然后退出!  我可以初始化 DSP SPI 端口。  我认为 G2553是一样的--没有 SMCLK,没有寄存器对与端口寄存器相关的写入做出响应。

    有什么想法?

    我已经捕获了你引用的示例代码--正是这样,我已经获取 了一个指向 MSP430Ware 网页的链接,并下载了我没有的最新版本,所以我可以根据需要利用所有的示例代码。

    此致、

    Keith

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

    我不确定我是否理解您提出 SMCLK 的理由。 向 MSP430寄存器写入数据基于 MCLK。 SMCLK 由 USCI_B SPI 模块等外设使用、但实际上不便于写入特定模块寄存器。

    我怀疑 SMCLK 未正确振荡、因此 USCI_B 模块未接收时钟。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我看不到您在 P1SELx 中为备用功能设置 P1.5-7的位置。 (另请参见 SLAS735J 表19。)

    您需要将引脚"移交"到 SPI 单元、否则您不会在引脚上看到任何活动。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bruce 和 Caleb:

    哦,我想你可能会在一段时间内根据你的输入来做一些事情,我没有在这些 GPIO 引脚 P1.5-7上启用 SPI 功能,但被用虚线表示-- 似乎我错过了包含以下内容的 GPIO 设置初始化、您将注意到这些引脚上的 SPI 功能实际上是用蓝色粗体启用的。  抱歉、我这么说了。  我正在尝试 Caleb 的想法,就是将需要 mds 的 SMCLK 输出到我的 G2553代码和 DSP 从代码中,以适应这种情况--一旦我对 Caleb 的问题“SMCLK 是否正在运行?”有了回答,我就会在这个线程中添加这样的内容。 --我们很快就会看到。  另请注意、全局中断使能在 GPIO/HW init 函数的末尾打开、以便与我之前输入的 USART_putstr 函数中的 SPI RX 和 TX 中断一起启用中断。

    此致、 Keith

    void 初始化硬件(void)

       WDTCTL = WDTPW | WDTHOLD;                               //在初始启动期间停止看门狗计时器超时
       P1OUT = 0;                                                     //端口1输出寄存器->将所有数据归零
       P1SEL = BIT5 | BIT6 | BIT7;                                        //端口1端口选择1寄存器->选择 UCB SPI 外设 P1.5-7
       P1SEL2 = BIT5 | BIT6 | BIT7;                                  //端口1端口选择2寄存器->选择 UCB SPI 外设 P1.5-7
       P1DIR = BIT3 | BIT6;                                             //端口1方向寄存器-> P1.3和 P1.6是输出
    //   P1IES = BIT4;                                                   //端口1中断边沿选择寄存器-> P1.4触发器高到低转换
       P1IES = 0;                                                          //端口1无中断
       P1IFG = 0;                                                       //端口1中断标志寄存器->无
    //   P1IE  = BIT4;                                                    //启用 P1.4中断
       P1IE  = 0;                                                           //禁用 P1.4中断
       P2OUT = BIT0;                                                          //端口2输出寄存器->除 DSP SPI 使能、P2.0=1之外的所有数据均为零;
       P2SEL = 0;                                                               //端口2端口选择1寄存器->选择所有 I/O
       P2SEL2 = 0;                                                              //端口2端口选择2寄存器->选择所有 I/O
       P2DIR = BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT4;                 //端口2方向寄存器-> P2.0-5是输出
       P2IES = 0;                                                                //端口2中断边沿选择寄存器->无
       P2IFG = 0;                                                                //端口2中断标志寄存器->无
       P3OUT = BIT4;                                                  //端口3输出寄存器->除 P3.4外的所有数据均为零
       P3SEL = 0;                                                               //端口3端口选择1寄存器->选择所有 I/O
       P3SEL2 = 0;                                                                  //端口3端口选择2寄存器->选择所有 I/O
       P3DIR = BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT4 | BIT6 | BIT4;   //端口3方向寄存器-> P3.0-7均为输出
       BCSCTL2 = SELM_0 | DIVM_0 | DIVS_0;                          // DCOCLK、除以1、除以1
       DCOCTL = BCSCTL1 = 0x00;                                  //清除时钟寄存器
       DCOCTL  = CALDCO_16MHz;                                 //设置 DCO 频率
       BCSCTL1 = XT2OFF | DIV_0|CAL_BC1_16MHz;            //禁用 XT2CLK,对 ACLK 进行1分频-->用于 RTC @ 32.768kHz
                                                                        //  并校准 DCO @16MHz
       BCSCTL3 = XT2S_0 | LFXT1S_0 | XCAP_3;                   // 0.4至1MHz 晶振、LFXT1上的32768Hz 晶振、~12.5pF (对于15pf 电容)
       初始化 adc();                                                    //初始化 ADC 进程和硬件
       timerRTC_initialize();                                            //初始化计时器进程和硬件
       初始化 UCB0_SPI ();                                           //初始化 SPI 接口和进程
       WDTCTL = WDTPW | WDTHOLD | WDTNMI;                 //停止看门狗计时器超时并使用 NMI 功能
       _enable_interrupt ();                                            //让我们把战犬敲竹杠
       返回;                                                                       //黑贝
    }                        //初始化硬件例程结束

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

    >P2SEL = 0;//端口2端口选择1寄存器->选择所有 I/O

    在这里要小心:P2SEL 在复位时为0xC0、以便为32kHz 晶振启用 XIN/XOUT。 您似乎正在使用该晶体;如果使用该晶体、则应保留此设置。 P2SEL2=0正常。 (另请参见 SLAU144J 表8-2。)

    这可能不会导致您描述的症状、但这是需要注意的问题。

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

    感谢您提供 GPIO 初始化信息。 我仍然认为、简化的代码示例将是我帮助您进行调试的最佳方式。 这样、我就可以看到您使用的所有宏的定义、验证正确性。

    对 SMCLK 实验有任何更新? 如果给定您在上面发布的代码、看起来您正在正确设置它。

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

    Bruce、Caleb、

    嗯,SMCLK 是在 P1.4上根据检查的要求生成的--但是现在我手上有了一个新的秘密。  Bruce 和 SMCLK 的输入进一步更新了 GPIO 和时钟初始化例程,但并未如人们所期望的那样以16MHz 运行,DCOCLK 以1分频驱动它 --说什么?  分析仪的测量值为~316KHz,相对于 DCO 时钟大约慢50倍(参见下面的 PIX -一个 SMCLK 时序测量和一个"失控 "SPICLK。  此外,还不清楚 SPICLK 为什么会消失--发送中断甚至还没有被启用(我怀疑在初始化时钟子系统和 SPI 端口之后发生了失控,但我还没有设置实验来确定这一点。  但是、您知道、它只是在调试器停止时继续运行、并且具有在调试器停止时停止时钟的功能、并且没有尝试在 TXBUF 中填充字符到这一点。  现在,我似乎向前迈出了一步,又向前走了两步。  另一个设置项目--为了防止 DSP 从站混淆问题 ,我执行了闪存擦除以将其置于高阻态-- 1)请勿干扰 SPI 主器件 G2553、因此 a) MISO 线路将处于高电平无效状态、B)不应影响 SPI 主器件的运行。  有新想法吗?  如果 SMCLK 直接反映了 DCOCLK 的速度、DCOCLK 如何能够以如此慢的速度运行?  我偶然发现了这个时钟问题--完全是意料之外的。  是的、我验证了时钟来自 G2553 28引脚版本的 P1.4或引脚6。  结果发现,审查 SMCLK 比我原来想象的更好(我的道歉 Caleb!)。  您将注意到,从远处看,SPI 时钟反映了 SMCLK 的速度,但似乎有一些抖动在进行-- 根据您在测量注释中的位置,您可以得到一些 SPICLK 周期和频率的变化,这对于固定的 SMCLK 频率来说也是没有太大意义的--我的 BR 波特率除数应该将它减至~9600位/秒--另一个异常。

    Caleb、

    要减少代码的工作量,以便您可以尝试在您的商店中运行代码,当然是可以完成的,但需要一些时间-- 我将需要在 IAR 工作区中创建一个重复项目、并全盘删除一些文件、然后执行一些复杂的编辑、以确保不会删除错误的代码、并且能够确保其编译。  我不知道你是在使用 IAR 还是 CCS --如果 CCS 你可能需要编辑各种与编译器相关的指令来构建代码。  如果您使用的是最新的 MSP430 IAR Workbench 8.0 (版本为8.0.12.5110、IDE 版本为7.11.1共享组件)、则编译时应该很少或没有错误。  但这可能需要到明天的某个时候才能实现。  我假设你正在寻找一个源代码库,它只包含我的 SPI 主函数和相关的初始化一个驱动程序代码(主函数中的小测试例程)来运行 SPI 主函数--是的?

    此致、Keith

    更新了初始化以启用 SMCLK、用于32.768kHz 时钟晶振的 XIN/XOUT (感谢 Bruce!) 以及对日期的更正。

    void 初始化硬件(void)

       WDTCTL = WDTPW | WDTHOLD;                                //在初始启动期间停止看门狗计时器超时
       P1OUT = 0;                                                               //端口1输出寄存器->将所有数据归零
    // KRA 编辑--用 G2553为主器件对 SMCLK OUT SPIENA*引脚进行临时测试(此时不需要 SPIENA)
       P1SEL = BIT4 | BIT4 | BIT6 | BIT4;                                   //端口1端口选择1寄存器->选择 SMCLK 外设 P1.4
                                                                                        //  和端口1端口选择1寄存器->选择 UCB SPI 外设 P1.5-7
       P1SEL2 = BIT5 | BIT6 | BIT7;                                    //端口1端口选择2寄存器->选择 UCB SPI 外设 P1.5-7
    // KRA 编辑--用 G2553为主器件对 SMCLK OUT SPIENA*引脚进行临时测试(此时不需要 SPIENA)
       P1DIR = BIT3 | BIT4 | BIT6;                                           //端口1方向寄存器-> P1.3、P1.4和 P1.6是输出
    //   P1IES = BIT4;                                                          //端口1中断边沿选择寄存器-> P1.4触发器高到低转换
       P1IES = 0;                                                       //端口1无中断
       P1IFG = 0;                                                      //端口1中断标志寄存器->无
    //   P1IE  = BIT4;                                                  //启用 P1.4中断
       P1IE  = 0;                                                                   //禁用 P1.4中断
    // KRA 编辑--临时(?) 使用 P2.0作为 DSP SPI 使能
       P2SEL = BIT6 | BIT7;                                                  //端口2端口选择1寄存器->选择除 XIN、XOUT 以外的所有 I/O 用于时钟 xtal
       P2SEL2 = 0;                                                               //端口2端口选择2寄存器->选择所有 I/O
       P2OUT = BIT0;                                                           //端口2输出寄存器->除 DSP SPI 使能、P2.0=1之外的所有数据均为零;
       P2DIR = BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT4 | BIT2;       //端口2方向寄存器-> P2.0-5是输出、P2.7是 XOUT、P2DIR.7 = 1
       P2IES = 0;                                                                 //端口2中断边沿选择寄存器->无
       P2IFG = 0;                                                                 //端口2中断标志寄存器->无
       P3OUT = BIT4;                                                  //端口3输出寄存器->除 P3.4外的所有数据均为零
       P3SEL = 0;                                                      //端口3端口选择1寄存器->选择所有 I/O
       P3SEL2 = 0;                                                       //端口3端口选择2寄存器->选择所有 I/O
       P3DIR = BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT4 | BIT6 | BIT4;   //端口3方向寄存器-> P3.0-7均为输出
       BCSCTL2 = SELM_0 | DIVM_0 | DIVS_0;                          //对于 MCLK 和 SMCLK、DCOCLK、除以1、除以1
       DCOCTL = BCSCTL1 = 0x00;                                    //清除时钟寄存器
       DCOCTL  = CALDCO_16MHz;                                  //设置 DCO 频率
       BCSCTL1 = XT2OFF | DIV_0|CAL_BC1_16MHz;          //禁用 XT2CLK,对 ACLK 进行1分频-->用于 RTC @ 32.768kHz
                                                                                     //  并校准 DCO @16MHz
       BCSCTL3 = XT2S_0 | LFXT1S_0 | XCAP_3;                  // 0.4至1MHz 晶振、LFXT1上的32768Hz 晶振、~12.5pF (对于15pf 电容)
       初始化 adc();                                                           //初始化 ADC 进程和硬件
       timerRTC_initialize();                                                   //初始化计时器进程和硬件
       初始化 UCB0_SPI ();                                                   //初始化 SPI 接口和进程
       WDTCTL = WDTPW | WDTHOLD | WDTNMI;                  //停止看门狗计时器超时并使用 NMI 功能
       _enable_interrupt ();                                           //让我们把战犬敲竹杠
       返回;                                                                      //黑贝
    }            //初始化硬件例程结束

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    > BCSCTL1 = XT2OFF | DIV_0|CAL_BC1_16MHz; //禁用 XT2CLK,对 ACLK 进行1分频-->用于 RTC @ 32.768kHz

    CAL_BC1_16MHz 是否与 CALBC1_16MHz 不同?

    我同情"白白"问题、但有时它所需要的只是一个拼写错误。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Bruce、

    逻辑问题。  尚未检查 CCS 的标准头文件、但 CAL_BC1_16MHz 与您在电子邮件中提到的基本值相同、但它是 G2553的 IAR 标准头文件中的标准值。  它让我很早就开始使用 G2553名称来寻找某些东西、而 IAR 却有自己的旋转。  不知道为什么他们选择了自己的器件、但不想为了 IAR 更新兼容性而使他们的名称变得混乱。  希望 Caleb 或者你自己如果你参与查看我的测试源 IAR 相关项目不会以太多的方式--我希望在今天的某个时候得到我的测试线束代码,以响应 Caleb 希望让我的错误代码进行测试的愿望。  我正在剥离与 SPI 主测试函数无关的所有多余代码。

    此致、Keith

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

    感谢您的详细更新。 我将等待您的评论、直到您发送测试安全带代码、以避免您提出请求。 此外、让我知道您使用的是哪个版本的 IAR、这样我就可以确保在我尝试导入项目时一切都兼容。

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

    Caleb、

    这是压缩在包含.c 和.h 文件的目录中的项目。  我粘贴了"关于 IAR"信息窗口以显示我正在使用的版本(基本上是最新的7.11.1版本。  请告诉我 zip 文件上载是否正常。  如果我们需要向您发送一个下拉框链接--我只需要相应的电子邮件就可以向您发送链接,除非您希望提供 FTP 连接。   我真的很感谢他们的帮助--我想知道我的 G2553芯片是否以某种奇怪的方式受到了损坏。

    Oops -- IAR 窗口粘贴未显示 up...use IAR Embedded Workbench for MSP430 IDE,包括完整的构建链和调试器。  7.11.1版与 IAR Embedded Workbench 共享组件 Ver 8.0.12.5110。

    此致、Keith

    e2e.ti.com/.../E2E_5F00_G2553_5F00_SPI_5F00_Master_5F00_Test_5F00_Project.zip

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

    我的(古代) IAR 副本没有 CAL_BC1_16MHz、但我运行了以下项目:

    e2e.ti.com/.../1089911

    这表明 CAL_BC1_16MHz 是 TLV 索引(具体为1)、其中 CALBC1_16MHz 应该是闪存中的地址、类似于(0x10F9u)。 SLAU735J (第29页)指出、设置 RSEL=1可使您获得大约150kHz 的频率。

    您可能需要再次检查 msp430g2553.h 的副本。

    [编辑:修复了 RSEL 错误报价。]

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

    Brian、

    很棒的发现……哦,太微妙了……

    哎呀!  深入了解用户指南(TLV 第24节)并搜索头文件后、我发现 DCO 校准正确:

     /* 16MHz 的 DCOCTL 校准数据 */

    _no_init volatile unsigned __read char CALDCO_16MHz @ 0x10F8;

    这允许我使用语句 DCOCTL = CALDCO_16MHz;如果设置正确、则将其设置为0x8C、即0x10F8的值。

    事实证明头文件中有两对基准面--一组直接从校准数据中引用正确的校准数据,另一组是从0x10F6处的 TAG_DCO_30标签地址偏移的:

     /* 16MHz 的 DCOCTL 校准数据 */

    _no_init volatile unsigned __read char CALDCO_16MHz @ 0x10F8;

     /*针对16MHz 的 BCSCTL1校准数据 */

    _NO_init volatile unsigned __read char CALBC1_16MHz @ 0x10F9;

    #define CAL_DCO_16MHz      (0x0002u) /* 16MHz DCOCTL 校准数据索引*/

    #define CAL_BC1_16MHz      (0x0003u) /* 16MHz BCSCTL1校准数据索引*/

    我设法使用 CAL_BC1_16MHz 的偏移、而不是正确的 CALBC1_16MHz 读取结构、该结构会正确地转到正确的校准数据地址。  我将修复此问题并"看看发生了什么..."可能是"有趣"...

    此致、Keith

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

    Bruce (抱歉--不知道为什么我给你叫 Brian,可能是因为我有一个与这个名字相关的关系),Caleb,

    我有好消息也有坏消息:

    优点--由于 Bruce 收到了上述 CAL_BC1_16MHz 与 CALBC1_16MHz 问题,我现在有一个16MHz SMCLK (意味着一个16MHz DCO CLK),并且 SPI 时钟不会消失。  Caleb --在我发送给您的代码中,按如下方式更新 system_hardware.c 中的 BCSCTL1初始化寄存器:

       BCSCTL1 = CALBC1_16MHz;                                                      // 添加此行
    // BCSCTL1 = XT2OFF | DIV_0|CAL_BC1_16MHz;                  //注释掉此行

    的-- 我使标有 DSP CE 的 SPI 从器件使能"芯片使能"变低,但仍然没有流量(没有 SPI 时钟,没有数据传输)-- 第一个字节在 TXBUF 中、但它仍然看起来好像移位寄存器没有执行它的操作并且端口永远不会发生!UCBUSY 并且下一个 TX 中断不会发生。  您能否验证 G2553器件中是否没有 ME2寄存器?  我找到了一个"模块启用"位4、该位将在 SPI 模式下启用 USART1、这可能会使我明白为什么端口不是仅运行以发现该寄存器似乎未在 G2553中定义、并且如果通过其他方式进行初始化、则端口始终启用。

    我们正在取得一些进展。  您是否对我通过 zip 文件发送给您的源文件有任何"早期结果"?  请告诉我、它是否由于安全问题而被剥离。

    此致、Keith

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

    您好、Keith、

    感谢您的更新。 我仍在梳理您提供的代码。 即使是已拆装的版本、它也有大量的代码。 我想指出的是、G2553没有 USART 模块、因此没有 ME2寄存器。 G2553有一个执行 SPI 通信的 USCI 模块。 与 USART 模块相比、它的使用更加简单和可靠。

    您能否将 示例加载到 MSP430G2553上并查看 SPI 输出是否有任何活动? 此示例已经过测试和验证、可正常运行。 如果仍然没有输出、我认为您使用的芯片很可能已损坏:


    此致、
    Caleb Overbay

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

    Caleb、

    如果您对问题的最后一个答复中的 MSP430链接旨在转到某些 MSP430Ware 工程、则只需我转到 MSP430G2553规范和文档页面。  没有指向项目的链接。

    我已经下载了 MSP430Ware、因此如果它是其中的一个项目、请告诉我这个名称、除非链接对您来说更容易。

    感谢你的帮助。  我一直担心芯片故障--奇怪的是,几十年来嵌入式开发的奇怪之处在于 happened...usually 如果其中一个 MSP“芯片”是灾难性的,不会再对该芯片进行编程,而该芯片似乎不属于该类别。  但是、运行一些预设的演示固件可以很好地检查这些问题。

    此致、Keith

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

    我刚刚完成了代码审核。 除了 Bruce 捕获的时钟之外、我没有看到任何设置错误。 您应该会在 SPI 线路上看到某种类型的输出。 我正在尝试在我这里拥有的电路板上测试代码、但我的 IAR 版本在通过 G2 launchpad 上的 eZ430加载代码时遇到了一些问题。

    下面是我希望您尝试的示例的链接:
    dev.ti.com/.../

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

    LaunchPad 器件上有14引脚调试接头、因此您可以绕过板载 eZ430。 您必须将大多数跳线取下到14引脚接头的右侧、然后将 MSP-FET 或 MSP-FET430UIF 调试器或其他兼容的仿真器/调试器连接到 Launchpad ...只是一个建议。

    我将制作另一个项目并尝试您建议的代码、并将让您知道我发现的内容。

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

    Caleb、

    忽略我上一条消息的一部分--我正在查看我的 FRAM Launchpad,而不是 G2553,并注意到2553 LP 没有14引脚调试端口,这与 FRAM5969 LP 不同。  因此、绕过它将不起作用。  您可以将我的源代码引入 CCS 工程中、并对编译器语法进行任何必要的更改、以使其能够编译/运行、这可能能够与 eZ430连接配合使用。  我的 G2553 Launch Pad 设备出了问题--我从调试器加载了代码,在调试模式下发现整个内存空间是零,这是没有意义的,因为被擦除的芯片应该是 FF。  需要加载我的独立 FET-MSP 工具、以查看我是否可以通过 eZ430 I/F 读取芯片内容。。。 我在一条非常蜿蜒的道路上...很高兴本周即将结束...

    此致、

    Keith

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    > UCB0CTL0__SPI = UCMSB | UCMODE_2 | UCSYNC; // MSB 优先作为从器件、4引脚 STE 低电平有效、同步

    UCMODE=2是4线制、包括 STE、但您不使用 STE (而是使用不同引脚的/CS)。 无论您使用的是 P1.4 (UCB0STE)、它都将使其保持高电平、因此 SPI 单元会识别出冲突并关闭 SPI (另请参阅 SLAU144J 第16.3.3.1节)。

    改为尝试 UCMODE=0:

    > UCB0CTL0__SPI = UCMSB | UCMODE_0 /*是_2*/| UCSYNC; // MSB 优先作为从器件、4引脚 STE 低电平有效、同步
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Bruce、

    您错过了下面几行中的代码...因为我想轻松地打开或关闭主模式,所以我编写了主器件预期的代码-- 红色粗体或 主模式位中的行、以便启用或禁用端口位于远程处理器上、而不是我的 G2553主器件上 (有一次我打算使用 G2553作为从器件、但它似乎是28069 DSP 可以运行的最慢速度、对于 G2553来说、SPI 端口仍然太快、因此我不得不交换模式。

     以下代码摘录正是我发送给您和 Caleb 的有关此主题的代码:

      UCB0CTL0__SPI = UCMSB | UCMODE_2 | UCSYNC;       // MSB 优先作为从器件、4引脚 STE 低电平有效、同步
                                                         //   目前,使用相位/极性= 00,数据 chg 在上升沿,捕获在后沿,时钟通常为低电平
       UCB0CTL1__SPI |= UCSSEL_2;                       // SMCLK、启用。 USCI 逻辑保持在复位状态

    // KRA edit --如果我们要将这个端口测试为主端口,我们将需要以下语句来设置波特率和强制主端口模式
       UCB0CTL0__SPI |= UCMST;                          //或主控模式控制位    注: 我这样做了、所以我只需注释掉使其成为主控器件的行、而无需编辑 UCB0CTL0_SPI 设置上方的行。

    此致、Keith

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否尝试过我建议的更改? 当我尝试它时、您的代码成功。

    您运行的是3线制主器件(因为 SPI 单元不控制 STE/CS)、但您告诉 SPI 单元它是4线制(主器件)。 这会导致其跳过 SLAU144J 第16.3.3.1节中描述的条件、从而产生您描述的症状。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Keith、

    我认为 Bruce 在这个问题上走得非常好。 您已将 MSP430G2553设置为用作4引脚 SPI 主器件。 这意味着在向从器件发送数据时、USCI_B 模块将尝试控制 UCB0STE 线路(P1.4)。 您当前已将代码设置为在 P1.4上输出 SMCLK、而不是为 USCI_B 模块提供引脚控制。 正如您所观察到的、这个冲突可能会导致 USCI_B 模块意外运行。

    由于您手动控制用于 CS 功能的 GPIO、我推荐 Bruce 的方案。 在对 CS 引脚进行管理控制时、使用 UCMODE_0 (3引脚 SPI)应解决此冲突。 您能否尝试一下并让我们知道结果?

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

    Brian、

    讨论令人困惑的文档...以下代码段(用户指南的16.4.1)表明 UCxSTE 只用于控制从器件、而不是主器件...

    UCMODEx 位2-1 USCI 模式。 当 UCSYNC=1时、UCMODEx 位选择同步模式。
                                   00 3引脚 SPI
                                   01 UCxSTE 高电平有效的4引脚 SPI:当 UCxSTE=1时、从器件被启用
                                   10 4引脚 SPI、UCxSTE 低电平有效:当 UCxSTE=0时、从器件被启用
                                   11 I2C 模式

    我正在使用端口引脚来控制 UCxSTE。  所以我假设我是 一个4引脚主器件...所以16.3.3.1与此相矛盾、引入了多主器件的概念、如果它的 UCxSTE 未被启用、4引脚主器件可以脱机... 这就是它的样子 ,但是如果用户指南中的文档在16.4..1中提到了它 ,就更好了。  尝试此操作后、我会在 TI 文档评论链接上推荐此操作。  根据我现在从大图的角度所了解的内容、很好的收获。  错误的文档可能会给您带来麻烦。  这一次我假定单主器件、多从器件-而不是多主器件多从器件...灵活、但始终具有由此产生的复杂性。

    此致、Keith

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

    这是对 Caleb 的意见的回应,他说:“我认为 Bruce 是正确的轨道” ,我同意 Bruce 的立场,但与您在电子邮件正文中所说的不完全一致。。。。

    您说"这意味着 USCI_B 模块在向从器 件发送数据时将尝试控制 UCB0STE 线路(P1.4)"-- UCB0STE 线路只是且始终是一个输入。  本地主设备或从设备都无法控制进入主设备或从设备运行的处理器的 STE 线路。  在4线制主控模式中、本地 UCB0STE 上的非激活输入会阻止主控器件发送、因为它假定另一个主控器件忙、这可能会很有用。  由于我正在处理的卫星 G2553代码可能需要作为主器 件运行、返回至作为从器件的 DSP;此外、DSP 在同一总线上具有作为从器件的 SPI 闪存、这意味着它必须是串行闪存的主器件。  我可能需要开发将 DSP 主设备转变为多主设备的机制来协调总线上的流量。  我只是没有意识到本地主器件可以这样设置、而在主器件模式下、本地 UCB0STE 输入将被忽略。   哎呀!

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

    各位嘉宾: Brian & Caleb、

    Brian 的建议是使用3线制主控模式、这似乎奏效了、只能证明 没有 SPI 接口必然与另一个接口完全一样。  主从或主从的概念非常常见、并且记录了接口的描述数量。  当我有机会时、我将建议对用户指南进行一些更改、以便更好地记录4线制主器件的细微影响。  无论如何,我都有必要的资料,以推动我的发展工作,而这一职位代表了问题的解决。

    感谢你们的帮助!

    此致、Keith

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

    我很高兴我们能够找到这个! 此外、我还会向 TI 的相应团队提供有关 UG 的反馈。 如果您有任何疑问、请告诉我。

    此致、
    Caleb Overbay