在近期的测试中发现了一个关于MSP430FR5969在SPI通讯中功耗的问题:将eUSCIA配置为SPI模式(UCCKPH配置为1,UCCKPL配置为0,主机模式,先发高位),每4ms进行一次SPI通讯,此时电流15uA左右(未通讯时处于LPM3低功耗)。在此过程中,当MISO管脚接收的8位数据最低位为1,且通讯结束MISO管脚从1跳变至0时,会发生电流突然变大的状况, MSP430FR5969电流变大至170uA(同样处于低功耗LPM3)。此时,停止SPI通讯后进入LPM3低功耗模式,电流不会减小,同时监测模块UCBUSY 一直在0/1之间跳变,而同等配置下SPIB模块则不会出现上述问题。不知贵公司是否了解该问题?在贵公司MSP430FR5969的勘误手册中,提及到了SPIA模块存在类似问题(问题编号:USCI41),怀疑与该问题有强相关性。
为明确该问题,我编写了一段简单的测试代码在贵公司的开发板(MSP430FR5969 LaunchPad™ Development Kit)上的最小系统上运行,可以复现之前描述的bug。基本思路是用MSP430FR5969的IO口输出来模拟从机的发送端,连接到430的P2.1即SPI的输入口 (UCA0SOMI)。当SPI接收的8位数据全部为1,SPI通讯结束后,将UCA0SOMI端口通过IO输出拉低,此时MSP430FR5969电流会增大至170uA,同时监测模块UCBUSY 一直在0/1之间跳变。
部分代码:
// MSP430FR5969
// —————–
// /|\ | P1.3|-> Slave Chip Select (GPIO)
// | | |
// | |
// | P2.0|-> Data Out (UCA0SIMO)
// | |
// | P2.1|<- Data In (UCA0SOMI)
// | |
// | P1.5|-> Serial Clock Out (UCA0CLK)
// | P2.4|-> 串联470K电阻并接P2.1|Data In (UCA0SOMI)
/*********************************************************************** 函数名称:// asic_spi_writedata
* 功能描述:// 通过spi读asic寄存器数据
* 输入参数:// ASIC寄存器地址
* 输出参数:// 无
* 返 回 值:// 该寄存器地址下数据
* 其它说明:
***********************************************************************/uint8_t asic_spi_readdata(uint8_t address)
{
uint8_t data = 0;
ASIC_SPI_CLEARCS();
__delay_cycles(100);
while(!(UCA0IFG & UCTXIFG)); //USCI_A0 TX buffer ready?
UCA0TXBUF = address; //发送数据
while(!(UCA0IFG & UCTXIFG));
__delay_cycles(100);
UCA0TXBUF = 0x00; //发送数据
while(!(UCA0IFG & UCTXIFG));
__delay_cycles(100);
while(!(UCA0IFG & UCRXIFG));
data = UCA0RXBUF; //读数据
__delay_cycles(100);
ASIC_SPI_SETCS();
return data;
}
/*********************************************************************** 函数名称:// void gpio_init_forPowerMeas(void)
* 功能描述:// 功耗测试使用的gpio驱动,将所有端口设为输出,以避免输入悬空对功耗的影响
* 输入参数:// 无
* 输出参数:// 无
* 返 回 值:// 无
* 其它说明:
***********************************************************************/
void gpio_init_forPowerMeas(void)
{
// Configure GPIO
P2SEL0 = 0;
P1SEL1 = ASIC_SCK ;
P1DIR = 0xff;
P1OUT = 0x00;
P2SEL0 = 0;
P2SEL1 = ASIC_MOSI + ASIC_MISO;
P2DIR = 0xff;
P2OUT = 0x00;
P3DIR = 0xff;
P3OUT = 0x00;
P4DIR = 0xff;
P4OUT = 0x00;
PJSEL0 = ACLK_OUT + LFXTIN + LFXTOUT ;
PJSEL1 = 0;
PJDIR |= 0xFF;
PJOUT = 0x00;
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
}
/*********************************************************************** 函数名称:// asic_spi_init
* 功能描述:// UCA0模块 SPI初始化,用于ASIC通讯
* 输入参数:// 无
* 输出参数:// 无
* 返 回 值:// 无
* 其它说明:波特率4M,3线SPI,CS端由IO口模拟
***********************************************************************/void asic_spi_init(void)
{
//Initialize SPI Master
//Disable the USCI Module
//Reset OFS_UCA0CTLW0 values
UCA0CTLW0 = UCSWRST + UCSSEL__SMCLK; //Select Clock SMCLK
//Bit clock prescaler setting. fBitClock = fBRCLK / UCBRx
//UCA0BRW = 8000000 / 1000000; //SMCLK 8M,波特率1M
UCA0BRW = 8000000 / 4000000;
/*
* Configure as SPI master mode.
* Clock phase select, polarity, msb
* UCMST = Master mode
* UCSYNC = Synchronous mode
* UCMODE_0 = 3-pin SPI
*/
//Data is changed on the first UCLK edge and captured on the followingedge.
//The inactive state is low.
//3-pin SPI
UCA0CTLW0 |= UCMSB + UCCKPH + UCMST + UCSYNC; //MSB First. capture changge
//Master mode //Synchronous mode
//No modulation
//UCA0MCTLW = 0;
//Enable SPI module
UCA0CTLW0 &= ~UCSWRST;
}
/*********************************************************************** 函数名称:// int main(void)
* 功能描述:// 1.应用程序的主函数
* 2.实现硬件和软件初始化,工作状态切换,记录复位源
* 输入参数:// 无
* 输出参数:// 无
* 返 回 值:// 无
* 其它说明:// 无
***********************************************************************/
int main(void)
{ cpu_initial();
uint16_t adc_cnt;
WDT_HOLD();
P2OUT |= BIT4; //P2.4管脚470K电阻接P2.1|<- Data In (UCA0SOMI)
adcbuf_v1 = asic_spi_readdata(0x00);
P2OUT &= ~BIT4; //进行读操作后将P2.4管脚置低
do
{
delay_ms(4);
//监测寄存器UCBUSY位,示波器接P3.6
if(UCA0STATW & UCBUSY)
{
P3OUT |= BIT6;
}
else
{
P3OUT &= ~BIT6;
}
}while(1);
}
灰小子:
建议楼主先试试勘误手册里提供的解决方法。
Susan Yang:
那您有没有尝试使用勘误表里的解决方案呢?
Check on transmit or receive interrupt flag UCTXIFG/UCRXIFG instead of UCBUSY to know if the UCAxTXBUF buffer is empty or ready for the next complete character.
Guanglei Zhang:
回复 Susan Yang:
您好,现在就是用的 就是UCTXIFG/UCRXIFG标志,接收的数据是没有问题的。主要问题是功耗会变大,直接影响了工程的应用。就是想确认这个问题,然后再想办法避免,比如每次接收结束后复位SPI模块。
Guanglei Zhang:
回复 灰小子:
您好,现在就是用的 就是UCTXIFG/UCRXIFG标志,接收的数据是没有问题的。主要问题是功耗会变大,直接影响了工程的应用。就是想确认这个问题,然后再想办法避免,比如每次接收结束后复位SPI模块。