您好,我在使用MSP430的SPI向从机发数据。SPI模式已经选择为主机模式。但是在430调试过程中 while (!(IFG2 & UTXIFG1))这一步老是死循环。应该就是说之前的数据还没发送出去吧,从机没有收到来自430的数据。请问该怎么解决这个问题。 附件为log
秋之初:
你好
1、你可以试试把断点设在 等待语句 的后一句 ,看看能否 运行到 那句:
while (!(IFG2 & UTXIFG1)) ;
断点 dummy +=1;
2、你可以用示波器看看,有没有发送出正确数据、时钟信号?
qi tang:
回复 秋之初:
没有UCLK1时钟输出,为什么会这样呢?我是设置过的啊
Peter_Zheng:
回复 qi tang:
没数据怎么有时钟?
参考一下代码例子:
UCA0CTL1 = UCSWRST; // **Put state machine in reset**
UCA0CTL0 |= UCCKPL + UCMSB + UCSYNC; // 3-pin, 8-bit SPI master
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE; // Enable USCI0 RX interrupt
__bis_SR_register(LPM4_bits + GIE); // Enter LPM4, enable interrupts
}
// Echo character
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR (void)
{
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = UCA0RXBUF;
}
或者把你的代码配置spi这块发出来看看
qi tang:
回复 Peter_Zheng:
时钟不是设置成主模式就有输出吗? 怎么要有数据才有时钟?不太明白。
qi tang:
回复 Peter_Zheng:
时钟不是设置成主模式就有输出吗? 怎么要有数据才有时钟?不太明白。以下是我的SPI设置
uchar Spi_Init(long baud,uchar dataBits,uchar mode,uchar clkMode)
{
long int brclk; //波特率发生器时钟频率
// P5SEL |= 0x0E; //// P5.1,P5.2,P5.3复用功能,SPI的出入和时钟
U1CTL |= SWRST; //初始 ?????????????????
//反馈选择位,为1,发送的数被自己接收,用于测试,正常使用时注释掉
//UxCTL |= LISTEN;
U1CTL |= SYNC + MM; //SPI 主机模式 ?????????//?????是否需要考虑SWRST
//时钟源设置
U1TCTL &=~ (SSEL0+SSEL1); //清除之前的时钟设置
if(baud<=16364) //
{
U1TCTL |= SSEL0; //ACLK,降低功耗
brclk = 32768; //波特率发生器时钟频率=ACLK(32768)
}
else
{
U1TCTL |= SSEL1; //SMCLK,保证速度
brclk = 1000000; //波特率发生器时钟频率=SMCLK(1MHz)
}
//————————设置波特率————————-
if(baud < 300||baud > 115200) //波特率超出范围
{
return 0;
}
//设置波特率寄存器
int fen = brclk / baud; //分频系数
if(fen<2)return (0); //分频系数必须大于2
else
{
U1BR0 = fen % 256;
U1BR1 = fen / 256;
}
//————————设置数据位————————-
switch(dataBits)
{
case 7:case'7': U1CTL &=~ CHAR; break; //7位数据
case 8:case'8': U1CTL |= CHAR; break; //8位数据
default : return(0); //参数错误
}
//————————设置模式—————————
switch(mode)
{
case 3:case'3': U1TCTL |= STC; USPI3ON; break; //三线模式
case 4:case'4': U1TCTL &=~ STC; USPI4ON; break; //四线模式
default : return(0); //参数错误
}
//————————设置UCLK模式———————–
switch(clkMode)
{
case 0:case'0': U1TCTL &=~ CKPH; U1TCTL &=~ CKPL; break; //模式0
case 1:case'1': U1TCTL &=~ CKPH; U1TCTL |= CKPL; break; //模式1
case 2:case'2': U1TCTL |= CKPH; U1TCTL &=~ CKPL; break; //模式2
case 3:case'3': U1TCTL |= CKPH; U1TCTL |= CKPL; break; //模式3
default : return(0); //参数错误
}
U1ME |= USPIE1; //模块使能
UCTL1 &= ~SWRST; // Initialize USART state machine
U1IE |= URXIE1 + UTXIE1; // Enable USART1 RX interrupt
return(1); //设置成功
}
Fuchong Wang:
回复 qi tang:
没数据发送的好像就是时钟不输出的呀
USICNT写了么?
时钟源设置正确了么?SPI使能了么?
qi tang:
回复 Fuchong Wang:
您好 您说的USICNT是什么?对应于430的哪个寄存器
Peter_Zheng:
回复 qi tang:
你的程序里还有波特率的配置?SPI的速度是由时钟决定的。建议你找demo code SPI配置这块看一下。master的配置主要是一下几个寄存器配置
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB; // 3-pin, 8-bit SPI master
// Clock polarity high, MSB
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 0x02; // /2
UCA0BR1 = 0; //
UCA0MCTL = 0; // No modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
qi tang:
回复 Peter_Zheng:
波特率的设置实际上也就是设置 UCA0BR0 这个寄存器。我在看一下有没有设置上的问题吧。因为我用的是Usart1这个口充当SPI口的。 现在想确定一个问题。 是不是只要SPI设置对了,就会有时钟发出。是不是只要有UCLK时钟,数据就会不停的发送接收(不管是给定数据,或是无效数据),也就是说不会在那句判定语上停止。 期待您的回答
Peter_Zheng:
回复 qi tang:
你用的哪颗片子,哪个USCI口。首先确定你使用端口的带有SPI功能,SPI发送数据时,SCLK与SMIO能测量到信号。发送数据都是你程序里设定的,发送数据就有SCLK信号,不发数据就没有。你在好好把SPI的协议看看吧。